From 5d16c727f86203316a96bd5a3f6040060ec06494 Mon Sep 17 00:00:00 2001 From: Alexander Artemev Date: Tue, 24 Jan 2023 00:36:36 +0700 Subject: [PATCH] TILES-4933: Support depth texture --- index.d.ts | 2 ++ src/RenderTarget.js | 55 +++++++++++++++++++++++++++++++++++++++------ src/Texture.js | 4 ++++ 3 files changed, 54 insertions(+), 7 deletions(-) diff --git a/index.d.ts b/index.d.ts index f40b381..b68d8ea 100644 --- a/index.d.ts +++ b/index.d.ts @@ -140,6 +140,7 @@ declare module '2gl' { export interface RenderTargetOptions extends TextureOptions { size: Vec2; + depthTexture: boolean; } export class Object3D { @@ -186,6 +187,7 @@ declare module '2gl' { public remove(gl: WebGLRenderingContext): this; public setSize(size: Vec2): this; public getTexture(): Texture; + public getDepthBuffer(): Texture | WebGLRenderbuffer | null; } export interface RendererState { diff --git a/src/RenderTarget.js b/src/RenderTarget.js index 0eca1d2..dfdbf5e 100644 --- a/src/RenderTarget.js +++ b/src/RenderTarget.js @@ -21,6 +21,13 @@ class RenderTarget { */ this._texture = new Texture(null, this.options); + + /** + * @type {Texture | WebGLRenderbuffer | null} + * @ignore + */ + this._depthBuffer = null; + /** * Контекст WebGL, в котором был инициализирован фреймбуфер. * Используется только для удаления, подумать хорошо, прежде чем использовать для чего-то ещё. @@ -79,6 +86,14 @@ class RenderTarget { return this._texture; } + /** + * Возвращает текущие буфер или текстуру глубины фреймбуфера + * @return {Texture | WebGLRenderbuffer | null} + */ + getDepthBuffer() { + return this._depthBuffer; + } + /** * Инициализирует фреймбуфер, текстуры и рендербуфер * @param {WebGLRenderingContext} gl @@ -96,12 +111,32 @@ class RenderTarget { this._frameBuffer = gl.createFramebuffer(); gl.bindFramebuffer(gl.FRAMEBUFFER, this._frameBuffer); - this._renderBuffer = gl.createRenderbuffer(); - gl.bindRenderbuffer(gl.RENDERBUFFER, this._renderBuffer); - gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, this.options.size[0], this.options.size[1]); - gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this._texture.getTexture(), 0); - gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, this._renderBuffer); + + if (this.options.depthTexture) { + this._depthBuffer = new Texture(null, { + magFilter: Texture.NearestFilter, + minFilter: Texture.NearestFilter, + format: Texture.DepthComponentFormat, + size: this.options.size, + premultiplyAlpha: false, + generateMipmaps: false, + type: Texture.UnsignedInt, + }); + this._depthBuffer.prepare(gl); + gl.framebufferTexture2D( + gl.FRAMEBUFFER, + gl.DEPTH_ATTACHMENT, + gl.TEXTURE_2D, + this._depthBuffer.getTexture(), + 0 + ); + } else { + this._depthBuffer = gl.createRenderbuffer(); + gl.bindRenderbuffer(gl.RENDERBUFFER, this._depthBuffer); + gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, this.options.size[0], this.options.size[1]); + gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, this._depthBuffer); + } this._checkComplete(gl); @@ -119,11 +154,15 @@ class RenderTarget { this._texture = null; } + if (this._depthBuffer) { + this._depthBuffer instanceof Texture ? + this._depthBuffer.remove(this._glContext) : this._glContext.deleteRenderbuffer(this._depthBuffer); + this._depthBuffer = null; + } + if (this._frameBuffer) { this._glContext.deleteFramebuffer(this._frameBuffer); - this._glContext.deleteRenderbuffer(this._renderBuffer); this._frameBuffer = null; - this._renderBuffer = null; } } @@ -154,6 +193,7 @@ class RenderTarget { RenderTarget.defaultOptions = Object.assign({}, Texture.defaultOptions, { size: [0, 0], generateMipmaps: false, + depthTexture: false, }); export default RenderTarget; @@ -163,4 +203,5 @@ export default RenderTarget; * * @typedef {Object} RenderTargetOptions * @property {Number[]} size + * @property {Boolean} depthTexture */ diff --git a/src/Texture.js b/src/Texture.js index 2ccffd0..39fa710 100644 --- a/src/Texture.js +++ b/src/Texture.js @@ -165,9 +165,11 @@ class Texture { if (param === Texture.RgbaFormat) { return gl.RGBA; } if (param === Texture.AlphaFormat) { return gl.ALPHA; } if (param === Texture.RgbFormat) { return gl.RGB; } + if (param === Texture.DepthComponentFormat) { return gl.DEPTH_COMPONENT; } if (param === Texture.UnsignedByte) { return gl.UNSIGNED_BYTE; } if (param === Texture.Float) { return gl.FLOAT; } + if (param === Texture.UnsignedInt) { return gl.UNSIGNED_INT; } return null; } @@ -184,12 +186,14 @@ Texture.LinearFilter = 4; Texture.LinearMipMapNearestFilter = 5; Texture.LinearMipMapLinearFilter = 6; +Texture.DepthComponentFormat = 7; Texture.RgbaFormat = 11; Texture.AlphaFormat = 12; Texture.RgbFormat = 13; Texture.UnsignedByte = 14; Texture.Float = 15; +Texture.UnsignedInt = 16; Texture.defaultOptions = { magFilter: Texture.LinearFilter,