@tolokoban/tgd
Version:
ToloGameDev library for WebGL2
147 lines • 13.6 kB
JavaScript
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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