cables_dev/cables/src/core/cgl/cgl_framebuffer2.js
- // * see framebuffer1
-
-
- import { Logger } from "cables-shared-client";
- import { Texture } from "./cgl_texture.js";
-
-
- const Framebuffer2 = function (cgl, w, h, options)
- {
- this._log = new Logger("cgl_framebuffer2");
- if (cgl.glVersion == 1) return this._log.error("framebuffer2 used on webgl1");
- this.Framebuffer2DrawTargetsDefault = null;
- this.Framebuffer2BlittingFramebuffer = null;
- this.Framebuffer2FinalFramebuffer = null;
- this._cgl = cgl;
-
- this._cgl.printError("before framebuffer2 constructor");
-
- this._width = 0;
- this._height = 0;
- this.valid = true;
-
- this._depthRenderbuffer = null;
- this._frameBuffer = null;
- this._textureFrameBuffer = null;
- this._colorRenderbuffers = [];
- this._drawTargetArray = [];
- this._disposed = false;
-
- if (!this.Framebuffer2BlittingFramebuffer) this.Framebuffer2BlittingFramebuffer = cgl.gl.createFramebuffer();
- if (!this.Framebuffer2FinalFramebuffer) this.Framebuffer2FinalFramebuffer = cgl.gl.createFramebuffer();
-
- if (!this.Framebuffer2DrawTargetsDefault) this.Framebuffer2DrawTargetsDefault = [cgl.gl.COLOR_ATTACHMENT0];
-
- this._options = options || {
- "isFloatingPointTexture": false,
- };
-
- // this._cgl.printError("fb2 before");
-
- this.name = this._options.name || "unknown";
-
- this._cgl.profileData.addHeavyEvent("framebuffer create", this.name);
-
- if (!this._options.hasOwnProperty("numRenderBuffers")) this._options.numRenderBuffers = 1;
- if (!this._options.hasOwnProperty("depth")) this._options.depth = true;
- if (!this._options.hasOwnProperty("clear")) this._options.clear = true;
- if (!this._options.hasOwnProperty("multisampling"))
- {
- this._options.multisampling = false;
- this._options.multisamplingSamples = 0;
- }
-
- if (this._options.multisamplingSamples)
- {
- if (this._cgl.glSlowRenderer) this._options.multisamplingSamples = 0;
- if (!this._cgl.gl.MAX_SAMPLES) this._options.multisamplingSamples = 0;
- else this._options.multisamplingSamples = Math.min(this._cgl.maxSamples, this._options.multisamplingSamples);
- }
-
- if (!this._options.hasOwnProperty("filter")) this._options.filter = Texture.FILTER_LINEAR;
- if (!this._options.hasOwnProperty("wrap")) this._options.wrap = Texture.WRAP_REPEAT;
-
- this._numRenderBuffers = this._options.numRenderBuffers;
- this._colorTextures = [];
-
- this.clearColors = [];
- for (let i = 0; i < this._numRenderBuffers; i++) this.clearColors.push([0, 0, 0, 1]);
-
-
- if (!options.pixelFormat)
- {
- if (options.isFloatingPointTexture) this._options.pixelFormat = Texture.PFORMATSTR_RGBA32F;
- else this._options.pixelFormat = Texture.PFORMATSTR_RGBA8UB;
- }
-
- for (let i = 0; i < this._numRenderBuffers; i++)
- {
- this._colorTextures[i] = new Texture(cgl, {
- "name": "fb2 " + this.name + " " + i,
- "isFloatingPointTexture": this._options.isFloatingPointTexture,
- "anisotropic": this._options.anisotropic || 0,
- "pixelFormat": this._options.pixelFormat,
- "filter": this._options.filter,
- "wrap": this._options.wrap,
- });
- }
-
-
-
- let fil = Texture.FILTER_NEAREST;
- if (this._options.shadowMap) fil = Texture.FILTER_LINEAR;
-
- const defaultTexSize = 512;
-
- if (this._options.depth)
- {
- this._textureDepth = new Texture(cgl,
- {
- "name": "fb2 depth " + this.name,
- "isDepthTexture": true,
- "filter": fil,
- "shadowMap": this._options.shadowMap || false,
- "width": w || defaultTexSize,
- "height": h || defaultTexSize,
- });
- }
-
- if (cgl.aborted) return;
-
- this.setSize(w || defaultTexSize, h || defaultTexSize);
-
- this._cgl.printError("framebuffer2 constructor");
- };
-
- Framebuffer2.prototype.getWidth = function ()
- {
- return this._width;
- };
- Framebuffer2.prototype.getHeight = function ()
- {
- return this._height;
- };
-
- Framebuffer2.prototype.getGlFrameBuffer = function ()
- {
- return this._frameBuffer;
- };
-
- Framebuffer2.prototype.getDepthRenderBuffer = function ()
- {
- return this._depthRenderbuffer;
- };
-
- Framebuffer2.prototype.getTextureColor = function ()
- {
- return this._colorTextures[0];
- };
-
- Framebuffer2.prototype.getTextureColorNum = function (i)
- {
- return this._colorTextures[i];
- };
-
- Framebuffer2.prototype.getTextureDepth = function ()
- {
- return this._textureDepth;
- };
-
- Framebuffer2.prototype.setFilter = function (f)
- {
- for (let i = 0; i < this._numRenderBuffers; i++)
- {
- this._colorTextures[i].filter = f;
- this._colorTextures[i].setSize(this._width, this._height);
- }
- };
-
- Framebuffer2.prototype.delete = Framebuffer2.prototype.dispose = function ()
- {
- this._disposed = true;
- let i = 0;
- for (i = 0; i < this._numRenderBuffers; i++) this._colorTextures[i].delete();
- // this._texture.delete();
- if (this._textureDepth) this._textureDepth.delete();
- for (i = 0; i < this._numRenderBuffers; i++) this._cgl.gl.deleteRenderbuffer(this._colorRenderbuffers[i]);
- this._cgl.gl.deleteRenderbuffer(this._depthRenderbuffer);
- this._cgl.gl.deleteFramebuffer(this._frameBuffer);
- this._cgl.gl.deleteFramebuffer(this._textureFrameBuffer);
- };
-
- Framebuffer2.prototype.setSize = function (w, h)
- {
- if (this._disposed) return this._log.warn("disposed framebuffer setsize...");
- this._cgl.profileData.addHeavyEvent("framebuffer resize", this.name);
-
- let i = 0;
-
- this._width = this._cgl.checkTextureSize(w);
- this._height = this._cgl.checkTextureSize(h);
-
- this._cgl.profileData.profileFrameBuffercreate++;
-
- if (this._frameBuffer)
- {
- for (i = 0; i < this._numRenderBuffers; i++) this._cgl.gl.deleteRenderbuffer(this._colorRenderbuffers[i]);
- // this._cgl.gl.deleteRenderbuffer(this._colorRenderbuffer);
- this._cgl.gl.deleteRenderbuffer(this._depthRenderbuffer);
- this._cgl.gl.deleteFramebuffer(this._frameBuffer);
- this._cgl.gl.deleteFramebuffer(this._textureFrameBuffer);
- }
-
- this._frameBuffer = this._cgl.gl.createFramebuffer();
- this._textureFrameBuffer = this._cgl.gl.createFramebuffer();
-
- const depth = this._options.depth;
-
- for (i = 0; i < this._numRenderBuffers; i++)
- {
- this._colorTextures[i].setSize(this._width, this._height);
- }
-
- for (i = 0; i < this._numRenderBuffers; i++)
- {
- const renderBuffer = this._cgl.gl.createRenderbuffer();
-
- // color renderbuffer
-
- this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER, this._frameBuffer);
- this._cgl.gl.bindRenderbuffer(this._cgl.gl.RENDERBUFFER, renderBuffer);
-
- const info = Texture.setUpGlPixelFormat(this._cgl, this._options.pixelFormat);
- let internFormat = info.glInternalFormat;
-
- // if (this._options.isFloatingPointTexture)
- // {
- if (CGL.Texture.isPixelFormatHalfFloat(info.pixelFormat))
- {
- if (!this._cgl.enableExtension("OES_texture_float_linear"))
- {
- this._options.filter = Texture.FILTER_NEAREST;
- this.setFilter(this._options.filter);
- }
- }
- else if (CGL.Texture.isPixelFormatFloat(info.pixelFormat))
- {
- if (!this._cgl.enableExtension("OES_texture_float_linear"))
- {
- this._log.warn("no linear pixelformat,using nearest");
- this._options.filter = Texture.FILTER_NEAREST;
- this.setFilter(this._options.filter);
- }
- }
- // else if (info.pixelFormat == Texture.PFORMATSTR_RGBA32F || info.pixelFormat == Texture.PFORMATSTR_R11FG11FB10F
- // else if (info.pixelFormat == Texture.PFORMATSTR_RGBA32F || info.pixelFormat == Texture.PFORMATSTR_R11FG11FB10F
- // else if (info.pixelFormat == Texture.PFORMATSTR_RG16F)
- // {
- // const extcb = this._cgl.enableExtension("EXT_color_buffer_float");
-
- // if (!this._cgl.enableExtension("OES_texture_float_linear"))
- // {
- // console.log("no linear pixelformat,switching to nearest");
- // this._options.filter = Texture.FILTER_NEAREST;
- // this.setFilter(this._options.filter);
- // }
- // }
- // }
-
- if (this._options.multisampling && this._options.multisamplingSamples)
- {
- this._cgl.gl.renderbufferStorageMultisample(this._cgl.gl.RENDERBUFFER, this._options.multisamplingSamples, internFormat, this._width, this._height);
- }
- else
- {
- this._cgl.gl.renderbufferStorage(this._cgl.gl.RENDERBUFFER, internFormat, this._width, this._height);
- }
-
-
-
- this._cgl.gl.framebufferRenderbuffer(this._cgl.gl.FRAMEBUFFER, this._cgl.gl.COLOR_ATTACHMENT0 + i, this._cgl.gl.RENDERBUFFER, renderBuffer);
- this._colorRenderbuffers[i] = renderBuffer;
- }
-
- // this._cgl.gl.bindFramebuffer(this._cgl.gl.DRAW_FRAMEBUFFER, this._textureFrameBuffer);
- this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER, this._textureFrameBuffer);
-
- for (i = 0; i < this._numRenderBuffers; i++)
- {
- this._cgl.gl.framebufferTexture2D(this._cgl.gl.FRAMEBUFFER, this._cgl.gl.COLOR_ATTACHMENT0 + i, this._cgl.gl.TEXTURE_2D, this._colorTextures[i].tex, 0);
- }
-
- if (this._options.depth)
- {
- this._cgl.gl.framebufferTexture2D(this._cgl.gl.FRAMEBUFFER, this._cgl.gl.DEPTH_ATTACHMENT, this._cgl.gl.TEXTURE_2D, this._textureDepth.tex, 0);
- }
-
- // depth renderbuffer
-
- this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER, this._frameBuffer);
-
-
- let depthType = this._cgl.gl.DEPTH_COMPONENT32F;
-
- if (this._cgl.glSlowRenderer) depthType = this._cgl.gl.DEPTH_COMPONENT16;
- if (depth)
- {
- this._textureDepth.setSize(this._width, this._height);
- this._depthRenderbuffer = this._cgl.gl.createRenderbuffer();
-
- this._cgl.gl.bindRenderbuffer(this._cgl.gl.RENDERBUFFER, this._depthRenderbuffer);
- if (this._options.isFloatingPointTexture)
- {
- if (this._options.multisampling) this._cgl.gl.renderbufferStorageMultisample(this._cgl.gl.RENDERBUFFER, this._options.multisamplingSamples, depthType, this._width, this._height);
- else this._cgl.gl.renderbufferStorage(this._cgl.gl.RENDERBUFFER, depthType, this._width, this._height);
- }
- else if (this._options.multisampling)
- {
- this._cgl.gl.renderbufferStorageMultisample(this._cgl.gl.RENDERBUFFER, this._options.multisamplingSamples, depthType, this._width, this._height);
- // this._cgl.gl.renderbufferStorage(this._cgl.gl.RENDERBUFFER,depthType, this._width, this._height);
- }
- else
- {
- this._cgl.gl.renderbufferStorage(this._cgl.gl.RENDERBUFFER, depthType, this._width, this._height);
- }
-
- this._cgl.gl.framebufferRenderbuffer(this._cgl.gl.FRAMEBUFFER, this._cgl.gl.DEPTH_ATTACHMENT, this._cgl.gl.RENDERBUFFER, this._depthRenderbuffer);
- }
-
- // this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER, null);
- // this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER, this._textureFrameBuffer);
-
- this._drawTargetArray.length = 0;
- for (i = 0; i < this._numRenderBuffers; i++) this._drawTargetArray.push(this._cgl.gl.COLOR_ATTACHMENT0 + i);
-
- // this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER, null);
-
-
- if (!this._cgl.gl.isFramebuffer(this._textureFrameBuffer)) this._log.warn("invalid framebuffer");// throw new Error("Invalid framebuffer");
- const status = this._cgl.gl.checkFramebufferStatus(this._cgl.gl.FRAMEBUFFER);
-
- if (status != this._cgl.gl.FRAMEBUFFER_COMPLETE)
- {
- this._log.error("framebuffer incomplete: " + this.name, this);
- this._log.log("options", this._options);
- this._log.log("options pixelformat", this._options.pixelFormat);
-
- switch (status)
- {
- case this._cgl.gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
- this._log.warn("FRAMEBUFFER_INCOMPLETE_ATTACHMENT...", this);
- throw new Error("Incomplete framebuffer: FRAMEBUFFER_INCOMPLETE_ATTACHMENT");
- case this._cgl.gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
- this._log.warn("FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT");
- throw new Error("Incomplete framebuffer: FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT");
- case this._cgl.gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
- this._log.warn("FRAMEBUFFER_INCOMPLETE_DIMENSIONS");
- throw new Error("Incomplete framebuffer: FRAMEBUFFER_INCOMPLETE_DIMENSIONS");
- case this._cgl.gl.FRAMEBUFFER_UNSUPPORTED:
- this._log.warn("FRAMEBUFFER_UNSUPPORTED");
- throw new Error("Incomplete framebuffer: FRAMEBUFFER_UNSUPPORTED");
- default:
- this.valid = false;
- this._log.error("incomplete framebuffer", status, this._frameBuffer);
- this._cgl.printError();
-
- this._frameBuffer = null;
- // debugger;
- throw new Error("Incomplete framebuffer: " + status);
-
- // throw("Incomplete framebuffer: " + status);
- }
- }
-
- this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER, null);
- this._cgl.gl.bindRenderbuffer(this._cgl.gl.RENDERBUFFER, null);
-
- // this._cgl.printError("fb setsize");
- };
-
- Framebuffer2.prototype.renderStart = function ()
- {
- if (this._disposed) return this._log.warn("disposed framebuffer renderStart...");
- this._cgl.checkFrameStarted("fb2 renderstart");
- this._cgl.pushModelMatrix(); // needed ??
-
- this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER, this._frameBuffer);
- this._cgl.pushGlFrameBuffer(this._frameBuffer);
- this._cgl.pushFrameBuffer(this);
-
- this._cgl.pushPMatrix();
- this._cgl.pushViewPort(0, 0, this._width, this._height);
-
- this._cgl.gl.drawBuffers(this._drawTargetArray);
-
- if (this._options.clear)
- {
- this._cgl.gl.clearColor(0, 0, 0, 0);
- this._cgl.gl.clear(this._cgl.gl.COLOR_BUFFER_BIT | this._cgl.gl.DEPTH_BUFFER_BIT);
- }
- };
-
- Framebuffer2.prototype.clear = function ()
- {
- if (this._numRenderBuffers <= 1)
- {
- this._cgl.gl.bindFramebuffer(this._cgl.gl.READ_FRAMEBUFFER, this._frameBuffer);
- this._cgl.gl.bindFramebuffer(this._cgl.gl.DRAW_FRAMEBUFFER, this._textureFrameBuffer);
- }
- else this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER, this._frameBuffer);
-
- this._cgl.gl.drawBuffers(this._drawTargetArray);
-
- for (let i = 0; i < this._numRenderBuffers; i++)
- {
- this._cgl.gl.framebufferTexture2D(this._cgl.gl.FRAMEBUFFER, this._cgl.gl.COLOR_ATTACHMENT0 + i, this._cgl.gl.TEXTURE_2D, this._colorTextures[i].tex, 0);
- this._cgl.gl.clearBufferfv(this._cgl.gl.COLOR, i, this.clearColors[i]);
- }
- this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER, null);
- };
-
- Framebuffer2.prototype.renderEnd = function ()
- {
- if (this._disposed) return this._log.warn("disposed framebuffer renderEnd...");
- this._cgl.popPMatrix();
-
- this._cgl.profileData.profileFramebuffer++;
-
-
- if (this._numRenderBuffers <= 1)
- {
- this._cgl.gl.bindFramebuffer(this._cgl.gl.READ_FRAMEBUFFER, this._frameBuffer);
- this._cgl.gl.bindFramebuffer(this._cgl.gl.DRAW_FRAMEBUFFER, this._textureFrameBuffer);
-
- this._cgl.gl.clearBufferfv(this._cgl.gl.COLOR, 0, [0.0, 0.0, 0.0, 1.0]);
- this._cgl.gl.blitFramebuffer(0, 0, this._width, this._height, 0, 0, this._width, this._height, this._cgl.gl.COLOR_BUFFER_BIT | this._cgl.gl.DEPTH_BUFFER_BIT, this._cgl.gl.NEAREST);
- }
- else
- {
- this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER, this.Framebuffer2BlittingFramebuffer);
- this._cgl.gl.framebufferRenderbuffer(this._cgl.gl.FRAMEBUFFER, this._cgl.gl.DEPTH_ATTACHMENT, this._cgl.gl.RENDERBUFFER, this._depthRenderbuffer);
-
- this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER, this.Framebuffer2FinalFramebuffer);
- this._cgl.gl.framebufferTexture2D(this._cgl.gl.FRAMEBUFFER, this._cgl.gl.DEPTH_ATTACHMENT, this._cgl.gl.TEXTURE_2D, this._textureDepth.tex, 0);
-
- for (let i = 0; i < this._numRenderBuffers; i++)
- {
- this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER, this.Framebuffer2BlittingFramebuffer);
- this._cgl.gl.framebufferRenderbuffer(this._cgl.gl.FRAMEBUFFER, this._cgl.gl.COLOR_ATTACHMENT0, this._cgl.gl.RENDERBUFFER, this._colorRenderbuffers[i]);
-
-
- this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER, this.Framebuffer2FinalFramebuffer);
- this._cgl.gl.framebufferTexture2D(this._cgl.gl.FRAMEBUFFER, this._cgl.gl.COLOR_ATTACHMENT0, this._cgl.gl.TEXTURE_2D, this._colorTextures[i].tex, 0);
-
- this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER, null);
-
- this._cgl.gl.bindFramebuffer(this._cgl.gl.READ_FRAMEBUFFER, this.Framebuffer2BlittingFramebuffer);
- this._cgl.gl.bindFramebuffer(this._cgl.gl.DRAW_FRAMEBUFFER, this.Framebuffer2FinalFramebuffer);
-
- // this._cgl.gl.clearBufferfv(this._cgl.gl.COLOR, i, [0.0, 0.0, 0.0, 1.0]);
-
-
-
- let flags = this._cgl.gl.COLOR_BUFFER_BIT;
- if (i == 0) flags |= this._cgl.gl.DEPTH_BUFFER_BIT;
-
- this._cgl.gl.blitFramebuffer(0, 0, this._width, this._height, 0, 0, this._width, this._height, flags, this._cgl.gl.NEAREST);
- }
- }
-
- this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER, this._cgl.popGlFrameBuffer());
- this._cgl.popFrameBuffer();
-
- this._cgl.popModelMatrix();
- // this._cgl.resetViewPort();
- this._cgl.popViewPort();
-
-
- if (this._colorTextures[0].filter == Texture.FILTER_MIPMAP)
- {
- for (let i = 0; i < this._numRenderBuffers; i++)
- {
- this._cgl.gl.bindTexture(this._cgl.gl.TEXTURE_2D, this._colorTextures[i].tex);
- this._colorTextures[i].updateMipMap();
- this._cgl.gl.bindTexture(this._cgl.gl.TEXTURE_2D, null);
- }
- }
- };
-
- export { Framebuffer2 };
-
- /// ///////