cables_dev/cables/src/core/cgl/cgl_framebuffer.js
- import { Logger } from "cables-shared-client";
- import { Texture } from "./cgl_texture.js";
-
- // todo: convert to prototyped...
-
- /**
- * a framebuffer
- * @constructor
- * @class
- * @constructs Framebuffer
- * @param {Context} _cgl cgl
- * @param {Number} _w width
- * @param {Number} _h height
- * @param {Object} options
- */
- const Framebuffer = function (_cgl, _w, _h, options)
- {
- const cgl = _cgl;
- this._log = new Logger("Framebuffer");
- this.valid = true;
-
- let depthTextureExt = cgl.gl.DEPTH_TEXTURE;
- if (!depthTextureExt) depthTextureExt = cgl.enableExtension("WEBGL_depth_texture");
- if (!depthTextureExt) depthTextureExt = cgl.enableExtension("WEBKIT_WEBGL_depth_texture");
- if (!depthTextureExt) depthTextureExt = cgl.enableExtension("MOZ_WEBGL_depth_texture");
-
- if (!depthTextureExt)
- {
- this._log.error("NO_DEPTH_TEXTURE", "no depth texture support");
- return;
- }
-
- let width = _w || 512;
- let height = _h || 512;
-
- options = options || {
- "isFloatingPointTexture": false,
- };
-
- if (!options.hasOwnProperty("clear")) options.clear = true;
- if (!options.hasOwnProperty("filter")) options.filter = Texture.FILTER_LINEAR;
-
- const texture = new Texture(cgl, {
- "isFloatingPointTexture": options.isFloatingPointTexture,
- "filter": options.filter,
- "wrap": options.wrap || Texture.CLAMP_TO_EDGE
- });
-
- let textureDepth = null;
- if (depthTextureExt)
- {
- textureDepth = new Texture(cgl, {
- "isDepthTexture": true,
- });
- }
- this._options = options;
-
- const frameBuf = cgl.gl.createFramebuffer();
- const depthBuffer = cgl.gl.createRenderbuffer();
-
- this.getWidth = function ()
- {
- return width;
- };
- this.getHeight = function ()
- {
- return height;
- };
-
- /**
- * get native gl framebuffer
- * @function getGlFrameBuffer
- * @memberof Framebuffer
- * @returns {Object} framebuffer
- */
- this.getGlFrameBuffer = function ()
- {
- return frameBuf;
- };
-
- /**
- * get depth renderbuffer
- * @function getDepthRenderBuffer
- * @memberof Framebuffer
- * @returns {Object} renderbuffer
- */
- this.getDepthRenderBuffer = function ()
- {
- return depthBuffer;
- };
-
- /**
- * get color texture
- * @function getTextureColor
- * @memberof Framebuffer
- * @returns {Texture} rgba texture
- */
- this.getTextureColor = function ()
- {
- return texture;
- };
-
- /**
- * get depth texture
- * @function getTextureDepth
- * @memberof Framebuffer
- * @returns {Texture} depth texture
- */
- this.getTextureDepth = function ()
- {
- return textureDepth;
- };
-
- this.setFilter = function (f)
- {
- texture.filter = f;
- texture.setSize(width, height);
- };
-
- this.setSize = function (w, h)
- {
- if (w < 2) w = 2;
- if (h < 2) h = 2;
-
- width = Math.ceil(w);
- height = Math.ceil(h);
-
- cgl.profileData.profileFrameBuffercreate++;
-
- cgl.gl.bindFramebuffer(cgl.gl.FRAMEBUFFER, frameBuf);
- cgl.gl.bindRenderbuffer(cgl.gl.RENDERBUFFER, depthBuffer);
-
- texture.setSize(width, height);
- if (textureDepth) textureDepth.setSize(width, height);
-
- // if(depthTextureExt) cgl.gl.renderbufferStorage(cgl.gl.RENDERBUFFER, cgl.gl.DEPTH_COMPONENT16, width,height);
- if (depthTextureExt) cgl.gl.renderbufferStorage(cgl.gl.RENDERBUFFER, cgl.gl.DEPTH_COMPONENT16, width, height);
-
- cgl.gl.framebufferTexture2D(cgl.gl.FRAMEBUFFER, cgl.gl.COLOR_ATTACHMENT0, cgl.gl.TEXTURE_2D, texture.tex, 0);
-
- if (depthTextureExt)
- {
- cgl.gl.framebufferRenderbuffer(cgl.gl.FRAMEBUFFER, cgl.gl.DEPTH_ATTACHMENT, cgl.gl.RENDERBUFFER, depthBuffer);
- cgl.gl.framebufferTexture2D(
- cgl.gl.FRAMEBUFFER,
- cgl.gl.DEPTH_ATTACHMENT, // safari needs DEPTH_ATTACHMENT NOT DEPTH_ATTACHMENT16
- // cgl.gl.DEPTH_COMPONENT16,
- cgl.gl.TEXTURE_2D,
- textureDepth.tex,
- 0,
- );
- }
-
- if (!cgl.gl.isFramebuffer(frameBuf)) throw new Error("Invalid framebuffer");
- const status = cgl.gl.checkFramebufferStatus(cgl.gl.FRAMEBUFFER);
-
- switch (status)
- {
- case cgl.gl.FRAMEBUFFER_COMPLETE:
- break;
- case cgl.gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
- this._log.warn("FRAMEBUFFER_INCOMPLETE_ATTACHMENT...", width, height, texture.tex, depthBuffer);
- this.valid = false;
- throw new Error("Incomplete framebuffer: FRAMEBUFFER_INCOMPLETE_ATTACHMENT");
- case cgl.gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
- this._log.warn("FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT");
- this.valid = false;
- throw new Error("Incomplete framebuffer: FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT");
- case cgl.gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
- this._log.warn("FRAMEBUFFER_INCOMPLETE_DIMENSIONS");
- this.valid = false;
- throw new Error("Incomplete framebuffer: FRAMEBUFFER_INCOMPLETE_DIMENSIONS");
- case cgl.gl.FRAMEBUFFER_UNSUPPORTED:
- this._log.warn("FRAMEBUFFER_UNSUPPORTED");
- this.valid = false;
- this._log.warn(width, height, options);
-
- throw new Error("Incomplete framebuffer: FRAMEBUFFER_UNSUPPORTED");
- case 0x8CDB:
- this._log.warn("Incomplete: FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER from ext. Or Safari/iOS undefined behaviour.");
- this.valid = false;
- break;
- default:
- this._log.warn("incomplete framebuffer", status);
- this.valid = false;
- throw new Error("Incomplete framebuffer: " + status);
- }
-
- cgl.gl.bindTexture(cgl.gl.TEXTURE_2D, null);
- cgl.gl.bindRenderbuffer(cgl.gl.RENDERBUFFER, null);
- cgl.gl.bindFramebuffer(cgl.gl.FRAMEBUFFER, null);
- };
-
- this.renderStart = function ()
- {
- cgl.pushModelMatrix();
- cgl.gl.bindFramebuffer(cgl.gl.FRAMEBUFFER, frameBuf);
- cgl.pushGlFrameBuffer(frameBuf);
- cgl.pushFrameBuffer(this);
-
- cgl.pushPMatrix();
- cgl.gl.viewport(0, 0, width, height);
-
- if (this._options.clear)
- {
- cgl.gl.clearColor(0, 0, 0, 0);
- cgl.gl.clear(cgl.gl.COLOR_BUFFER_BIT | cgl.gl.DEPTH_BUFFER_BIT);
- }
- };
-
- this.renderEnd = function ()
- {
- cgl.popPMatrix();
- cgl.gl.bindFramebuffer(cgl.gl.FRAMEBUFFER, cgl.popGlFrameBuffer());
- cgl.popFrameBuffer();
-
- cgl.popModelMatrix();
- cgl.resetViewPort();
- };
-
-
- this.delete = function ()
- {
- texture.delete();
- this.valid = false;
- if (textureDepth) textureDepth.delete();
- cgl.gl.deleteRenderbuffer(depthBuffer);
- cgl.gl.deleteFramebuffer(frameBuf);
- };
-
- this.dispose = this.delete;
-
- this.setSize(width, height);
- };
-
- export { Framebuffer };