cables_dev/cables/src/core/cgl/cgl_state.js
- import { Logger } from "cables-shared-client";
- import { CONSTANTS } from "./constants.js";
- import { Shader } from "./cgl_shader.js";
- import { ProfileData } from "./cgl_profiledata.js";
- import { CGState } from "../cg/cg_state.js";
- import { CG } from "../cg/cg_constants.js";
-
-
- /**
- * cables gl context/state manager
- * @class
- * @namespace external:CGL
- * @hideconstructor
- */
- // const Context(_patch)
- class Context extends CGState
- {
- constructor(_patch)
- {
- super(_patch);
-
- this.gApi = CG.GAPI_WEBGL;
- this.aborted = false;
-
- this.pushMvMatrix = this.pushModelMatrix; // deprecated and wrong... still used??
- this.popMvMatrix = this.popmMatrix = this.popModelMatrix;// deprecated and wrong... still used??
-
- this.profileData = new ProfileData(this);
- this._log = new Logger("cgl_context", { "onError": _patch.config.onError });
- this._viewPort = [0, 0, 0, 0];
- this.glVersion = 0;
- this.glUseHalfFloatTex = false;
- this.clearCanvasTransparent = true;
- this.clearCanvasDepth = true;
- this.debugOneFrame = false;
- this.checkGlErrors = false; // true is slow // false should be default...
- this.maxTextureUnits = 0;
- this.maxVaryingVectors = 0;
- this.currentProgram = null;
- this._hadStackError = false;
- this.glSlowRenderer = false;
- this._isSafariCrap = false;
-
- this.temporaryTexture = null;
- this._onetimeCallbacks = [];
- this.gl = null;
-
- this._cursor = "auto";
- this._currentCursor = "";
-
- this._viewPortStack = [];
- this._glFrameBufferStack = [];
- this._frameBufferStack = [];
- this._shaderStack = [];
- this._stackDepthTest = [];
- this.mainloopOp = null;
-
- this._simpleShader = new Shader(this, "simpleshader");
- this._simpleShader.setModules(["MODULE_VERTEX_POSITION", "MODULE_COLOR", "MODULE_BEGIN_FRAG", "MODULE_VERTEX_MODELVIEW"]);
- this._simpleShader.setSource(Shader.getDefaultVertexShader(), Shader.getDefaultFragmentShader());
-
- this._currentShader = this._simpleShader;
-
-
- this._oldCanvasWidth = -1;
- this._oldCanvasHeight = -1;
- this._enabledExtensions = {};
- }
-
- // set pixelDensity(p)
- // {
- // this._pixelDensity = p;
- // }
-
- // get pixelDensity()
- // {
- // return this._pixelDensity;
- // }
-
-
-
- get viewPort()
- {
- if (this._viewPortStack.length > 3)
- {
- const l = this._viewPortStack.length;
-
- return [
- this._viewPortStack[l - 4],
- this._viewPortStack[l - 3],
- this._viewPortStack[l - 2],
- this._viewPortStack[l - 1]
- ];
- }
- else
- {
- // workaround pre viewport stack times / or+and initial value...
-
- return this._viewPort;
- }
- }
-
-
-
- get mvMatrix() // deprecate
- {
- return this.mMatrix;
- }
-
- set mvMatrix(m) // deprecate
- {
- this.mMatrix = m;
- }
-
- _setCanvas(canv)
- {
- if (!canv) this._log.stack("_setCanvas undef");
-
- if (!this.patch.config.canvas) this.patch.config.canvas = {};
- if (!this.patch.config.canvas.hasOwnProperty("preserveDrawingBuffer")) this.patch.config.canvas.preserveDrawingBuffer = false;
- if (!this.patch.config.canvas.hasOwnProperty("premultipliedAlpha")) this.patch.config.canvas.premultipliedAlpha = false;
- if (!this.patch.config.canvas.hasOwnProperty("alpha")) this.patch.config.canvas.alpha = false;
-
- this.patch.config.canvas.stencil = true;
-
- if (this.patch.config.hasOwnProperty("clearCanvasColor")) this.clearCanvasTransparent = this.patch.config.clearCanvasColor;
- if (this.patch.config.hasOwnProperty("clearCanvasDepth")) this.clearCanvasDepth = this.patch.config.clearCanvasDepth;
-
- // safari stuff..........
- if (/^((?!chrome|android).)*safari/i.test(navigator.userAgent) && (navigator.userAgent.match(/iPhone/i)))
- {
- this._isSafariCrap = true;
- this.glUseHalfFloatTex = true;
- }
-
- if (!this.patch.config.canvas.forceWebGl1) this.gl = canv.getContext("webgl2", this.patch.config.canvas);
-
-
- if (!this.gl || this.gl.isContextLost())
- {
- this.aborted = true;
- this._log.error("NO_WEBGL", "sorry, could not initialize WebGL. Please check if your Browser supports WebGL or try to restart your browser.");
- return;
- }
-
- if (this.gl.getParameter(this.gl.VERSION) != "WebGL 1.0")
- {
- this.glVersion = 2;
- }
- else
- {
- this.gl = canv.getContext("webgl", this.patch.config.canvas) || canv.getContext("experimental-webgl", this.patch.config.canvas);
- this.glVersion = 1;
-
- // safari
- // if (/^((?!chrome|android).)*safari/i.test(navigator.userAgent) && (navigator.userAgent.match(/iPhone/i)))
- // {
- // this.glUseHalfFloatTex = true;
- // }
-
- // ios
- if (/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream)
- {
- if (!this.patch.config.canvas.hasOwnProperty("powerPreference")) this.patch.config.canvas.powerPreference = "high-performance";
- }
-
- this.enableExtension("OES_standard_derivatives");
- // this.enableExtension("GL_OES_standard_derivatives");
- const instancingExt = this.enableExtension("ANGLE_instanced_arrays") || this.gl;
- if (instancingExt.vertexAttribDivisorANGLE)
- {
- this.gl.vertexAttribDivisor = instancingExt.vertexAttribDivisorANGLE.bind(instancingExt);
- this.gl.drawElementsInstanced = instancingExt.drawElementsInstancedANGLE.bind(instancingExt);
- }
- }
-
- const dbgRenderInfo = this.enableExtension("WEBGL_debug_renderer_info");
- if (dbgRenderInfo)
- {
- this.glRenderer = this.gl.getParameter(dbgRenderInfo.UNMASKED_RENDERER_WEBGL);
- if (this.glRenderer === "Google SwiftShader") this.glSlowRenderer = true;
- }
-
- this.canvas.addEventListener("webglcontextlost", (event) =>
- {
- if (this.aborted) return this._log.warn("[cgl_state] aborted context lost... can be ignored...");
- this._log.error("canvas lost...", event);
- this.emitEvent("webglcontextlost");
- this.aborted = true;
- });
-
-
- this.maxAnisotropic = 0;
- if (this.enableExtension("EXT_texture_filter_anisotropic"))
- this.maxAnisotropic = this.gl.getParameter(this.enableExtension("EXT_texture_filter_anisotropic").MAX_TEXTURE_MAX_ANISOTROPY_EXT);
-
-
- this.maxVaryingVectors = this.gl.getParameter(this.gl.MAX_VARYING_VECTORS);
- this.maxTextureUnits = this.gl.getParameter(this.gl.MAX_TEXTURE_IMAGE_UNITS);
- this.maxTexSize = this.gl.getParameter(this.gl.MAX_TEXTURE_SIZE);
- this.maxUniformsFrag = this.gl.getParameter(this.gl.MAX_FRAGMENT_UNIFORM_VECTORS);
- this.maxUniformsVert = this.gl.getParameter(this.gl.MAX_VERTEX_UNIFORM_VECTORS);
- this.maxSamples = 0;
- if (this.gl.MAX_SAMPLES) this.maxSamples = this.gl.getParameter(this.gl.MAX_SAMPLES);
-
- if (this.glVersion == 1)
- {
- this.enableExtension("OES_standard_derivatives");
- const instancingExt = this.enableExtension("ANGLE_instanced_arrays") || this.gl;
-
- if (instancingExt.vertexAttribDivisorANGLE)
- {
- this.gl.vertexAttribDivisor = instancingExt.vertexAttribDivisorANGLE.bind(instancingExt);
- this.gl.drawElementsInstanced = instancingExt.drawElementsInstancedANGLE.bind(instancingExt);
- }
- }
-
- this.DEPTH_FUNCS = [
- this.gl.NEVER,
- this.gl.ALWAYS,
- this.gl.LESS,
- this.gl.LEQUAL,
- this.gl.GREATER,
- this.gl.GEQUAL,
- this.gl.EQUAL,
- this.gl.NOTEQUAL
- ];
- this.CULL_MODES = [
- null,
- this.gl.BACK,
- this.gl.FRONT,
- this.gl.FRONT_AND_BACK
- ];
- }
-
- getInfo()
- {
- return {
- "glVersion": this.glVersion,
- "glRenderer": this.glRenderer,
- "glUseHalfFloatTex": this.glUseHalfFloatTex,
- "maxVaryingVectors": this.maxVaryingVectors,
- "maxTextureUnits": this.maxTextureUnits,
- "maxTexSize": this.maxTexSize,
- "maxUniformsFrag": this.maxUniformsFrag,
- "maxUniformsVert": this.maxUniformsVert,
- "maxSamples": this.maxSamples
- };
- }
-
-
-
-
-
- /**
- * @function popViewPort
- * @memberof Context
- * @instance
- * @description pop viewPort stack
- */
-
-
- popViewPort()
- {
- this._viewPortStack.pop();
- this._viewPortStack.pop();
- this._viewPortStack.pop();
- this._viewPortStack.pop();
-
- if (this._viewPortStack.length == 0)
- {
- this.setViewPort(0, 0, this.canvasWidth, this.canvasHeight);
- // this.gl.viewport(this._viewPort[0], this._viewPort[1], this._viewPort[2], this._viewPort[3]);
- // this.setViewPort(this._viewPort[0], this._viewPort[1], this._viewPort[2], this._viewPort[3]);
- }
- else
- {
- // this.viewPort = [this._viewPortStack[this._viewPort.length - 4], this._viewPortStack[this._viewPort.length - 3], this._viewPortStack[this._viewPort.length - 2], this._viewPortStack[this._viewPort.length - 1]];
- // this.gl.viewport(this._viewPortStack[this._viewPort.length - 4], this._viewPortStack[this._viewPort.length - 3], this._viewPortStack[this._viewPort.length - 2], this._viewPortStack[this._viewPort.length - 1]);
- this.setViewPort(this._viewPortStack[this._viewPort.length - 4], this._viewPortStack[this._viewPort.length - 3], this._viewPortStack[this._viewPort.length - 2], this._viewPortStack[this._viewPort.length - 1]);
- }
- }
-
- /**
- * @function pushViewPort
- * @memberof Context
- * @instance
- * @description push a new viewport onto stack
- * @param {Number} x
- * @param {Number} y
- * @param {Number} w
- * @param {Number} h
- */
-
- pushViewPort(x, y, w, h)
- {
- this._viewPortStack.push(x, y, w, h);
- this.setViewPort(x, y, w, h);
- }
-
-
- // old
- getViewPort()
- {
- return this._viewPort;
- }
-
- // old
- resetViewPort()
- {
- this.gl.viewport(this._viewPort[0], this._viewPort[1], this._viewPort[2], this._viewPort[3]);
- }
-
- // old
- setViewPort(x, y, w, h)
- {
- this._viewPort[0] = Math.round(x);
- this._viewPort[1] = Math.round(y);
- this._viewPort[2] = Math.round(w);
- this._viewPort[3] = Math.round(h);
- this.gl.viewport(this._viewPort[0], this._viewPort[1], this._viewPort[2], this._viewPort[3]);
- }
-
-
- screenShot(cb, doScreenshotClearAlpha, mimeType, quality)
- {
- if (doScreenshotClearAlpha)
- {
- this.gl.clearColor(1, 1, 1, 1);
- this.gl.colorMask(false, false, false, true);
- this.gl.clear(this.gl.COLOR_BUFFER_BIT);
- this.gl.colorMask(true, true, true, true);
- }
-
- if (this.canvas && this.canvas.toBlob)
- {
- this.canvas.toBlob((blob) =>
- {
- if (cb) cb(blob);
- else this._log.log("no screenshot callback...");
- }, mimeType, quality);
- }
- }
-
- endFrame()
- {
- if (this.patch.isEditorMode()) CABLES.GL_MARKER.drawMarkerLayer(this);
-
- this.setPreviousShader();
-
- if (this._vMatrixStack.length() > 0) this.logStackError("view matrix stack length !=0 at end of rendering...");
- if (this._mMatrixStack.length() > 0) this.logStackError("mvmatrix stack length !=0 at end of rendering...");
- if (this._pMatrixStack.length() > 0) this.logStackError("pmatrix stack length !=0 at end of rendering...");
- if (this._glFrameBufferStack.length > 0) this.logStackError("glFrameBuffer stack length !=0 at end of rendering...");
- if (this._stackDepthTest.length > 0) this.logStackError("depthtest stack length !=0 at end of rendering...");
- if (this._stackDepthWrite.length > 0) this.logStackError("depthwrite stack length !=0 at end of rendering...");
- if (this._stackDepthFunc.length > 0) this.logStackError("depthfunc stack length !=0 at end of rendering...");
- if (this._stackBlend.length > 0) this.logStackError("blend stack length !=0 at end of rendering...");
- if (this._stackBlendMode.length > 0) this.logStackError("blendMode stack length !=0 at end of rendering...");
- if (this._shaderStack.length > 0) this.logStackError("this._shaderStack length !=0 at end of rendering...");
- if (this._stackCullFace.length > 0) this.logStackError("this._stackCullFace length !=0 at end of rendering...");
- if (this._stackCullFaceFacing.length > 0) this.logStackError("this._stackCullFaceFacing length !=0 at end of rendering...");
- if (this._viewPortStack.length > 0) this.logStackError("viewport stack length !=0 at end of rendering...");
-
- this._frameStarted = false;
-
- if (this._oldCanvasWidth != this.canvasWidth || this._oldCanvasHeight != this.canvasHeight)
- {
- this._oldCanvasWidth = this.canvasWidth;
- this._oldCanvasHeight = this.canvasHeight;
- this.emitEvent("resize");
- }
-
- if (this._cursor != this._currentCursor)
- {
- this._currentCursor = this.canvas.style.cursor = this._cursor;
- }
-
- this.emitEvent("endframe");
-
- this.fpsCounter.endFrame();
- }
-
- logStackError(str)
- {
- if (!this._hadStackError)
- {
- this._hadStackError = true;
- this._log.warn("[" + this.canvas.id + "]: ", str);
- }
- }
-
- // shader stack
- getShader()
- {
- if (this._currentShader) if (!this.tempData || ((this.tempData.renderOffscreen === true) == this._currentShader.offScreenPass) === true) return this._currentShader;
-
- for (let i = this._shaderStack.length - 1; i >= 0; i--) if (this._shaderStack[i]) if (this.tempData.renderOffscreen == this._shaderStack[i].offScreenPass) return this._shaderStack[i];
- }
-
- getDefaultShader()
- {
- return this._simpleShader;
- }
-
- /**
- * push a shader to the shader stack
- * @function pushShader
- * @memberof Context
- * @instance
- * @param {Object} shader
- * @function
- */
-
- pushShader(shader)
- {
- if (this.tempData.forceShaderMods)
- {
- for (let i = 0; i < this.tempData.forceShaderMods.length; i++)
- {
- // if (!currentShader.forcedMod && currentShader != this.tempData.forceShaderMods[i])
- // {
- // currentShader.forcedMod = this.tempData.forceShaderMods[i];
- shader = this.tempData.forceShaderMods[i].bind(shader, false);
- // }
- // return currentShader;
- // if (this.tempData.forceShaderMods[i].currentShader() && shader != this.tempData.forceShaderMods[i].currentShader().shader)
- }
- }
-
- this._shaderStack.push(shader);
- this._currentShader = shader;
- }
-
-
- /**
- * pop current used shader from shader stack
- * @function popShader
- * @memberof Context
- * @instance
- * @function
- */
- setPreviousShader()
- {
- if (this.tempData.forceShaderMods)
- {
- for (let i = 0; i < this.tempData.forceShaderMods.length; i++)
- {
- // const a =
- this.tempData.forceShaderMods[i].unbind(false);
- // if (a) return;
- // this.popShader();
- }
- }
-
- if (this._shaderStack.length === 0) throw new Error("Invalid shader stack pop!");
- this._shaderStack.pop();
- this._currentShader = this._shaderStack[this._shaderStack.length - 1];
- }
-
- /**
- * push a framebuffer to the framebuffer stack
- * @function pushGlFrameBuffer
- * @memberof Context
- * @instance
- * @param {Object} fb framebuffer
- * @function
- */
- pushGlFrameBuffer(fb)
- {
- this._glFrameBufferStack.push(fb);
- }
-
- /**
- * pop framebuffer stack
- * @function popGlFrameBuffer
- * @memberof Context
- * @instance
- * @returns {Object} current framebuffer or null
- */
- popGlFrameBuffer()
- {
- if (this._glFrameBufferStack.length == 0) return null;
- this._glFrameBufferStack.pop();
- return this._glFrameBufferStack[this._glFrameBufferStack.length - 1];
- }
-
- /**
- * get current framebuffer
- * @function getCurrentFrameBuffer
- * @memberof Context
- * @instance
- * @returns {Object} current framebuffer or null
- */
- getCurrentGlFrameBuffer()
- {
- if (this._glFrameBufferStack.length === 0) return null;
- return this._glFrameBufferStack[this._glFrameBufferStack.length - 1];
- }
-
- /**
- * push a framebuffer to the framebuffer stack
- * @function pushGlFrameBuffer
- * @memberof Context
- * @instance
- * @param {Framebuffer} fb framebuffer
- */
- pushFrameBuffer(fb)
- {
- this._frameBufferStack.push(fb);
- }
-
- /**
- * pop framebuffer stack
- * @function popFrameBuffer
- * @memberof Context
- * @instance
- * @returns {Framebuffer} current framebuffer or null
- */
- popFrameBuffer()
- {
- if (this._frameBufferStack.length == 0) return null;
- this._frameBufferStack.pop();
- return this._frameBufferStack[this._frameBufferStack.length - 1];
- }
-
- /**
- * get current framebuffer
- * @function getCurrentFrameBuffer
- * @memberof Context
- * @instance
- * @returns {Framebuffer} current framebuffer or null
- */
- getCurrentFrameBuffer()
- {
- if (this._frameBufferStack.length === 0) return null;
- return this._frameBufferStack[this._frameBufferStack.length - 1];
- }
-
-
- renderStart(cgl, identTranslate, identTranslateView)
- {
- this.fpsCounter.startFrame();
- this.pushDepthTest(true);
- this.pushDepthWrite(true);
- this.pushDepthFunc(cgl.gl.LEQUAL);
- this.pushCullFaceFacing(cgl.gl.BACK);
- this.pushCullFace(false);
-
- // if (this.clearCanvasTransparent)
- // {
- // cgl.gl.clearColor(0, 0, 0, 0);
- // cgl.gl.clear(cgl.gl.COLOR_BUFFER_BIT);
- // }
- // if (this.clearCanvasDepth) cgl.gl.clear(cgl.gl.DEPTH_BUFFER_BIT);
-
- cgl.setViewPort(0, 0, cgl.canvasWidth, cgl.canvasHeight);
-
- this._startMatrixStacks(identTranslate, identTranslateView);
-
- cgl.pushBlendMode(CONSTANTS.BLEND_MODES.BLEND_NORMAL, false);
-
- for (let i = 0; i < this._textureslots.length; i++) this._textureslots[i] = null;
-
- this.pushShader(this._simpleShader);
-
- this._frameStarted = true;
-
- if (this._onetimeCallbacks.length > 0)
- {
- for (let i = 0; i < this._onetimeCallbacks.length; i++) this._onetimeCallbacks[i]();
- this._onetimeCallbacks.length = 0;
- }
-
- for (let i = 0; i < this._textureslots.length; i++)
- {
- this.gl.activeTexture(this.gl.TEXTURE0 + i);
- this.gl.bindTexture(this.gl.TEXTURE_2D, null);
- this._textureslots[i] = null;
- }
-
- this.emitEvent("beginFrame");
- }
-
- renderEnd(cgl)
- {
- this._endMatrixStacks();
-
- this.popDepthTest();
- this.popDepthWrite();
- this.popDepthFunc();
- this.popCullFaceFacing();
- this.popCullFace();
- this.popBlend();
- this.popBlendMode();
-
- cgl.endFrame();
-
- this.emitEvent("endFrame");
- }
-
- getTexture(slot)
- {
- return this._textureslots[slot];
- }
-
- hasFrameStarted()
- {
- return this._frameStarted;
- }
-
- /**
- * log warning to console if the rendering of one frame has not been started / handy to check for async problems
- * @function checkFrameStarted
- * @memberof Context
- * @param string
- * @instance
- */
- checkFrameStarted(string)
- {
- if (!this._frameStarted)
- {
- this._log.warn("frame not started " + string);
- this.patch.printTriggerStack();
- }
- }
-
-
- setTexture(slot, t, type)
- {
- this.checkFrameStarted("cgl setTexture");
-
- if (t === null) t = CGL.Texture.getEmptyTexture(this).tex;
-
- if (this._textureslots[slot] != t)
- {
- this.gl.activeTexture(this.gl.TEXTURE0 + slot);
- this.gl.bindTexture(type || this.gl.TEXTURE_2D, t);
- this._textureslots[slot] = t;
- }
-
-
- return true;
- }
-
- fullScreen()
- {
- if (this.canvas.requestFullscreen) this.canvas.requestFullscreen();
- else if (this.canvas.mozRequestFullScreen) this.canvas.mozRequestFullScreen();
- else if (this.canvas.webkitRequestFullscreen) this.canvas.webkitRequestFullscreen();
- else if (this.canvas.msRequestFullscreen) this.canvas.msRequestFullscreen();
- }
-
-
- printError(str)
- {
- if (!this.checkGlErrors) return;
- let found = false;
- let error = this.gl.getError();
-
- if (error != this.gl.NO_ERROR)
- {
- let errStr = "";
- if (error == this.gl.OUT_OF_MEMORY) errStr = "OUT_OF_MEMORY";
- if (error == this.gl.INVALID_ENUM) errStr = "INVALID_ENUM";
- if (error == this.gl.INVALID_OPERATION) errStr = "INVALID_OPERATION";
- if (error == this.gl.INVALID_FRAMEBUFFER_OPERATION) errStr = "INVALID_FRAMEBUFFER_OPERATION";
- if (error == this.gl.INVALID_VALUE) errStr = "INVALID_VALUE";
- if (error == this.gl.CONTEXT_LOST_WEBGL)
- {
- this.aborted = true;
- errStr = "CONTEXT_LOST_WEBGL";
- }
- if (error == this.gl.NO_ERROR) errStr = "NO_ERROR";
-
- found = true;
-
-
- this._log.warn("gl error [" + this.canvas.id + "]: ", str, error, errStr);
-
- if (this.canvas.id.contains("glGuiCanvas"))
- if (!this._loggedGlError)
- {
- this.patch.printTriggerStack();
- this._log.stack("glerror");
- this._loggedGlError = true;
- }
- }
- error = this.gl.getError();
-
- return found;
- }
-
- saveScreenshot(filename, cb, pw, ph, noclearalpha)
- {
- this.patch.renderOneFrame();
-
- let w = this.canvas.clientWidth * this.pixelDensity;
- let h = this.canvas.clientHeight * this.pixelDensity;
-
- if (pw)
- {
- this.canvas.width = pw;
- w = pw;
- }
- if (ph)
- {
- this.canvas.height = ph;
- h = ph;
- }
-
- function padLeft(nr, n, str)
- {
- return Array(n - String(nr).length + 1).join(str || "0") + nr;
- }
-
- const d = new Date();
-
- const dateStr = "".concat(String(d.getFullYear()) + String(d.getMonth() + 1) + String(d.getDate()), "_").concat(padLeft(d.getHours(), 2)).concat(padLeft(d.getMinutes(), 2)).concat(padLeft(d.getSeconds(), 2));
-
- if (!filename) filename = "cables_" + dateStr + ".png";
- else filename += ".png";
-
- this.patch.cgl.screenShot(function (blob)
- {
- this.canvas.width = w;
- this.canvas.height = h;
-
- if (blob)
- {
- const anchor = document.createElement("a");
-
- anchor.download = filename;
- anchor.href = URL.createObjectURL(blob);
-
- setTimeout(function ()
- {
- anchor.click();
- if (cb) cb(blob);
- }, 100);
- }
- else
- {
- this._log.log("screenshot: no blob");
- }
- }.bind(this), noclearalpha);
- }
-
- _dispose()
- {
- this._simpleShader.dispose();
- this.gl = null;
- }
- }
-
-
- Context.prototype.popShader = Context.prototype.setPreviousShader;
- Context.prototype.setShader = Context.prototype.pushShader;
-
- /**
- * execute the callback next frame, once
- * @function addNextFrameOnceCallback
- * @memberof Context
- * @instance
- * @param {function} cb
- */
- Context.prototype.addNextFrameOnceCallback = function (cb)
- {
- if (cb && this._onetimeCallbacks.indexOf(cb) == -1) this._onetimeCallbacks.push(cb);
- };
-
- // state depthtest
-
- /**
- * push depth testing enabled state
- * @function pushDepthTest
- * @param {Boolean} enabled
- * @memberof Context
- * @instance
- */
- Context.prototype._stackDepthTest = [];
- Context.prototype.pushDepthTest = function (b)
- {
- this._stackDepthTest.push(b);
- if (!b) this.gl.disable(this.gl.DEPTH_TEST);
- else this.gl.enable(this.gl.DEPTH_TEST);
- };
- /**
- * current state of depth testing
- * @function stateCullFace
- * @returns {Boolean} enabled
- * @memberof Context
- * @instance
- */
- Context.prototype.stateDepthTest = function ()
- {
- return this._stackDepthTest[this._stackDepthTest.length - 1];
- };
-
- /**
- * pop depth testing state
- * @function popCullFace
- * @memberof Context
- * @instance
- */
- Context.prototype.popDepthTest = function ()
- {
- this._stackDepthTest.pop();
-
- if (!this._stackDepthTest[this._stackDepthTest.length - 1]) this.gl.disable(this.gl.DEPTH_TEST);
- else this.gl.enable(this.gl.DEPTH_TEST);
- };
-
- // --------------------------------------
- // state depthwrite
-
- /**
- * push depth write enabled state
- * @function pushDepthTest
- * @param {Boolean} enabled
- * @memberof Context
- * @instance
- */
- Context.prototype._stackDepthWrite = [];
- Context.prototype.pushDepthWrite = function (b)
- {
- b = b || false;
- this._stackDepthWrite.push(b);
- this.gl.depthMask(b);
- };
-
- /**
- * current state of depth writing
- * @function stateDepthWrite
- * @returns {Boolean} enabled
- * @memberof Context
- * @instance
- */
- Context.prototype.stateDepthWrite = function ()
- {
- return this._stackDepthWrite[this._stackDepthWrite.length - 1];
- };
-
- /**
- * pop depth writing state
- * @function popDepthWrite
- * @memberof Context
- * @instance
- */
- Context.prototype.popDepthWrite = function ()
- {
- this._stackDepthWrite.pop();
- this.gl.depthMask(this._stackDepthWrite[this._stackDepthWrite.length - 1] || false);
- };
-
-
- // --------------------------------------
- // state CullFace
-
- Context.prototype._stackCullFace = [];
-
- /**
- * push face culling face enabled state
- * @function pushCullFace
- * @param {Boolean} b enabled
- * @memberof Context
- * @instance
- */
- Context.prototype.pushCullFace = function (b)
- {
- this._stackCullFace.push(b);
-
- if (b) this.gl.enable(this.gl.CULL_FACE);
- else this.gl.disable(this.gl.CULL_FACE);
- };
-
- /**
- * current state of face culling
- * @function stateCullFace
- * @returns {Boolean} enabled
- * @memberof Context
- * @instance
- */
- Context.prototype.stateCullFace = function ()
- {
- return this._stackCullFace[this._stackCullFace.length - 1];
- };
-
- /**
- * pop face culling enabled state
- * @function popCullFace
- * @memberof Context
- * @instance
- */
- Context.prototype.popCullFace = function ()
- {
- this._stackCullFace.pop();
-
- if (this._stackCullFace[this._stackCullFace.length - 1]) this.gl.enable(this.gl.CULL_FACE);
- else this.gl.disable(this.gl.CULL_FACE);
- };
-
-
- // --------------------------------------
- // state CullFace Facing
-
-
- /**
- * push face culling face side
- * @function pushCullFaceFacing
- * @param {Number} cgl.gl.FRONT_AND_BACK, cgl.gl.BACK or cgl.gl.FRONT
- * @memberof Context
- * @instance
- */
- Context.prototype._stackCullFaceFacing = [];
- Context.prototype.pushCullFaceFacing = function (b)
- {
- this._stackCullFaceFacing.push(b);
- this.gl.cullFace(this._stackCullFaceFacing[this._stackCullFaceFacing.length - 1]);
- };
-
- /**
- * current state of face culling side
- * @function stateCullFaceFacing
- * @returns {Boolean} enabled
- * @memberof Context
- * @instance
- */
- Context.prototype.stateCullFaceFacing = function ()
- {
- return this._stackCullFaceFacing[this._stackCullFaceFacing.length - 1];
- };
-
- /**
- * pop face culling face side
- * @function popCullFaceFacing
- * @memberof Context
- * @instance
- */
- Context.prototype.popCullFaceFacing = function ()
- {
- this._stackCullFaceFacing.pop();
- if (this._stackCullFaceFacing.length > 0) this.gl.cullFace(this._stackCullFaceFacing[this._stackCullFaceFacing.length - 1]);
- };
-
-
- // --------------------------------------
- // state depthfunc
-
- Context.prototype._stackDepthFunc = [];
-
- /**
- * enable / disable depth testing
- * like `gl.depthFunc(boolean);`
- * @function pushDepthFunc
- * @memberof Context
- * @instance
- * @param {Boolean} f depthtesting
- */
- Context.prototype.pushDepthFunc = function (f)
- {
- this._stackDepthFunc.push(f);
- this.gl.depthFunc(f);
- };
-
- /**
- * current state of blend
- * @function stateDepthFunc
- * @memberof Context
- * @instance
- * @returns {Boolean} depth testing enabled/disabled
- */
- Context.prototype.stateDepthFunc = function ()
- {
- if (this._stackDepthFunc.length > 0) return this._stackDepthFunc[this._stackDepthFunc.length - 1];
- return false;
- };
-
- /**
- * pop depth testing and set the previous state
- * @function popDepthFunc
- * @memberof Context
- * @instance
- */
- Context.prototype.popDepthFunc = function ()
- {
- this._stackDepthFunc.pop();
- if (this._stackDepthFunc.length > 0) this.gl.depthFunc(this._stackDepthFunc[this._stackDepthFunc.length - 1]);
- };
-
- // --------------------------------------
- // state blending
-
- Context.prototype._stackBlend = [];
-
- /**
- * enable / disable blend
- * like gl.enable(gl.BLEND); / gl.disable(gl.BLEND);
- * @function pushBlend
- * @memberof Context
- * @instance
- * @param {boolean} b blending
- */
- Context.prototype.pushBlend = function (b)
- {
- this._stackBlend.push(b);
- if (!b) this.gl.disable(this.gl.BLEND);
- else this.gl.enable(this.gl.BLEND);
- };
-
- /**
- * pop blend state and set the previous state
- * @function popBlend
- * @memberof Context
- * @instance
- */
- Context.prototype.popBlend = function ()
- {
- this._stackBlend.pop();
-
- if (!this._stackBlend[this._stackBlend.length - 1]) this.gl.disable(this.gl.BLEND);
- else this.gl.enable(this.gl.BLEND);
- };
-
- /**
- * current state of blend
- * @function stateBlend
- * @returns {boolean} blending enabled/disabled
- * @memberof Context
- * @instance
- */
- Context.prototype.stateBlend = function ()
- {
- return this._stackBlend[this._stackBlend.length - 1];
- };
-
- export const BLENDS = {
- "BLEND_NONE": 0,
- "BLEND_NORMAL": 1,
- "BLEND_ADD": 2,
- "BLEND_SUB": 3,
- "BLEND_MUL": 4,
- };
-
- Context.prototype._stackBlendMode = [];
- Context.prototype._stackBlendModePremul = [];
-
- /**
- * push and switch to predefined blendmode (CONSTANTS.BLEND_MODES.BLEND_NONE,CONSTANTS.BLEND_MODES.BLEND_NORMAL,CONSTANTS.BLEND_MODES.BLEND_ADD,CONSTANTS.BLEND_MODES.BLEND_SUB,CONSTANTS.BLEND_MODES.BLEND_MUL)
- * @function pushBlendMode
- * @memberof Context
- * @instance
- * @param {Number} blendMode
- * @param {Boolean} premul premultiplied mode
- */
- Context.prototype.pushBlendMode = function (blendMode, premul)
- {
- this._stackBlendMode.push(blendMode);
- this._stackBlendModePremul.push(premul);
-
- const n = this._stackBlendMode.length - 1;
-
- this.pushBlend(this._stackBlendMode[n] !== CONSTANTS.BLEND_MODES.BLEND_NONE);
- this._setBlendMode(this._stackBlendMode[n], this._stackBlendModePremul[n]);
- };
-
- /**
- * pop predefined blendmode / switch back to previous blendmode
- * @function popBlendMode
- * @memberof Context
- * @instance
- */
- Context.prototype.popBlendMode = function ()
- {
- this._stackBlendMode.pop();
- this._stackBlendModePremul.pop();
-
- const n = this._stackBlendMode.length - 1;
-
- this.popBlend(this._stackBlendMode[n] !== CONSTANTS.BLEND_MODES.BLEND_NONE);
-
- if (n >= 0) this._setBlendMode(this._stackBlendMode[n], this._stackBlendModePremul[n]);
- };
-
-
- // --------------------------------------
- // state stencil
-
- Context.prototype._stackStencil = [];
-
- /**
- * enable / disable stencil testing
-
- * @function pushStencil
- * @memberof Context
- * @instance
- * @param {Boolean} b enable
- */
- Context.prototype.pushStencil = function (b)
- {
- this._stackStencil.push(b);
- if (!b) this.gl.disable(this.gl.STENCIL_TEST);
- else this.gl.enable(this.gl.STENCIL_TEST);
- };
-
- /**
- * pop stencil test state and set the previous state
- * @function popStencil
- * @memberof Context
- * @instance
- */
- Context.prototype.popStencil = function ()
- {
- this._stackStencil.pop();
-
- if (!this._stackStencil[this._stackStencil.length - 1]) this.gl.disable(this.gl.STENCIL_TEST);
- else this.gl.enable(this.gl.STENCIL_TEST);
- };
-
- // --------------------------------------
-
-
- Context.prototype.glGetAttribLocation = function (prog, name)
- {
- const l = this.gl.getAttribLocation(prog, name);
- // if (l == -1)
- // {
- // this._log.warn("get attr loc -1 ", name);
- // }
- return l;
- };
-
-
- /**
- * should an op now draw helpermeshes
- * @function shouldDrawHelpers
- * @memberof Context
- * @param op
- * @instance
- */
- Context.prototype.shouldDrawHelpers = function (op)
- {
- if (this.tempData.shadowPass) return false;
- if (!op.patch.isEditorMode()) return false;
-
- // const fb = this.getCurrentFrameBuffer();
- // if (fb && fb.getWidth)
- // {
- // const fbshould = this.canvasWidth / this.canvasHeight == fb.getWidth() / fb.getHeight();
- // if (!fbshould) return false;
- // }
-
- return gui.shouldDrawOverlay;// || (CABLES.UI.renderHelperCurrent && op.isCurrentUiOp());
- };
-
- Context.prototype._setBlendMode = function (blendMode, premul)
- {
- const gl = this.gl;
-
- if (blendMode == CONSTANTS.BLEND_MODES.BLEND_NONE)
- {
- // this.gl.disable(this.gl.BLEND);
- }
- else if (blendMode == CONSTANTS.BLEND_MODES.BLEND_ADD)
- {
- if (premul)
- {
- gl.blendEquationSeparate(gl.FUNC_ADD, gl.FUNC_ADD);
- gl.blendFuncSeparate(gl.ONE, gl.ONE, gl.ONE, gl.ONE);
- }
- else
- {
- gl.blendEquation(gl.FUNC_ADD);
- gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
- }
- }
- else if (blendMode == CONSTANTS.BLEND_MODES.BLEND_SUB)
- {
- if (premul)
- {
- gl.blendEquationSeparate(gl.FUNC_ADD, gl.FUNC_ADD);
- gl.blendFuncSeparate(gl.ZERO, gl.ZERO, gl.ONE_MINUS_SRC_COLOR, gl.ONE_MINUS_SRC_ALPHA);
- }
- else
- {
- gl.blendEquation(gl.FUNC_ADD);
- gl.blendFunc(gl.ZERO, gl.ONE_MINUS_SRC_COLOR);
- }
- }
- else if (blendMode == CONSTANTS.BLEND_MODES.BLEND_MUL)
- {
- if (premul)
- {
- gl.blendEquationSeparate(gl.FUNC_ADD, gl.FUNC_ADD);
- gl.blendFuncSeparate(gl.ZERO, gl.SRC_COLOR, gl.ZERO, gl.SRC_ALPHA);
- }
- else
- {
- gl.blendEquation(gl.FUNC_ADD);
- gl.blendFunc(gl.ZERO, gl.SRC_COLOR);
- }
- }
- else if (blendMode == CONSTANTS.BLEND_MODES.BLEND_NORMAL)
- {
- if (premul)
- {
- gl.blendEquationSeparate(gl.FUNC_ADD, gl.FUNC_ADD);
- gl.blendFuncSeparate(gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
- }
- else
- {
- gl.blendEquationSeparate(gl.FUNC_ADD, gl.FUNC_ADD);
- gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
- }
- }
- else
- {
- this._log.log("setblendmode: unknown blendmode");
- }
- };
-
- Context.prototype.createMesh = function (geom, options)
- {
- if (CABLES.UTILS.isNumeric(options))options = { "glPrimitive": options }; // old constructor fallback...
- return new CGL.Mesh(this, geom, options);
- };
-
-
- /**
- * set cursor
- * @function setCursor
- * @memberof Context
- * @instance
- * @param {String} str css cursor string
- */
- Context.prototype.setCursor = function (str)
- {
- this._cursor = str;
- };
-
- /**
- * enable a webgl extension
- * @function enableExtension
- * @memberof Context
- * @instance
- * @param {String} name extension name
- * @returns {Object} extension object or null
- */
- Context.prototype.enableExtension = function (name)
- {
- if (!this.gl) return null;
-
- if (this._enabledExtensions.hasOwnProperty(name))
- return this._enabledExtensions[name];
-
- const o = this.gl.getExtension(name);
- this._enabledExtensions[name] = o;
-
- if (!o)
- this._log.warn("[cgl_state] extension not available " + name);
- // else
- // this._log.log("enabled extension", name);
-
- return o;
- };
-
- Context.prototype.checkTextureSize = function (x)
- {
- x = x || 1;
- x = Math.floor(x);
- x = Math.min(x, this.maxTexSize);
- x = Math.max(x, 1);
- return x;
- };
-
-
- export { Context };
-