@tolokoban/tgd
Version:
ToloGameDev library for WebGL2
164 lines • 14 kB
JavaScript
import { debug, highlightEnum } from "./../../debug/index.js";
import { WebglEnumStencilFunction, WebglEnumStencilOperation } from "./../../types/index.js";
export const webglPresetStencil = {
off: {
enabled: false,
maskBack: 0,
maskFront: 0,
functionBack: WebglEnumStencilFunction.ALWAYS,
functionBackMask: 0,
functionBackRef: 0,
functionFront: WebglEnumStencilFunction.ALWAYS,
functionFrontMask: 0,
functionFrontRef: 0,
operationBack1FailStencil: WebglEnumStencilOperation.KEEP,
operationBack2FailDepth: WebglEnumStencilOperation.KEEP,
operationBack3Pass: WebglEnumStencilOperation.KEEP,
operationFront1FailStencil: WebglEnumStencilOperation.KEEP,
operationFront2FailDepth: WebglEnumStencilOperation.KEEP,
operationFront3Pass: WebglEnumStencilOperation.KEEP,
},
/** Set the stencil to `value` for each fragment. */
write: (value) => ({
enabled: true,
maskBack: 0xff,
maskFront: 0xff,
functionBack: WebglEnumStencilFunction.ALWAYS,
functionBackRef: value,
functionBackMask: 0xff,
functionFront: WebglEnumStencilFunction.ALWAYS,
functionFrontRef: value,
functionFrontMask: 0xff,
operationBack1FailStencil: WebglEnumStencilOperation.KEEP,
operationBack2FailDepth: WebglEnumStencilOperation.KEEP,
operationBack3Pass: WebglEnumStencilOperation.REPLACE,
operationFront1FailStencil: WebglEnumStencilOperation.KEEP,
operationFront2FailDepth: WebglEnumStencilOperation.KEEP,
operationFront3Pass: WebglEnumStencilOperation.REPLACE,
}),
/** Paint only if the stencil is equal to `value` */
paintIfEqual: (value) => ({
enabled: true,
maskBack: 0x00,
maskFront: 0x00,
functionBack: WebglEnumStencilFunction.EQUAL,
functionBackRef: value,
functionBackMask: 0xff,
functionFront: WebglEnumStencilFunction.EQUAL,
functionFrontRef: value,
functionFrontMask: 0xff,
operationBack1FailStencil: WebglEnumStencilOperation.KEEP,
operationBack2FailDepth: WebglEnumStencilOperation.KEEP,
operationBack3Pass: WebglEnumStencilOperation.KEEP,
operationFront1FailStencil: WebglEnumStencilOperation.KEEP,
operationFront2FailDepth: WebglEnumStencilOperation.KEEP,
operationFront3Pass: WebglEnumStencilOperation.KEEP,
}),
};
export function webglStencilSet(gl, stencil) {
if (stencil.enabled) {
gl.enable(gl.STENCIL_TEST);
gl.stencilFuncSeparate(gl.FRONT, stencil.functionFront, stencil.functionFrontRef, stencil.functionFrontMask);
gl.stencilFuncSeparate(gl.BACK, stencil.functionBack, stencil.functionBackRef, stencil.functionBackMask);
gl.stencilOpSeparate(gl.FRONT, stencil.operationFront1FailStencil, stencil.operationFront2FailDepth, stencil.operationFront3Pass);
gl.stencilOpSeparate(gl.BACK, stencil.operationBack1FailStencil, stencil.operationBack2FailDepth, stencil.operationBack3Pass);
gl.stencilMaskSeparate(gl.FRONT, stencil.maskFront);
gl.stencilMaskSeparate(gl.BACK, stencil.maskBack);
}
else {
gl.disable(gl.STENCIL_TEST);
}
}
export function webglStencilGet(gl) {
const enabled = Boolean(gl.getParameter(gl.STENCIL_TEST));
if (!enabled)
return Object.assign({}, webglPresetStencil.off);
return {
enabled,
maskBack: gl.getParameter(gl.STENCIL_BACK_WRITEMASK),
maskFront: gl.getParameter(gl.STENCIL_WRITEMASK),
functionFront: gl.getParameter(gl.STENCIL_FUNC),
functionFrontMask: gl.getParameter(gl.STENCIL_VALUE_MASK),
functionFrontRef: gl.getParameter(gl.STENCIL_REF),
functionBack: gl.getParameter(gl.STENCIL_BACK_FUNC),
functionBackMask: gl.getParameter(gl.STENCIL_BACK_VALUE_MASK),
functionBackRef: gl.getParameter(gl.STENCIL_BACK_REF),
operationFront1FailStencil: gl.getParameter(gl.STENCIL_FAIL),
operationFront2FailDepth: gl.getParameter(gl.STENCIL_PASS_DEPTH_FAIL),
operationFront3Pass: gl.getParameter(gl.STENCIL_PASS_DEPTH_PASS),
operationBack1FailStencil: gl.getParameter(gl.STENCIL_BACK_FAIL),
operationBack2FailDepth: gl.getParameter(gl.STENCIL_BACK_PASS_DEPTH_FAIL),
operationBack3Pass: gl.getParameter(gl.STENCIL_BACK_PASS_DEPTH_PASS),
};
}
export function webglStencilExec(gl, stencil, action) {
const currentState = webglStencilGet(gl);
webglStencilSet(gl, stencil);
try {
action();
}
finally {
webglStencilSet(gl, currentState);
}
}
export function webglDebugStencil(gl, caption = "Stencil test:") {
const stencil = webglStencilGet(gl);
debug([`Stencil ${caption}: `, stencil.enabled]);
console.log(stencil);
if (stencil.enabled) {
debug([
{ cls: "code" },
[`gl.enable(`, highlightEnum("STENCIL_TEST"), ")\n"],
[
"gl.stencilFuncSeparate(",
highlightEnum("FRONT"),
", ",
highlightEnum(stencil.functionFront),
`, ${stencil.functionFrontRef}, 0b${stencil.functionFrontMask.toString(2)})\n`,
],
[
"gl.stencilFuncSeparate(",
highlightEnum("BACK"),
", ",
highlightEnum(stencil.functionBack),
`, ${stencil.functionBackRef}, 0b${stencil.functionBackMask.toString(2)})\n`,
],
[
"gl.stencilOpSeparate(",
highlightEnum("FRONT"),
", ",
highlightEnum(stencil.operationFront1FailStencil),
", ",
highlightEnum(stencil.operationFront2FailDepth),
", ",
highlightEnum(stencil.operationFront3Pass),
")\n",
],
[
"gl.stencilOpSeparate(",
highlightEnum("BACK"),
", ",
highlightEnum(stencil.operationBack1FailStencil),
", ",
highlightEnum(stencil.operationBack2FailDepth),
", ",
highlightEnum(stencil.operationBack3Pass),
")\n",
],
[
"gl.stencilMaskSeparate(",
highlightEnum("FRONT"),
`, 0b${stencil.maskFront.toString(2)})\n`,
],
[
"gl.stencilMaskSeparate(",
highlightEnum("BACK"),
`, 0b${stencil.maskBack.toString(2)})\n`,
],
]);
}
else {
debug([{ cls: "code" }, [`gl.disable(`, highlightEnum("STENCIL_TEST")]]);
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RlbmNpbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy91dGlscy9zdGF0ZS9zdGVuY2lsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxLQUFLLEVBQUUsYUFBYSxFQUFFLE1BQU0sWUFBWSxDQUFBO0FBQ2pELE9BQU8sRUFBRSx3QkFBd0IsRUFBRSx5QkFBeUIsRUFBRSxNQUFNLFlBQVksQ0FBQTtBQW9CaEYsTUFBTSxDQUFDLE1BQU0sa0JBQWtCLEdBQUc7SUFDOUIsR0FBRyxFQUFFO1FBQ0QsT0FBTyxFQUFFLEtBQUs7UUFDZCxRQUFRLEVBQUUsQ0FBQztRQUNYLFNBQVMsRUFBRSxDQUFDO1FBQ1osWUFBWSxFQUFFLHdCQUF3QixDQUFDLE1BQU07UUFDN0MsZ0JBQWdCLEVBQUUsQ0FBQztRQUNuQixlQUFlLEVBQUUsQ0FBQztRQUNsQixhQUFhLEVBQUUsd0JBQXdCLENBQUMsTUFBTTtRQUM5QyxpQkFBaUIsRUFBRSxDQUFDO1FBQ3BCLGdCQUFnQixFQUFFLENBQUM7UUFDbkIseUJBQXlCLEVBQUUseUJBQXlCLENBQUMsSUFBSTtRQUN6RCx1QkFBdUIsRUFBRSx5QkFBeUIsQ0FBQyxJQUFJO1FBQ3ZELGtCQUFrQixFQUFFLHlCQUF5QixDQUFDLElBQUk7UUFDbEQsMEJBQTBCLEVBQUUseUJBQXlCLENBQUMsSUFBSTtRQUMxRCx3QkFBd0IsRUFBRSx5QkFBeUIsQ0FBQyxJQUFJO1FBQ3hELG1CQUFtQixFQUFFLHlCQUF5QixDQUFDLElBQUk7S0FDdEQ7SUFDRCxvREFBb0Q7SUFDcEQsS0FBSyxFQUFFLENBQUMsS0FBYSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZCLE9BQU8sRUFBRSxJQUFJO1FBQ2IsUUFBUSxFQUFFLElBQUk7UUFDZCxTQUFTLEVBQUUsSUFBSTtRQUNmLFlBQVksRUFBRSx3QkFBd0IsQ0FBQyxNQUFNO1FBQzdDLGVBQWUsRUFBRSxLQUFLO1FBQ3RCLGdCQUFnQixFQUFFLElB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