"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.createVolClassBlendProgram = exports.createVolClassSetBlendProgram = exports.createVolClassCopyZProgram = exports.createVolClassColorUsingStencilProgram = void 0;
const core_common_1 = require("@itwin/core-common");
const CachedGeometry_1 = require("../CachedGeometry");
const FloatRGBA_1 = require("../FloatRGBA");
const RenderFlags_1 = require("../RenderFlags");
const Texture_1 = require("../Texture");
const Fragment_1 = require("./Fragment");
const ViewportQuad_1 = require("./ViewportQuad");
const computehiliteColor = "return vec4(u_hilite_color.rgb, 1.0);";
const computeSetBlendColor = "return u_blend_color;";
const computeBlendTextureColor = "return TEXTURE(u_blendTexture, v_texCoord);";
const computeTexCoord = "v_texCoord = (rawPosition.xy + 1.0) * 0.5;";
const checkDiscardBackgroundByZ = `
  if (u_boundaryType == kBoundaryType_Out)
    return TEXTURE(u_depthTexture, v_texCoord).r == 1.0;
  return false;
`;
const depthFromTexture = "return TEXTURE(u_depthTexture, v_texCoord).r;";
const scratchColor = FloatRGBA_1.FloatRgba.fromColorDef(core_common_1.ColorDef.white);
/** @internal */
function addBoundaryTypeConstants(builder) {
    // NB: These are the bit positions of each flag in OvrFlags enum - not the flag values
    builder.addConstant("kBoundaryType_Out", 1 /* VariableType.Int */, "0");
    builder.addConstant("kBoundaryType_In", 1 /* VariableType.Int */, "1");
    builder.addConstant("kBoundaryType_Selected", 1 /* VariableType.Int */, "2");
}
/** @internal */
function setScratchColor(display, hilite, hAlpha) {
    switch (display) {
        case core_common_1.SpatialClassifierOutsideDisplay.Dimmed:
            scratchColor.set(0.0, 0.0, 0.0, 0.3);
            break;
        case core_common_1.SpatialClassifierOutsideDisplay.Off:
            scratchColor.set(0.0, 0.0, 0.0, 0.8);
            break;
        case core_common_1.SpatialClassifierOutsideDisplay.On:
            scratchColor.set(0.0, 0.0, 0.0, 0.0);
            break;
        default: // Hilite or ByElementColor (though ByElementColor should never use this shader)
            scratchColor.set(hilite.red, hilite.green, hilite.blue, hAlpha);
            break;
    }
}
/** @internal */
function createVolClassColorUsingStencilProgram(context) {
    const builder = (0, ViewportQuad_1.createViewportQuadBuilder)(false);
    const frag = builder.frag;
    frag.set(1 /* FragmentShaderComponent.ComputeBaseColor */, computehiliteColor);
    frag.set(16 /* FragmentShaderComponent.AssignFragData */, Fragment_1.assignFragColor);
    frag.addUniform("u_hilite_color", 5 /* VariableType.Vec4 */, (prog) => {
        prog.addGraphicUniform("u_hilite_color", (uniform, params) => {
            const useLighting = params.geometry.getFlashMode(params);
            if (useLighting) {
                const hiliteColor = params.target.uniforms.hilite.hiliteColor;
                scratchColor.set(hiliteColor.red, hiliteColor.green, hiliteColor.blue, 1.0);
            }
            else
                scratchColor.set(1.0, 1.0, 1.0, 0.0);
            scratchColor.bind(uniform);
        });
    });
    builder.vert.headerComment = "//!V! VolClassColorUsingStencil";
    builder.frag.headerComment = "//!F! VolClassColorUsingStencil";
    return builder.buildProgram(context);
}
exports.createVolClassColorUsingStencilProgram = createVolClassColorUsingStencilProgram;
/** @internal */
function createVolClassCopyZProgram(context) {
    const builder = (0, ViewportQuad_1.createViewportQuadBuilder)(true);
    builder.addInlineComputedVarying("v_texCoord", 3 /* VariableType.Vec2 */, computeTexCoord); // TODO: I think this is not necessary because it's already added from the create above
    const frag = builder.frag;
    frag.set(1 /* FragmentShaderComponent.ComputeBaseColor */, computeSetBlendColor);
    frag.set(16 /* FragmentShaderComponent.AssignFragData */, Fragment_1.assignFragColor);
    frag.addUniform("u_blend_color", 5 /* VariableType.Vec4 */, (prog) => {
        prog.addGraphicUniform("u_blend_color", (uniform, _params) => {
            scratchColor.set(0.0, 0.0, 0.0, 0.0);
            scratchColor.bind(uniform);
        });
    });
    frag.addUniform("u_depthTexture", 8 /* VariableType.Sampler2D */, (prog) => {
        prog.addGraphicUniform("u_depthTexture", (uniform, params) => {
            const geom = params.geometry;
            Texture_1.Texture2DHandle.bindSampler(uniform, geom.texture, RenderFlags_1.TextureUnit.Zero);
        });
    });
    frag.set(18 /* FragmentShaderComponent.FinalizeDepth */, depthFromTexture);
    builder.vert.headerComment = "//!V! VolClassCopyZ";
    builder.frag.headerComment = "//!F! VolClassCopyZ";
    return builder.buildProgram(context);
}
exports.createVolClassCopyZProgram = createVolClassCopyZProgram;
/** @internal */
function createVolClassSetBlendProgram(context) {
    const builder = (0, ViewportQuad_1.createViewportQuadBuilder)(true);
    builder.addInlineComputedVarying("v_texCoord", 3 /* VariableType.Vec2 */, computeTexCoord);
    const frag = builder.frag;
    addBoundaryTypeConstants(frag);
    frag.set(0 /* FragmentShaderComponent.CheckForEarlyDiscard */, checkDiscardBackgroundByZ);
    frag.set(1 /* FragmentShaderComponent.ComputeBaseColor */, computeSetBlendColor);
    frag.set(16 /* FragmentShaderComponent.AssignFragData */, Fragment_1.assignFragColor);
    frag.addUniform("u_boundaryType", 1 /* VariableType.Int */, (prog) => {
        prog.addGraphicUniform("u_boundaryType", (uniform, params) => {
            const geom = params.geometry;
            uniform.setUniform1i(geom.boundaryType);
        });
    });
    frag.addUniform("u_blend_color", 5 /* VariableType.Vec4 */, (prog) => {
        prog.addGraphicUniform("u_blend_color", (uniform, params) => {
            const geom = params.geometry;
            const hiliteColor = params.target.uniforms.hilite.hiliteColor;
            const hiliteAlpha = params.target.uniforms.hilite.hiliteSettings.visibleRatio;
            switch (geom.boundaryType) {
                case CachedGeometry_1.BoundaryType.Outside:
                    setScratchColor(params.target.activeVolumeClassifierProps.flags.outside, hiliteColor, hiliteAlpha);
                    break;
                case CachedGeometry_1.BoundaryType.Inside:
                    setScratchColor(params.target.activeVolumeClassifierProps.flags.inside, hiliteColor, hiliteAlpha);
                    break;
                case CachedGeometry_1.BoundaryType.Selected:
                    // setScratchColor(params.target.activeVolumeClassifierProps!.flags.selected, hiliteColor, hiliteAlpha);
                    setScratchColor(core_common_1.SpatialClassifierInsideDisplay.Hilite, hiliteColor, hiliteAlpha); // option for how to display selected classifiers has been removed, always just hilite
                    break;
            }
            scratchColor.bind(uniform);
        });
    });
    frag.addUniform("u_depthTexture", 8 /* VariableType.Sampler2D */, (prog) => {
        prog.addGraphicUniform("u_depthTexture", (uniform, params) => {
            const geom = params.geometry;
            Texture_1.Texture2DHandle.bindSampler(uniform, geom.texture, RenderFlags_1.TextureUnit.Zero);
        });
    });
    builder.vert.headerComment = "//!V! VolClassSetBlend";
    builder.frag.headerComment = "//!F! VolClassSetBlend";
    return builder.buildProgram(context);
}
exports.createVolClassSetBlendProgram = createVolClassSetBlendProgram;
/** @internal */
function createVolClassBlendProgram(context) {
    const builder = (0, ViewportQuad_1.createViewportQuadBuilder)(true);
    builder.addInlineComputedVarying("v_texCoord", 3 /* VariableType.Vec2 */, computeTexCoord);
    const frag = builder.frag;
    frag.set(1 /* FragmentShaderComponent.ComputeBaseColor */, computeBlendTextureColor);
    frag.set(16 /* FragmentShaderComponent.AssignFragData */, Fragment_1.assignFragColor);
    frag.addUniform("u_blendTexture", 8 /* VariableType.Sampler2D */, (prog) => {
        prog.addGraphicUniform("u_blendTexture", (uniform, params) => {
            const geom = params.geometry;
            Texture_1.Texture2DHandle.bindSampler(uniform, geom.texture, RenderFlags_1.TextureUnit.Zero);
        });
    });
    builder.vert.headerComment = "//!V! VolClassBlend";
    builder.frag.headerComment = "//!F! VolClassBlend";
    return builder.buildProgram(context);
}
exports.createVolClassBlendProgram = createVolClassBlendProgram;
//# sourceMappingURL=CopyStencil.js.map