void GLBackend::do_setStateStencil(State::StencilActivation activation, State::StencilTest testFront, State::StencilTest testBack) {
    const auto& currentActivation = _pipeline._stateCache.stencilActivation;
    const auto& currentTestFront = _pipeline._stateCache.stencilTestFront;
    const auto& currentTestBack = _pipeline._stateCache.stencilTestBack;
    if ((currentActivation != activation)
        || (currentTestFront != testFront)
        || (currentTestBack != testBack)) {

        if (activation.isEnabled()) {
            glEnable(GL_STENCIL_TEST);
        } else {
            glDisable(GL_STENCIL_TEST);
        }

        if (activation.getWriteMaskFront() != activation.getWriteMaskBack()) {
            glStencilMaskSeparate(GL_FRONT, activation.getWriteMaskFront());
            glStencilMaskSeparate(GL_BACK, activation.getWriteMaskBack());
        } else {
            glStencilMask(activation.getWriteMaskFront());
        }

        static GLenum STENCIL_OPS[State::NUM_STENCIL_OPS] = {
            GL_KEEP,
            GL_ZERO,
            GL_REPLACE,
            GL_INCR_WRAP,
            GL_DECR_WRAP,
            GL_INVERT,
            GL_INCR,
            GL_DECR };

        if (testFront != testBack) {
            glStencilOpSeparate(GL_FRONT, STENCIL_OPS[testFront.getFailOp()], STENCIL_OPS[testFront.getPassOp()], STENCIL_OPS[testFront.getDepthFailOp()]);
            glStencilFuncSeparate(GL_FRONT, COMPARISON_TO_GL[testFront.getFunction()], testFront.getReference(), testFront.getReadMask());

            glStencilOpSeparate(GL_BACK, STENCIL_OPS[testBack.getFailOp()], STENCIL_OPS[testBack.getPassOp()], STENCIL_OPS[testBack.getDepthFailOp()]);
            glStencilFuncSeparate(GL_BACK, COMPARISON_TO_GL[testBack.getFunction()], testBack.getReference(), testBack.getReadMask());
        } else {
            glStencilOp(STENCIL_OPS[testFront.getFailOp()], STENCIL_OPS[testFront.getPassOp()], STENCIL_OPS[testFront.getDepthFailOp()]);
            glStencilFunc(COMPARISON_TO_GL[testFront.getFunction()], testFront.getReference(), testFront.getReadMask());
        }

        (void)CHECK_GL_ERROR();

        _pipeline._stateCache.stencilActivation = activation;
        _pipeline._stateCache.stencilTestFront = testFront;
        _pipeline._stateCache.stencilTestBack = testBack;
    }
}
Exemple #2
0
void GLBackend::do_setStateStencil(State::StencilActivation activation, State::StencilTest frontTest, State::StencilTest backTest) {
    
    if ((_pipeline._stateCache.stencilActivation != activation)
        || (_pipeline._stateCache.stencilTestFront != frontTest)
        || (_pipeline._stateCache.stencilTestBack != backTest)) {

        if (activation.isEnabled()) {
            glEnable(GL_STENCIL_TEST);
            glStencilMaskSeparate(GL_FRONT, activation.getWriteMaskFront());
            glStencilMaskSeparate(GL_BACK, activation.getWriteMaskBack());

            static GLenum STENCIL_OPS[] = {
                GL_KEEP,
                GL_ZERO,
                GL_REPLACE,
                GL_INCR_WRAP,
                GL_DECR_WRAP,
                GL_INVERT,
                GL_INCR,
                GL_DECR };

            glStencilFuncSeparate(GL_FRONT, STENCIL_OPS[frontTest.getFailOp()], STENCIL_OPS[frontTest.getPassOp()], STENCIL_OPS[frontTest.getDepthFailOp()]);
            glStencilFuncSeparate(GL_FRONT, GL_COMPARISON_FUNCTIONS[frontTest.getFunction()], frontTest.getReference(), frontTest.getReadMask());

            glStencilFuncSeparate(GL_BACK, STENCIL_OPS[backTest.getFailOp()], STENCIL_OPS[backTest.getPassOp()], STENCIL_OPS[backTest.getDepthFailOp()]);
            glStencilFuncSeparate(GL_BACK, GL_COMPARISON_FUNCTIONS[backTest.getFunction()], backTest.getReference(), backTest.getReadMask());
        } else {
            glDisable(GL_STENCIL_TEST);
        }
        (void) CHECK_GL_ERROR();

        _pipeline._stateCache.stencilActivation = activation;
        _pipeline._stateCache.stencilTestFront = frontTest;
        _pipeline._stateCache.stencilTestBack = backTest;
    }
}