UNPKG

@tolokoban/tgd

Version:

ToloGameDev library for WebGL2

147 lines 13.6 kB
import { TgdPainterGroup } from "./group.js"; import { webglCreateFramebuffer, webglLookup } from "./../utils/index.js"; export class TgdPainterFramebuffer extends TgdPainterGroup { constructor(context, options) { super(options.children); this.context = context; this.options = options; /** * The framebuffer becomes dirty as soon as the width or height changes. */ this.dirty = true; this._width = 0; this._height = 0; this._framebuffer = null; this._depthBuffer = null; this._stencilBuffer = null; const { textureColor0, textureColor1, textureColor2, textureColor3 } = options; if (!(textureColor0 || textureColor1 || textureColor2 || textureColor3)) { console.error("[TgdPainterFramebuffer] You gave no color texture in the constructor: nothing will be rendered!"); } this.textureColor0 = textureColor0; this.textureColor1 = textureColor1; this.textureColor2 = textureColor2; this.textureColor3 = textureColor3; this.textureDepth = options.textureDepth; this.onEnter = options.onEnter; this.onExit = options.onExit; const { gl } = this.context; this.drawBuffers = [ this.textureColor0 ? gl.COLOR_ATTACHMENT0 : gl.NONE, this.textureColor1 ? gl.COLOR_ATTACHMENT1 : gl.NONE, this.textureColor2 ? gl.COLOR_ATTACHMENT2 : gl.NONE, this.textureColor3 ? gl.COLOR_ATTACHMENT3 : gl.NONE, ]; } get width() { return this._width; } set width(v) { if (this._width === v) return; this._width = v; this.dirty = true; } get height() { return this._height; } set height(v) { if (this._height === v) return; this._height = v; this.dirty = true; } updateTextureForColor(tgdTexture, attachment) { if (!tgdTexture) return; const { context, width, height } = this; const { gl } = context; tgdTexture.resize(width, height); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + attachment, gl.TEXTURE_2D, tgdTexture.glTexture, 0); } createTextureForDepth() { const tgdTexture = this.textureDepth; if (!tgdTexture) return; const { context, width, height } = this; const { gl } = context; tgdTexture.resize(width, height); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, tgdTexture.glTexture, 0); } createDepthBuffer(gl) { if (this.options.depthBuffer === false) return; const { width, height } = this; // Create a Depth Buffer, because the default // framebuffer has none. const depthBuffer = gl.createRenderbuffer(); if (!depthBuffer) throw new Error("Unable to create WebGLRenderBuffer for depth!"); this._depthBuffer = depthBuffer; gl.bindRenderbuffer(gl.RENDERBUFFER, depthBuffer); gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, width, height); gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthBuffer); } createStencilBuffer(gl) { if (this.options.stencilBuffer !== false) { const { width, height } = this; const stencilBuffer = gl.createRenderbuffer(); if (!stencilBuffer) throw new Error("Unable to create WebGLRenderBuffer for stencil!"); this._stencilBuffer = stencilBuffer; gl.bindRenderbuffer(gl.RENDERBUFFER, stencilBuffer); gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, width, height); gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, stencilBuffer); } } createFramebufferIfNeeded() { if (!this.dirty) return; const { context } = this; const { gl } = context; this.delete(); this._framebuffer = webglCreateFramebuffer(gl); gl.bindFramebuffer(gl.FRAMEBUFFER, this._framebuffer); this.updateTextureForColor(this.textureColor0, 0); this.updateTextureForColor(this.textureColor1, 1); this.updateTextureForColor(this.textureColor2, 2); this.updateTextureForColor(this.textureColor3, 3); this.createTextureForDepth(); this.createDepthBuffer(gl); this.createStencilBuffer(gl); const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER); if (status !== gl.FRAMEBUFFER_COMPLETE) { console.error(`Your Framebuffer is incomplete: ${webglLookup(status)}!`); } this.dirty = false; } paint(time, delay) { const { context, options } = this; const { gl } = context; const { viewportMatchingScale = 1 } = options; this.width = Math.round(context.width * viewportMatchingScale); this.height = Math.round(context.height * viewportMatchingScale); this.createFramebufferIfNeeded(); gl.bindFramebuffer(gl.FRAMEBUFFER, this._framebuffer); gl.drawBuffers(this.drawBuffers); super.paint(time, delay); gl.bindFramebuffer(gl.FRAMEBUFFER, null); } delete() { const { context, _framebuffer, _depthBuffer, _stencilBuffer } = this; const { gl } = context; if (_framebuffer) { gl.deleteFramebuffer(_framebuffer); this._framebuffer = null; } if (_depthBuffer) { gl.deleteRenderbuffer(_depthBuffer); this._depthBuffer = null; } if (_stencilBuffer) { gl.deleteRenderbuffer(_stencilBuffer); this._stencilBuffer = null; } } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZnJhbWVidWZmZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcGFpbnRlci9mcmFtZWJ1ZmZlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sU0FBUyxDQUFBO0FBQ3pDLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxXQUFXLEVBQUUsTUFBTSxZQUFZLENBQUE7QUEwQ2hFLE1BQU0sT0FBTyxxQkFBc0IsU0FBUSxlQUFlO0lBa0J0RCxZQUNxQixPQUFtQixFQUNuQixPQUE4QztRQUUvRCxLQUFLLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFBO1FBSE4sWUFBTyxHQUFQLE9BQU8sQ0FBWTtRQUNuQixZQUFPLEdBQVAsT0FBTyxDQUF1QztRQWJuRTs7V0FFRztRQUNLLFVBQUssR0FBRyxJQUFJLENBQUE7UUFDWixXQUFNLEdBQUcsQ0FBQyxDQUFBO1FBQ1YsWUFBTyxHQUFHLENBQUMsQ0FBQTtRQUNYLGlCQUFZLEdBQTRCLElBQUksQ0FBQTtRQUM1QyxpQkFBWSxHQUE2QixJQUFJLENBQUE7UUFDN0MsbUJBQWMsR0FBNkIsSUFBSSxDQUFBO1FBUW5ELE1BQU0sRUFBRSxhQUFhLEVBQUUsYUFBYSxFQUFFLGFBQWEsRUFBRSxhQUFhLEVBQUUsR0FDaEUsT0FBTyxDQUFBO1FBQ1gsSUFDSSxDQUFDLENBQUMsYUFBYSxJQUFJLGFBQWEsSUFBSSxhQUFhLElBQUksYUFBYSxDQUFDLEVBQ3JFLENBQUM7WUFDQyxPQUFPLENBQUMsS0FBSyxDQUNULGlHQUFpRyxDQUNwRyxDQUFBO1FBQ0wsQ0FBQztRQUNELElBQUksQ0FBQyxhQUFhLEdBQUcsYUFBYSxDQUFBO1FBQ2xDLElBQUksQ0FBQyxhQUFhLEdBQUcsYUFBYSxDQUFBO1FBQ2xDLElBQUksQ0FBQyxhQUFhLEdBQUcsYUFBYSxDQUFBO1FBQ2xDLElBQUksQ0FBQyxhQUFhLEdBQUcsYUFBYSxDQUFBO1FBQ2xDLElBQUksQ0FBQyxZ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