@itwin/core-frontend
Version:
iTwin.js frontend components
351 lines • 13.1 kB
JavaScript
"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
* @module WebGL
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.RenderState = exports.RenderStateStencil = exports.RenderStateStencilFunction = exports.RenderStateStencilOperation = exports.RenderStateBlend = exports.RenderStateFlags = void 0;
const GL_1 = require("./GL");
const System_1 = require("./System");
/** @internal */
class RenderStateFlags {
cull = false;
depthTest = false;
blend = false;
stencilTest = false;
depthMask = true;
colorWrite = true;
constructor(src) {
if (src) {
this.copyFrom(src);
}
}
copyFrom(src) {
this.cull = src.cull;
this.depthTest = src.depthTest;
this.blend = src.blend;
this.stencilTest = src.stencilTest;
this.depthMask = src.depthMask;
this.colorWrite = src.colorWrite;
}
clone(result) {
if (!result) {
return new RenderStateFlags(this);
}
else {
result.copyFrom(this);
return result;
}
}
equals(rhs) {
return this.cull === rhs.cull
&& this.depthTest === rhs.depthTest
&& this.blend === rhs.blend
&& this.stencilTest === rhs.stencilTest
&& this.depthMask === rhs.depthMask
&& this.colorWrite === rhs.colorWrite;
}
apply(previousFlags) {
RenderStateFlags.enableOrDisable(this.cull, GL_1.GL.Capability.CullFace, previousFlags.cull);
RenderStateFlags.enableOrDisable(this.depthTest, GL_1.GL.Capability.DepthTest, previousFlags.depthTest);
RenderStateFlags.enableOrDisable(this.blend, GL_1.GL.Capability.Blend, previousFlags.blend);
RenderStateFlags.enableOrDisable(this.stencilTest, GL_1.GL.Capability.StencilTest, previousFlags.stencilTest);
if (previousFlags.depthMask !== this.depthMask) {
System_1.System.instance.context.depthMask(this.depthMask);
}
if (previousFlags.colorWrite !== this.colorWrite) {
System_1.System.instance.context.colorMask(this.colorWrite, this.colorWrite, this.colorWrite, this.colorWrite);
}
}
static enableOrDisable(currentFlag, value, previousFlag) {
if (currentFlag !== previousFlag) {
const gl = System_1.System.instance.context;
if (currentFlag) {
gl.enable(value);
}
else {
gl.disable(value);
}
}
}
}
exports.RenderStateFlags = RenderStateFlags;
/** @internal */
class RenderStateBlend {
color = [0.0, 0.0, 0.0, 0.0];
equationRgb = GL_1.GL.BlendEquation.Default;
equationAlpha = GL_1.GL.BlendEquation.Default;
functionSourceRgb = GL_1.GL.BlendFactor.DefaultSrc;
functionSourceAlpha = GL_1.GL.BlendFactor.DefaultSrc;
functionDestRgb = GL_1.GL.BlendFactor.DefaultDst;
functionDestAlpha = GL_1.GL.BlendFactor.DefaultDst;
constructor(src) {
if (src) {
this.copyFrom(src);
}
}
apply(previousBlend) {
const gl = System_1.System.instance.context;
if (previousBlend === undefined || !this.equalColors(previousBlend)) {
gl.blendColor(this.color[0], this.color[1], this.color[2], this.color[3]);
}
if (previousBlend === undefined || previousBlend.equationRgb !== this.equationRgb || previousBlend.equationAlpha !== this.equationAlpha) {
gl.blendEquationSeparate(this.equationRgb, this.equationAlpha);
}
if (previousBlend === undefined || previousBlend.functionSourceRgb !== this.functionSourceRgb || previousBlend.functionSourceAlpha !== this.functionSourceAlpha
|| previousBlend.functionDestRgb !== this.functionDestRgb || previousBlend.functionDestAlpha !== this.functionDestAlpha) {
gl.blendFuncSeparate(this.functionSourceRgb, this.functionDestRgb, this.functionSourceAlpha, this.functionDestAlpha);
}
}
copyFrom(src) {
this.setColor(src.color);
this.equationRgb = src.equationRgb;
this.equationAlpha = src.equationAlpha;
this.functionSourceRgb = src.functionSourceRgb;
this.functionSourceAlpha = src.functionSourceAlpha;
this.functionDestRgb = src.functionDestRgb;
this.functionDestAlpha = src.functionDestAlpha;
}
clone(result) {
if (!result) {
return new RenderStateBlend(this);
}
else {
result.copyFrom(this);
return result;
}
}
equals(rhs) {
return this.equalColors(rhs)
&& this.equationRgb === rhs.equationRgb
&& this.equationAlpha === rhs.equationAlpha
&& this.functionSourceRgb === rhs.functionSourceRgb
&& this.functionSourceAlpha === rhs.functionSourceAlpha
&& this.functionDestRgb === rhs.functionDestRgb
&& this.functionDestAlpha === rhs.functionDestAlpha;
}
equalColors(rhs) {
return this.color[0] === rhs.color[0] &&
this.color[1] === rhs.color[1] &&
this.color[2] === rhs.color[2] &&
this.color[3] === rhs.color[3];
}
setColor(color) {
this.color[0] = color[0];
this.color[1] = color[1];
this.color[2] = color[2];
this.color[3] = color[3];
}
setBlendFunc(src, dst) {
this.setBlendFuncSeparate(src, src, dst, dst);
}
setBlendFuncSeparate(srcRgb, srcAlpha, dstRgb, dstAlpha) {
this.functionSourceRgb = srcRgb;
this.functionSourceAlpha = srcAlpha;
this.functionDestRgb = dstRgb;
this.functionDestAlpha = dstAlpha;
}
}
exports.RenderStateBlend = RenderStateBlend;
/** @internal */
class RenderStateStencilOperation {
fail = GL_1.GL.StencilOperation.Default;
zFail = GL_1.GL.StencilOperation.Default;
zPass = GL_1.GL.StencilOperation.Default;
constructor(src) {
if (src) {
this.copyFrom(src);
}
}
copyFrom(src) {
this.fail = src.fail;
this.zFail = src.zFail;
this.zPass = src.zPass;
}
clone(result) {
if (!result) {
return new RenderStateStencilOperation(this);
}
else {
result.copyFrom(this);
return result;
}
}
equals(rhs) {
return this.fail === rhs.fail
&& this.zFail === rhs.zFail
&& this.zPass === rhs.zPass;
}
}
exports.RenderStateStencilOperation = RenderStateStencilOperation;
/** @internal */
class RenderStateStencilFunction {
function = GL_1.GL.StencilFunction.Default;
ref = 0;
mask = 0xFFFFFFFF;
constructor(src) {
if (src) {
this.copyFrom(src);
}
}
copyFrom(src) {
this.function = src.function;
this.ref = src.ref;
this.mask = src.mask;
}
clone(result) {
if (!result) {
return new RenderStateStencilFunction(this);
}
else {
result.copyFrom(this);
return result;
}
}
equals(rhs) {
return this.function === rhs.function
&& this.ref === rhs.ref
&& this.mask === rhs.mask;
}
}
exports.RenderStateStencilFunction = RenderStateStencilFunction;
/** @internal */
class RenderStateStencil {
frontFunction = new RenderStateStencilFunction();
backFunction = new RenderStateStencilFunction();
frontOperation = new RenderStateStencilOperation();
backOperation = new RenderStateStencilOperation();
constructor(src) {
if (src) {
this.copyFrom(src);
}
}
apply(previousStencil) {
const gl = System_1.System.instance.context;
if (previousStencil === undefined || !previousStencil.frontFunction.equals(this.frontFunction)) {
gl.stencilFuncSeparate(GL_1.GL.CullFace.Front, this.frontFunction.function, this.frontFunction.ref, this.frontFunction.mask);
}
if (previousStencil === undefined || !previousStencil.backFunction.equals(this.backFunction)) {
gl.stencilFuncSeparate(GL_1.GL.CullFace.Back, this.backFunction.function, this.backFunction.ref, this.backFunction.mask);
}
if (previousStencil === undefined || !previousStencil.frontOperation.equals(this.frontOperation)) {
gl.stencilOpSeparate(GL_1.GL.CullFace.Front, this.frontOperation.fail, this.frontOperation.zFail, this.frontOperation.zPass);
}
if (previousStencil === undefined || !previousStencil.backOperation.equals(this.backOperation)) {
gl.stencilOpSeparate(GL_1.GL.CullFace.Back, this.backOperation.fail, this.backOperation.zFail, this.backOperation.zPass);
}
}
copyFrom(src) {
this.frontFunction.copyFrom(src.frontFunction);
this.backFunction.copyFrom(src.backFunction);
this.frontOperation.copyFrom(src.frontOperation);
this.backOperation.copyFrom(src.backOperation);
}
clone(result) {
if (!result) {
return new RenderStateStencil(this);
}
else {
result.copyFrom(this);
return result;
}
}
equals(rhs) {
return this.frontFunction.equals(rhs.frontFunction)
&& this.backFunction.equals(rhs.backFunction)
&& this.frontOperation.equals(rhs.frontOperation)
&& this.backOperation.equals(rhs.backOperation);
}
}
exports.RenderStateStencil = RenderStateStencil;
/** Encapsulates the state of an OpenGL context.
* to modify the context for a rendering operation, do *not* directly call
* functions like glDepthMask(), glBlendFunc(), etc - otherwise such calls may adversely
* affect subsequent rendering operations.
* Instead, set up a RenderState as desired and invoke System.instance.applyRenderState()
* The context tracks the most-recently applied RenderState, allowing it to minimize
* the number of GL state changes actually invoked, improving performance.
* @internal
*/
class RenderState {
flags = new RenderStateFlags();
blend = new RenderStateBlend();
stencil = new RenderStateStencil();
frontFace = GL_1.GL.FrontFace.Default;
cullFace = GL_1.GL.CullFace.Default;
depthFunc = GL_1.GL.DepthFunc.Default;
stencilMask = 0xFFFFFFFF;
constructor(src) {
if (src) {
this.copyFrom(src);
}
}
static defaults = new RenderState();
copyFrom(src) {
this.flags.copyFrom(src.flags);
this.blend.copyFrom(src.blend);
this.stencil.copyFrom(src.stencil);
this.frontFace = src.frontFace;
this.cullFace = src.cullFace;
this.depthFunc = src.depthFunc;
this.stencilMask = src.stencilMask;
}
clone(result) {
if (!result) {
return new RenderState(this);
}
else {
result.copyFrom(this);
return result;
}
}
set clockwiseFrontFace(clockwise) {
this.frontFace = clockwise ? GL_1.GL.FrontFace.Clockwise : GL_1.GL.FrontFace.CounterClockwise;
}
equals(rhs) {
return this.flags.equals(rhs.flags)
&& this.blend.equals(rhs.blend)
&& this.stencil.equals(rhs.stencil)
&& this.frontFace === rhs.frontFace
&& this.cullFace === rhs.cullFace
&& this.depthFunc === rhs.depthFunc
&& this.stencilMask === rhs.stencilMask;
}
apply(prevState) {
this.flags.apply(prevState.flags);
if (this.flags.blend) {
if (prevState.flags.blend)
this.blend.apply(prevState.blend);
else
this.blend.apply();
}
if (this.flags.cull) {
if (!prevState.flags.cull || prevState.cullFace !== this.cullFace) {
System_1.System.instance.context.cullFace(this.cullFace);
}
}
if (this.flags.depthTest) {
if (!prevState.flags.depthTest || prevState.depthFunc !== this.depthFunc) {
System_1.System.instance.context.depthFunc(this.depthFunc);
}
}
if (this.flags.stencilTest) {
if (prevState.flags.stencilTest)
this.stencil.apply(prevState.stencil);
else
this.stencil.apply();
}
if (this.frontFace !== prevState.frontFace) {
System_1.System.instance.context.frontFace(this.frontFace);
}
if (this.stencilMask !== prevState.stencilMask) {
System_1.System.instance.context.stencilMask(this.stencilMask);
}
}
}
exports.RenderState = RenderState;
Object.freeze(RenderState.defaults);
//# sourceMappingURL=RenderState.js.map