UNPKG

playcanvas

Version:

PlayCanvas WebGL game engine

753 lines (752 loc) 23.9 kB
/** * The graphics device manages the underlying graphics context. It is responsible for submitting * render state changes and graphics primitives to the hardware. A graphics device is tied to a * specific canvas HTML element. It is valid to have more than one canvas element per page and * create a new graphics device against each. * * @category Graphics */ export class GraphicsDevice extends EventHandler { static EVENT_RESIZE: string; constructor(canvas: any, options: any); /** * Fired when the canvas is resized. The handler is passed the new width and height as number * parameters. * * @event * @example * graphicsDevice.on('resizecanvas', (width, height) => { * console.log(`The canvas was resized to ${width}x${height}`); * }); */ /** * The canvas DOM element that provides the underlying WebGL context used by the graphics device. * * @type {HTMLCanvasElement} * @readonly */ readonly canvas: HTMLCanvasElement; /** * The render target representing the main back-buffer. * * @type {RenderTarget|null} * @ignore */ backBuffer: RenderTarget | null; /** * The dimensions of the back buffer. * * @ignore */ backBufferSize: Vec2; /** * The pixel format of the back buffer. Typically PIXELFORMAT_RGBA8, PIXELFORMAT_BGRA8 or * PIXELFORMAT_RGB8. * * @ignore */ backBufferFormat: any; /** * True if the back buffer should use anti-aliasing. * * @type {boolean} */ backBufferAntialias: boolean; /** * True if the deviceType is WebGPU * * @type {boolean} * @readonly */ readonly isWebGPU: boolean; /** * True if the deviceType is WebGL2 * * @type {boolean} * @readonly */ readonly isWebGL2: boolean; /** * True if the deviceType is Null * * @type {boolean} * @readonly */ readonly isNull: boolean; /** * True if the back-buffer is using HDR format, which means that the browser will display the * rendered images in high dynamic range mode. This is true if the options.displayFormat is set * to {@link DISPLAYFORMAT_HDR} when creating the graphics device using * {@link createGraphicsDevice}, and HDR is supported by the device. */ isHdr: boolean; /** * The scope namespace for shader attributes and variables. * * @type {ScopeSpace} * @readonly */ readonly scope: ScopeSpace; /** * The maximum number of indirect draw calls that can be used within a single frame. Used on * WebGPU only. This needs to be adjusted based on the maximum number of draw calls that can * be used within a single frame. Defaults to 1024. * * @type {number} */ maxIndirectDrawCount: number; /** * The maximum supported texture anisotropy setting. * * @type {number} * @readonly */ readonly maxAnisotropy: number; /** * The maximum supported dimension of a cube map. * * @type {number} * @readonly */ readonly maxCubeMapSize: number; /** * The maximum supported dimension of a texture. * * @type {number} * @readonly */ readonly maxTextureSize: number; /** * The maximum supported dimension of a 3D texture (any axis). * * @type {number} * @readonly */ readonly maxVolumeSize: number; /** * The maximum supported number of color buffers attached to a render target. * * @type {number} * @readonly */ readonly maxColorAttachments: number; /** * The highest shader precision supported by this graphics device. Can be 'hiphp', 'mediump' or * 'lowp'. * * @type {string} * @readonly */ readonly precision: string; /** * The number of hardware anti-aliasing samples used by the frame buffer. * * @readonly * @type {number} */ readonly samples: number; /** * The maximum supported number of hardware anti-aliasing samples. * * @readonly * @type {number} */ readonly maxSamples: number; /** * True if the main framebuffer contains stencil attachment. * * @ignore * @type {boolean} */ supportsStencil: boolean; /** * True if the device supports multi-draw. This is always supported on WebGPU, and support on * WebGL2 is optional, but pretty common. * * @type {boolean} */ supportsMultiDraw: boolean; /** * True if the device supports compute shaders. * * @readonly * @type {boolean} */ readonly supportsCompute: boolean; /** * True if the device can read from StorageTexture in the compute shader. By default, the * storage texture can be only used with the write operation. * When a shader uses this feature, it's recommended to use a `requires` directive to signal the * potential for non-portability at the top of the WGSL shader code: * ```javascript * requires readonly_and_readwrite_storage_textures; * ``` * * @readonly * @type {boolean} */ readonly supportsStorageTextureRead: boolean; /** * Currently active render target. * * @type {RenderTarget|null} * @ignore */ renderTarget: RenderTarget | null; /** * Array of objects that need to be re-initialized after a context restore event * * @type {Shader[]} * @ignore */ shaders: Shader[]; /** * An array of currently created textures. * * @type {Texture[]} * @ignore */ textures: Texture[]; /** * A set of currently created render targets. * * @type {Set<RenderTarget>} * @ignore */ targets: Set<RenderTarget>; /** * A version number that is incremented every frame. This is used to detect if some object were * invalidated. * * @type {number} * @ignore */ renderVersion: number; /** * Index of the currently active render pass. * * @type {number} * @ignore */ renderPassIndex: number; /** @type {boolean} */ insideRenderPass: boolean; /** * True if the device supports uniform buffers. * * @type {boolean} * @ignore */ supportsUniformBuffers: boolean; /** * True if the device supports clip distances (WebGPU only). Clip distances allow you to restrict * primitives' clip volume with user-defined half-spaces in the output of vertex stage. * * @type {boolean} */ supportsClipDistances: boolean; /** * True if 32-bit floating-point textures can be used as a frame buffer. * * @type {boolean} * @readonly */ readonly textureFloatRenderable: boolean; /** * True if 16-bit floating-point textures can be used as a frame buffer. * * @type {boolean} * @readonly */ readonly textureHalfFloatRenderable: boolean; /** * True if small-float textures with format {@link PIXELFORMAT_111110F} can be used as a frame * buffer. This is always true on WebGL2, but optional on WebGPU device. * * @type {boolean} * @readonly */ readonly textureRG11B10Renderable: boolean; /** * True if filtering can be applied when sampling float textures. * * @type {boolean} * @readonly */ readonly textureFloatFilterable: boolean; /** * A vertex buffer representing a quad. * * @type {VertexBuffer} * @ignore */ quadVertexBuffer: VertexBuffer; /** * An object representing current blend state * * @ignore */ blendState: BlendState; /** * The current depth state. * * @ignore */ depthState: DepthState; /** * True if stencil is enabled and stencilFront and stencilBack are used * * @ignore */ stencilEnabled: boolean; /** * The current front stencil parameters. * * @ignore */ stencilFront: StencilParameters; /** * The current back stencil parameters. * * @ignore */ stencilBack: StencilParameters; /** * The dynamic buffer manager. * * @type {DynamicBuffers} * @ignore */ dynamicBuffers: DynamicBuffers; /** * The GPU profiler. * * @type {GpuProfiler} */ gpuProfiler: GpuProfiler; /** * @type {boolean} * @ignore */ _destroyed: boolean; defaultClearOptions: { color: number[]; depth: number; stencil: number; flags: number; }; /** * The current client rect. * * @type {{ width: number, height: number }} * @ignore */ clientRect: { width: number; height: number; }; /** * A very heavy handed way to force all shaders to be rebuilt. Avoid using as much as possible. * * @type {boolean} * @ignore */ _shadersDirty: boolean; /** * A list of shader defines based on the capabilities of the device. * * @type {Map<string, string>} * @ignore */ capsDefines: Map<string, string>; /** * A set of maps to clear at the end of the frame. * * @type {Set<Map>} * @ignore */ mapsToClear: Set<Map<any, any>>; initOptions: any; _maxPixelRatio: number; buffers: any[]; _vram: { texShadow: number; texAsset: number; texLightmap: number; tex: number; vb: number; ib: number; ub: number; sb: number; }; _shaderStats: { vsCompiled: number; fsCompiled: number; linked: number; materialShaders: number; compileTime: number; }; _drawCallsPerFrame: number; _shaderSwitchesPerFrame: number; _primsPerFrame: number[]; _renderTargetCreationTime: number; textureBias: import("./scope-id.js").ScopeId; /** * Function that executes after the device has been created. */ postInit(): void; /** * Initialize the map of device capabilities, which are supplied to shaders as defines. * * @ignore */ initCapsDefines(): void; /** * Destroy the graphics device. */ destroy(): void; onDestroyShader(shader: any): void; postDestroy(): void; /** * Called when the device context was lost. It releases all context related resources. * * @ignore */ loseContext(): void; contextLost: boolean; /** * Called when the device context is restored. It reinitializes all context related resources. * * @ignore */ restoreContext(): void; toJSON(key: any): any; initializeContextCaches(): void; vertexBuffers: any[]; shader: any; shaderValid: any; shaderAsyncCompile: boolean; initializeRenderState(): void; cullMode: number; vx: number; vy: number; vw: number; vh: number; sx: number; sy: number; sw: number; sh: number; blendColor: Color; /** * Sets the specified stencil state. If both stencilFront and stencilBack are null, stencil * operation is disabled. * * @param {StencilParameters} [stencilFront] - The front stencil parameters. Defaults to * {@link StencilParameters.DEFAULT} if not specified. * @param {StencilParameters} [stencilBack] - The back stencil parameters. Defaults to * {@link StencilParameters.DEFAULT} if not specified. */ setStencilState(stencilFront?: StencilParameters, stencilBack?: StencilParameters): void; /** * Sets the specified blend state. * * @param {BlendState} blendState - New blend state. */ setBlendState(blendState: BlendState): void; /** * Sets the constant blend color and alpha values used with {@link BLENDMODE_CONSTANT} and * {@link BLENDMODE_ONE_MINUS_CONSTANT} factors specified in {@link BlendState}. Defaults to * [0, 0, 0, 0]. * * @param {number} r - The value for red. * @param {number} g - The value for green. * @param {number} b - The value for blue. * @param {number} a - The value for alpha. */ setBlendColor(r: number, g: number, b: number, a: number): void; /** * Sets the specified depth state. * * @param {DepthState} depthState - New depth state. */ setDepthState(depthState: DepthState): void; /** * Controls how triangles are culled based on their face direction. The default cull mode is * {@link CULLFACE_BACK}. * * @param {number} cullMode - The cull mode to set. Can be: * * - {@link CULLFACE_NONE} * - {@link CULLFACE_BACK} * - {@link CULLFACE_FRONT} */ setCullMode(cullMode: number): void; /** * Sets the specified render target on the device. If null is passed as a parameter, the back * buffer becomes the current target for all rendering operations. * * @param {RenderTarget|null} renderTarget - The render target to activate. * @example * // Set a render target to receive all rendering output * device.setRenderTarget(renderTarget); * * // Set the back buffer to receive all rendering output * device.setRenderTarget(null); */ setRenderTarget(renderTarget: RenderTarget | null): void; /** * Sets the current vertex buffer on the graphics device. For subsequent draw calls, the * specified vertex buffer(s) will be used to provide vertex data for any primitives. * * @param {VertexBuffer} vertexBuffer - The vertex buffer to assign to the device. * @ignore */ setVertexBuffer(vertexBuffer: VertexBuffer): void; /** * Clears the vertex buffer set on the graphics device. This is called automatically by the * renderer. * @ignore */ clearVertexBuffer(): void; /** * Retrieves the first available slot in the {@link indirectDrawBuffer} used for indirect * rendering, which can be utilized by a {@link Compute} shader to generate indirect draw * parameters and by {@link MeshInstance#setIndirect} to configure indirect draw calls. * * When reserving multiple consecutive slots, specify the optional `count` parameter. * * @param {number} [count] - Number of consecutive slots to reserve. Defaults to 1. * @returns {number} - The first reserved slot index used for indirect rendering. */ getIndirectDrawSlot(count?: number): number; /** * Returns the buffer used to store arguments for indirect draw calls. The size of the buffer is * controlled by the {@link maxIndirectDrawCount} property. This buffer can be passed to a * {@link Compute} shader along with a slot obtained by calling {@link getIndirectDrawSlot}, in * order to prepare indirect draw parameters. Also see {@link MeshInstance#setIndirect}. * * Only available on WebGPU, returns null on other platforms. * * @type {StorageBuffer|null} */ get indirectDrawBuffer(): StorageBuffer | null; /** * Queries the currently set render target on the device. * * @returns {RenderTarget} The current render target. * @example * // Get the current render target * const renderTarget = device.getRenderTarget(); */ getRenderTarget(): RenderTarget; /** * Initialize render target before it can be used. * * @param {RenderTarget} target - The render target to be initialized. * @ignore */ initRenderTarget(target: RenderTarget): void; /** * Submits a graphical primitive to the hardware for immediate rendering. * * @param {object} primitive - Primitive object describing how to submit current vertex/index * buffers. * @param {number} primitive.type - The type of primitive to render. Can be: * * - {@link PRIMITIVE_POINTS} * - {@link PRIMITIVE_LINES} * - {@link PRIMITIVE_LINELOOP} * - {@link PRIMITIVE_LINESTRIP} * - {@link PRIMITIVE_TRIANGLES} * - {@link PRIMITIVE_TRISTRIP} * - {@link PRIMITIVE_TRIFAN} * * @param {number} primitive.base - The offset of the first index or vertex to dispatch in the * draw call. * @param {number} primitive.count - The number of indices or vertices to dispatch in the draw * call. * @param {boolean} [primitive.indexed] - True to interpret the primitive as indexed, thereby * using the currently set index buffer and false otherwise. * @param {IndexBuffer} [indexBuffer] - The index buffer to use for the draw call. * @param {number} [numInstances] - The number of instances to render when using instancing. * Defaults to 1. * @param {DrawCommands} [drawCommands] - The draw commands to use for the draw call. * @param {boolean} [first] - True if this is the first draw call in a sequence of draw calls. * When set to true, vertex and index buffers related state is set up. Defaults to true. * @param {boolean} [last] - True if this is the last draw call in a sequence of draw calls. * When set to true, vertex and index buffers related state is cleared. Defaults to true. * @example * // Render a single, unindexed triangle * device.draw({ * type: pc.PRIMITIVE_TRIANGLES, * base: 0, * count: 3, * indexed: false * }); * * @ignore */ draw(primitive: { type: number; base: number; count: number; indexed?: boolean; }, indexBuffer?: IndexBuffer, numInstances?: number, drawCommands?: DrawCommands, first?: boolean, last?: boolean): void; /** * Reports whether a texture source is a canvas, image, video or ImageBitmap. * * @param {*} texture - Texture source data. * @returns {boolean} True if the texture is a canvas, image, video or ImageBitmap and false * otherwise. * @ignore */ _isBrowserInterface(texture: any): boolean; _isImageBrowserInterface(texture: any): boolean; _isImageCanvasInterface(texture: any): boolean; _isImageVideoInterface(texture: any): boolean; /** * Sets the width and height of the canvas, then fires the `resizecanvas` event. Note that the * specified width and height values will be multiplied by the value of * {@link GraphicsDevice#maxPixelRatio} to give the final resultant width and height for the * canvas. * * @param {number} width - The new width of the canvas. * @param {number} height - The new height of the canvas. * @ignore */ resizeCanvas(width: number, height: number): void; /** * Sets the width and height of the canvas, then fires the `resizecanvas` event. Note that the * value of {@link GraphicsDevice#maxPixelRatio} is ignored. * * @param {number} width - The new width of the canvas. * @param {number} height - The new height of the canvas. * @ignore */ setResolution(width: number, height: number): void; update(): void; updateClientRect(): void; /** * Width of the back buffer in pixels. * * @type {number} */ get width(): number; /** * Height of the back buffer in pixels. * * @type {number} */ get height(): number; /** * Sets whether the device is currently in fullscreen mode. * * @type {boolean} */ set fullscreen(fullscreen: boolean); /** * Gets whether the device is currently in fullscreen mode. * * @type {boolean} */ get fullscreen(): boolean; /** * Sets the maximum pixel ratio. * * @type {number} */ set maxPixelRatio(ratio: number); /** * Gets the maximum pixel ratio. * * @type {number} */ get maxPixelRatio(): number; /** * Gets the type of the device. Can be: * * - {@link DEVICETYPE_WEBGL2} * - {@link DEVICETYPE_WEBGPU} * * @type {DEVICETYPE_WEBGL2|DEVICETYPE_WEBGPU} */ get deviceType(): "webgl2" | "webgpu"; startRenderPass(renderPass: any): void; endRenderPass(renderPass: any): void; startComputePass(name: any): void; endComputePass(): void; /** * Function which executes at the start of the frame. This should not be called manually, as * it is handled by the AppBase instance. * * @ignore */ frameStart(): void; /** * Function which executes at the end of the frame. This should not be called manually, as it is * handled by the AppBase instance. * * @ignore */ frameEnd(): void; /** * Dispatch multiple compute shaders inside a single compute shader pass. * * @param {Array<Compute>} computes - An array of compute shaders to dispatch. * @param {string} [name] - The name of the dispatch, used for debugging and reporting only. */ computeDispatch(computes: Array<Compute>, name?: string): void; /** * Get a renderable HDR pixel format supported by the graphics device. * * Note: * * - When the `filterable` parameter is set to false, this function returns one of the supported * formats on the majority of devices apart from some very old iOS and Android devices (99%). * - When the `filterable` parameter is set to true, the function returns a format on a * considerably lower number of devices (70%). * * @param {number[]} [formats] - An array of pixel formats to check for support. Can contain: * * - {@link PIXELFORMAT_111110F} * - {@link PIXELFORMAT_RGBA16F} * - {@link PIXELFORMAT_RGBA32F} * * @param {boolean} [filterable] - If true, the format also needs to be filterable. Defaults to * true. * @param {number} [samples] - The number of samples to check for. Some formats are not * compatible with multi-sampling, for example {@link PIXELFORMAT_RGBA32F} on WebGPU platform. * Defaults to 1. * @returns {number|undefined} The first supported renderable HDR format or undefined if none is * supported. */ getRenderableHdrFormat(formats?: number[], filterable?: boolean, samples?: number): number | undefined; /** * Validate that all attributes required by the shader are present in the currently assigned * vertex buffers. * * @param {Shader} shader - The shader to validate. * @param {VertexFormat} vb0Format - The format of the first vertex buffer. * @param {VertexFormat} vb1Format - The format of the second vertex buffer. * @protected */ protected validateAttributes(shader: Shader, vb0Format: VertexFormat, vb1Format: VertexFormat): void; } import { EventHandler } from '../../core/event-handler.js'; import type { RenderTarget } from './render-target.js'; import { Vec2 } from '../../core/math/vec2.js'; import { ScopeSpace } from './scope-space.js'; import type { Shader } from './shader.js'; import type { Texture } from './texture.js'; import { VertexBuffer } from './vertex-buffer.js'; import { BlendState } from './blend-state.js'; import { DepthState } from './depth-state.js'; import { StencilParameters } from './stencil-parameters.js'; import type { DynamicBuffers } from './dynamic-buffers.js'; import type { GpuProfiler } from './gpu-profiler.js'; import { Color } from '../../core/math/color.js'; import type { StorageBuffer } from './storage-buffer.js'; import type { IndexBuffer } from './index-buffer.js'; import type { DrawCommands } from './draw-commands.js'; import type { Compute } from './compute.js'; import { VertexFormat } from './vertex-format.js';