123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232 |
- import { RenderTargetWrapper } from "../renderTargetWrapper.js";
- /** @internal */
- export class WebGLRenderTargetWrapper extends RenderTargetWrapper {
- constructor(isMulti, isCube, size, engine, context) {
- super(isMulti, isCube, size, engine);
- /**
- * @internal
- */
- this._framebuffer = null;
- /**
- * @internal
- */
- this._depthStencilBuffer = null;
- // eslint-disable-next-line @typescript-eslint/naming-convention
- /**
- * @internal
- */
- // eslint-disable-next-line @typescript-eslint/naming-convention
- this._MSAAFramebuffer = null;
- // Multiview
- /**
- * @internal
- */
- this._colorTextureArray = null;
- /**
- * @internal
- */
- this._depthStencilTextureArray = null;
- /**
- * @internal
- */
- this._disposeOnlyFramebuffers = false;
- /**
- * @internal
- */
- this._currentLOD = 0;
- this._context = context;
- }
- _cloneRenderTargetWrapper() {
- let rtw = null;
- if (this._colorTextureArray && this._depthStencilTextureArray) {
- rtw = this._engine.createMultiviewRenderTargetTexture(this.width, this.height);
- rtw.texture.isReady = true;
- }
- else {
- rtw = super._cloneRenderTargetWrapper();
- }
- return rtw;
- }
- _swapRenderTargetWrapper(target) {
- super._swapRenderTargetWrapper(target);
- target._framebuffer = this._framebuffer;
- target._depthStencilBuffer = this._depthStencilBuffer;
- target._MSAAFramebuffer = this._MSAAFramebuffer;
- target._colorTextureArray = this._colorTextureArray;
- target._depthStencilTextureArray = this._depthStencilTextureArray;
- this._framebuffer = this._depthStencilBuffer = this._MSAAFramebuffer = this._colorTextureArray = this._depthStencilTextureArray = null;
- }
- /**
- * Creates the depth/stencil texture
- * @param comparisonFunction Comparison function to use for the texture
- * @param bilinearFiltering true if bilinear filtering should be used when sampling the texture
- * @param generateStencil true if the stencil aspect should also be created
- * @param samples sample count to use when creating the texture
- * @param format format of the depth texture
- * @param label defines the label to use for the texture (for debugging purpose only)
- * @returns the depth/stencil created texture
- */
- createDepthStencilTexture(comparisonFunction = 0, bilinearFiltering = true, generateStencil = false, samples = 1, format = 14, label) {
- if (this._depthStencilBuffer) {
- const engine = this._engine;
- // Dispose previous depth/stencil render buffers and clear the corresponding attachment.
- // Next time this framebuffer is bound, the new depth/stencil texture will be attached.
- const currentFrameBuffer = engine._currentFramebuffer;
- const gl = this._context;
- engine._bindUnboundFramebuffer(this._framebuffer);
- gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, null);
- gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, null);
- gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, null);
- engine._bindUnboundFramebuffer(currentFrameBuffer);
- gl.deleteRenderbuffer(this._depthStencilBuffer);
- this._depthStencilBuffer = null;
- }
- return super.createDepthStencilTexture(comparisonFunction, bilinearFiltering, generateStencil, samples, format, label);
- }
- /**
- * Shares the depth buffer of this render target with another render target.
- * @param renderTarget Destination renderTarget
- */
- shareDepth(renderTarget) {
- super.shareDepth(renderTarget);
- const gl = this._context;
- const depthbuffer = this._depthStencilBuffer;
- const framebuffer = renderTarget._MSAAFramebuffer || renderTarget._framebuffer;
- const engine = this._engine;
- if (renderTarget._depthStencilBuffer && renderTarget._depthStencilBuffer !== depthbuffer) {
- gl.deleteRenderbuffer(renderTarget._depthStencilBuffer);
- }
- renderTarget._depthStencilBuffer = depthbuffer;
- const attachment = renderTarget._generateStencilBuffer ? gl.DEPTH_STENCIL_ATTACHMENT : gl.DEPTH_ATTACHMENT;
- engine._bindUnboundFramebuffer(framebuffer);
- gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment, gl.RENDERBUFFER, depthbuffer);
- engine._bindUnboundFramebuffer(null);
- }
- /**
- * Binds a texture to this render target on a specific attachment
- * @param texture The texture to bind to the framebuffer
- * @param attachmentIndex Index of the attachment
- * @param faceIndexOrLayer The face or layer of the texture to render to in case of cube texture or array texture
- * @param lodLevel defines the lod level to bind to the frame buffer
- */
- _bindTextureRenderTarget(texture, attachmentIndex = 0, faceIndexOrLayer, lodLevel = 0) {
- if (!texture._hardwareTexture) {
- return;
- }
- const framebuffer = this._framebuffer;
- const engine = this._engine;
- const currentFB = engine._currentFramebuffer;
- engine._bindUnboundFramebuffer(framebuffer);
- if (engine.webGLVersion > 1) {
- const gl = this._context;
- const attachment = gl["COLOR_ATTACHMENT" + attachmentIndex];
- if (texture.is2DArray || texture.is3D) {
- faceIndexOrLayer = faceIndexOrLayer ?? this.layerIndices?.[attachmentIndex] ?? 0;
- gl.framebufferTextureLayer(gl.FRAMEBUFFER, attachment, texture._hardwareTexture.underlyingResource, lodLevel, faceIndexOrLayer);
- }
- else if (texture.isCube) {
- // if face index is not specified, try to query it from faceIndices
- // default is face 0
- faceIndexOrLayer = faceIndexOrLayer ?? this.faceIndices?.[attachmentIndex] ?? 0;
- gl.framebufferTexture2D(gl.FRAMEBUFFER, attachment, gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndexOrLayer, texture._hardwareTexture.underlyingResource, lodLevel);
- }
- else {
- gl.framebufferTexture2D(gl.FRAMEBUFFER, attachment, gl.TEXTURE_2D, texture._hardwareTexture.underlyingResource, lodLevel);
- }
- }
- else {
- // Default behavior (WebGL)
- const gl = this._context;
- const attachment = gl["COLOR_ATTACHMENT" + attachmentIndex + "_WEBGL"];
- const target = faceIndexOrLayer !== undefined ? gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndexOrLayer : gl.TEXTURE_2D;
- gl.framebufferTexture2D(gl.FRAMEBUFFER, attachment, target, texture._hardwareTexture.underlyingResource, lodLevel);
- }
- engine._bindUnboundFramebuffer(currentFB);
- }
- /**
- * Set a texture in the textures array
- * @param texture the texture to set
- * @param index the index in the textures array to set
- * @param disposePrevious If this function should dispose the previous texture
- */
- setTexture(texture, index = 0, disposePrevious = true) {
- super.setTexture(texture, index, disposePrevious);
- this._bindTextureRenderTarget(texture, index);
- }
- /**
- * Sets the layer and face indices of every render target texture
- * @param layers The layer of the texture to be set (make negative to not modify)
- * @param faces The face of the texture to be set (make negative to not modify)
- */
- setLayerAndFaceIndices(layers, faces) {
- super.setLayerAndFaceIndices(layers, faces);
- if (!this.textures || !this.layerIndices || !this.faceIndices) {
- return;
- }
- // the length of this._attachments is the right one as it does not count the depth texture, in case we generated it
- const textureCount = this._attachments?.length ?? this.textures.length;
- for (let index = 0; index < textureCount; index++) {
- const texture = this.textures[index];
- if (!texture) {
- // The target type was probably -1 at creation time and setTexture has not been called yet for this index
- continue;
- }
- if (texture.is2DArray || texture.is3D) {
- this._bindTextureRenderTarget(texture, index, this.layerIndices[index]);
- }
- else if (texture.isCube) {
- this._bindTextureRenderTarget(texture, index, this.faceIndices[index]);
- }
- else {
- this._bindTextureRenderTarget(texture, index);
- }
- }
- }
- /**
- * Set the face and layer indices of a texture in the textures array
- * @param index The index of the texture in the textures array to modify
- * @param layer The layer of the texture to be set
- * @param face The face of the texture to be set
- */
- setLayerAndFaceIndex(index = 0, layer, face) {
- super.setLayerAndFaceIndex(index, layer, face);
- if (!this.textures || !this.layerIndices || !this.faceIndices) {
- return;
- }
- const texture = this.textures[index];
- if (texture.is2DArray || texture.is3D) {
- this._bindTextureRenderTarget(this.textures[index], index, this.layerIndices[index]);
- }
- else if (texture.isCube) {
- this._bindTextureRenderTarget(this.textures[index], index, this.faceIndices[index]);
- }
- }
- dispose(disposeOnlyFramebuffers = this._disposeOnlyFramebuffers) {
- const gl = this._context;
- if (!disposeOnlyFramebuffers) {
- if (this._colorTextureArray) {
- this._context.deleteTexture(this._colorTextureArray);
- this._colorTextureArray = null;
- }
- if (this._depthStencilTextureArray) {
- this._context.deleteTexture(this._depthStencilTextureArray);
- this._depthStencilTextureArray = null;
- }
- }
- if (this._framebuffer) {
- gl.deleteFramebuffer(this._framebuffer);
- this._framebuffer = null;
- }
- if (this._depthStencilBuffer) {
- gl.deleteRenderbuffer(this._depthStencilBuffer);
- this._depthStencilBuffer = null;
- }
- if (this._MSAAFramebuffer) {
- gl.deleteFramebuffer(this._MSAAFramebuffer);
- this._MSAAFramebuffer = null;
- }
- super.dispose(disposeOnlyFramebuffers);
- }
- }
- //# sourceMappingURL=webGLRenderTargetWrapper.js.map
|