Exemple #1
0
void RegisterCombinersChunk::activate( DrawActionBase *action, UInt32  )
{
    Window *win = action->getWindow();

    if(! win->hasExtension(_nvRegisterCombiners))
        return;

    // setup register combiners

    // functions

    void (OSG_APIENTRY*CombinerParameterfv)(GLenum pname, GLfloat *params) =
        reinterpret_cast<void (OSG_APIENTRY*)(GLenum pname, GLfloat *params)>(
            win->getFunction(_funcCombinerParameterfv));

    void (OSG_APIENTRY*CombinerStageParameterfv)(GLenum stage,
            GLenum pname,
            GLfloat *params) =
                reinterpret_cast<void (OSG_APIENTRY*)(GLenum stage,
                        GLenum pname,
                        GLfloat *params)>(
                    win->getFunction(_funcCombinerStageParameterfv));

    void (OSG_APIENTRY*CombinerInput)(GLenum stage,
                                      GLenum portion,
                                      GLenum variable,
                                      GLenum input,
                                      GLenum mapping,
                                      GLenum component) =
                                          reinterpret_cast<void (OSG_APIENTRY*)(GLenum stage,
                                                  GLenum portion,
                                                  GLenum variable,
                                                  GLenum input,
                                                  GLenum mapping,
                                                  GLenum component)>(
                                                          win->getFunction(_funcCombinerInput));

    void (OSG_APIENTRY*CombinerOutput)(GLenum stage,
                                       GLenum portion,
                                       GLenum abOut,
                                       GLenum cdOut,
                                       GLenum sumOut,
                                       GLenum scale,
                                       GLenum bias,
                                       GLboolean abdot,
                                       GLboolean cddot,
                                       GLboolean muxSum) =
                                           reinterpret_cast<void (OSG_APIENTRY*)(GLenum stage,
                                                   GLenum portion,
                                                   GLenum abOut,
                                                   GLenum cdOut,
                                                   GLenum sumOut,
                                                   GLenum scale,
                                                   GLenum bias,
                                                   GLboolean abdot,
                                                   GLboolean cddot,
                                                   GLboolean muxSum)>(
                                                           win->getFunction(_funcCombinerOutput));

    void (OSG_APIENTRY*FinalCombinerInput)(GLenum variable,
                                           GLenum input,
                                           GLenum mapping,
                                           GLenum component) =
                                                   reinterpret_cast<void (OSG_APIENTRY*)(GLenum variable,
                                                           GLenum input,
                                                           GLenum mapping,
                                                           GLenum component)>(
                                                                   win->getFunction(_funcFinalCombinerInput));

    // how many combiners do we need?

    Int32 ncomb;

    for(ncomb = OSG_NUM_COMBINERS - 1; ncomb >= 0; ncomb--)
    {
        if(getVariableArgb(ncomb * 3) != unused)
            break;
    }

    if(ncomb < 0)
    {
        // no combiner active, return

        glDisable(GL_REGISTER_COMBINERS_NV);
        return;
    }

    ncomb++;

    GLfloat dummy = GLfloat(ncomb);
    CombinerParameterfv(GL_NUM_GENERAL_COMBINERS_NV, &dummy);
    CombinerParameterfv(GL_CONSTANT_COLOR0_NV,
                        const_cast<GLfloat *>(getColor0().getValuesRGBA()));

    CombinerParameterfv(GL_CONSTANT_COLOR1_NV,
                        const_cast<GLfloat*>(getColor1().getValuesRGBA()));

    dummy = getColorSumClamp();
    CombinerParameterfv(GL_COLOR_SUM_CLAMP_NV, &dummy);

    // setup the general combiners

    bool hasRC2 = win->hasExtension(_nvRegisterCombiners2);

    for(UInt16 i = 0; i < ncomb; i++)
    {
        if(getVariableArgb(i * 3) != unused)
        {
            // RGB inputs
            CombinerInput(GL_COMBINER0_NV + i, GL_RGB, GL_VARIABLE_A_NV,
                          getVariableArgb(i * 3),
                          getVariableArgb(i * 3 + 1),
                          getVariableArgb(i * 3 + 2) );
            CombinerInput(GL_COMBINER0_NV + i, GL_RGB, GL_VARIABLE_B_NV,
                          getVariableBrgb(i * 3),
                          getVariableBrgb(i * 3 + 1),
                          getVariableBrgb(i * 3 + 2) );
            CombinerInput(GL_COMBINER0_NV + i, GL_RGB, GL_VARIABLE_C_NV,
                          getVariableCrgb(i * 3),
                          getVariableCrgb(i * 3 + 1),
                          getVariableCrgb(i * 3 + 2) );
            CombinerInput(GL_COMBINER0_NV + i, GL_RGB, GL_VARIABLE_D_NV,
                          getVariableDrgb(i * 3),
                          getVariableDrgb(i * 3 + 1),
                          getVariableDrgb(i * 3 + 2) );

            // RGB output
            CombinerOutput(GL_COMBINER0_NV + i, GL_RGB,
                           getOutputABrgb    (i),
                           getOutputCDrgb    (i),
                           getOutputSumrgb   (i),
                           getScalergb       (i),
                           getBiasrgb        (i),
                           getDotABrgb       (i),
                           getDotCDrgb       (i),
                           getMuxSumrgb      (i) );

        }
        else
        {
            CombinerInput(GL_COMBINER0_NV + i, GL_RGB, GL_VARIABLE_A_NV,
                          GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB);
            CombinerInput(GL_COMBINER0_NV + i, GL_RGB, GL_VARIABLE_B_NV,
                          GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB);
            CombinerInput(GL_COMBINER0_NV + i, GL_RGB, GL_VARIABLE_C_NV,
                          GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB);
            CombinerInput(GL_COMBINER0_NV + i, GL_RGB, GL_VARIABLE_D_NV,
                          GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB);

            CombinerOutput(GL_COMBINER0_NV + i, GL_RGB,
                           GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV,
                           GL_NONE, GL_NONE,
                           GL_FALSE, GL_FALSE, GL_FALSE );

        }

        if(getVariableAalpha(i * 3) != unused)
        {
            // Alpha inputs
            CombinerInput(GL_COMBINER0_NV + i, GL_ALPHA, GL_VARIABLE_A_NV,
                          getVariableAalpha(i * 3),
                          getVariableAalpha(i * 3 + 1),
                          getVariableAalpha(i * 3 + 2) );
            CombinerInput(GL_COMBINER0_NV + i, GL_ALPHA, GL_VARIABLE_B_NV,
                          getVariableBalpha(i * 3),
                          getVariableBalpha(i * 3 + 1),
                          getVariableBalpha(i * 3 + 2) );
            CombinerInput(GL_COMBINER0_NV + i, GL_ALPHA, GL_VARIABLE_C_NV,
                          getVariableCalpha(i * 3),
                          getVariableCalpha(i * 3 + 1),
                          getVariableCalpha(i * 3 + 2) );
            CombinerInput(GL_COMBINER0_NV + i, GL_ALPHA, GL_VARIABLE_D_NV,
                          getVariableDalpha(i * 3),
                          getVariableDalpha(i * 3 + 1),
                          getVariableDalpha(i * 3 + 2) );

            // ALPHA output
            CombinerOutput(GL_COMBINER0_NV + i, GL_ALPHA,
                           getOutputABalpha    (i),
                           getOutputCDalpha    (i),
                           getOutputSumalpha   (i),
                           getScalealpha       (i),
                           getBiasalpha        (i),
                           GL_FALSE,
                           GL_FALSE,
                           getMuxSumalpha      (i) );
        }
        else
        {
            CombinerInput(GL_COMBINER0_NV + i, GL_ALPHA, GL_VARIABLE_A_NV,
                          GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA);
            CombinerInput(GL_COMBINER0_NV + i, GL_ALPHA, GL_VARIABLE_B_NV,
                          GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA);
            CombinerInput(GL_COMBINER0_NV + i, GL_ALPHA, GL_VARIABLE_C_NV,
                          GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA);
            CombinerInput(GL_COMBINER0_NV + i, GL_ALPHA, GL_VARIABLE_D_NV,
                          GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA);

            CombinerOutput(GL_COMBINER0_NV + i, GL_ALPHA,
                           GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV,
                           GL_NONE, GL_NONE,
                           GL_FALSE, GL_FALSE, GL_FALSE );
        }

        if(getPerStageConstants())
        {
            if(hasRC2)
            {
                CombinerStageParameterfv(
                    GL_COMBINER0_NV + i,
                    GL_CONSTANT_COLOR0_NV,
                    const_cast<GLfloat*>(
                        getCombinerColor0(i).getValuesRGBA()));

                CombinerStageParameterfv(
                    GL_COMBINER0_NV + i,
                    GL_CONSTANT_COLOR1_NV,
                    const_cast<GLfloat*>(
                        getCombinerColor1(i).getValuesRGBA()));

            }
            else
            {
                FWARNING(("RegisterCombinersChunk::register_combiners2 not"
                          "supported, constant colors ignored!!\n"));
            }
        }
    }

    if(hasRC2)
    {
        if(getPerStageConstants())
        {
            glEnable(GL_PER_STAGE_CONSTANTS_NV);
        }
        else
        {
            glDisable(GL_PER_STAGE_CONSTANTS_NV);
        }
    }

    glErr("RegisterCombinersChunk::general combiners setup");

    // setup the final combiner

    FinalCombinerInput(GL_VARIABLE_A_NV,
                       getVariableArgb(OSG_NUM_COMBINERS * 3),
                       getVariableArgb(OSG_NUM_COMBINERS * 3 + 1),
                       getVariableArgb(OSG_NUM_COMBINERS * 3 + 2));

    glErr("RegisterCombinersChunk::final combiner var a setup");

    FinalCombinerInput(GL_VARIABLE_B_NV,
                       getVariableBrgb(OSG_NUM_COMBINERS * 3),
                       getVariableBrgb(OSG_NUM_COMBINERS * 3 + 1),
                       getVariableBrgb(OSG_NUM_COMBINERS * 3 + 2));

    glErr("RegisterCombinersChunk::final combiner var b setup");

    FinalCombinerInput(GL_VARIABLE_C_NV,
                       getVariableCrgb(OSG_NUM_COMBINERS * 3),
                       getVariableCrgb(OSG_NUM_COMBINERS * 3 + 1),
                       getVariableCrgb(OSG_NUM_COMBINERS * 3 + 2));

    glErr("RegisterCombinersChunk::final combiner var c setup");

    FinalCombinerInput(GL_VARIABLE_D_NV,
                       getVariableDrgb(OSG_NUM_COMBINERS * 3),
                       getVariableDrgb(OSG_NUM_COMBINERS * 3 + 1),
                       getVariableDrgb(OSG_NUM_COMBINERS * 3 + 2));

    glErr("RegisterCombinersChunk::final combiner var d setup");

    FinalCombinerInput(GL_VARIABLE_E_NV,
                       getVariableE(0),
                       getVariableE(1),
                       getVariableE(2));

    glErr("RegisterCombinersChunk::final combiner var e setup");

    FinalCombinerInput(GL_VARIABLE_F_NV,
                       getVariableF(0),
                       getVariableF(1),
                       getVariableF(2));

    glErr("RegisterCombinersChunk::final combiner var f setup");

    FinalCombinerInput(GL_VARIABLE_G_NV,
                       getVariableG(0),
                       getVariableG(1),
                       getVariableG(2));

    glErr("RegisterCombinersChunk::final combiner setup");
    // and activate everything

    glEnable(GL_REGISTER_COMBINERS_NV);

    glErr("RegisterCombinersChunk::activate");
}
void DeferredContainer::draw() const {
    //"The Screen". It may not be actually the screen since a upper container might be postprocessing
    const RenderTargetBase* screen = RenderTargetBase::getCurrent();

    GL_ASSERT(glEnable(GL_DEPTH_TEST));
    GL_ASSERT(glDisable(GL_BLEND));

    //Deferred pass
    Debugger::pushMark("Deferred Pass", "Time spent rendering geometry to the g-buffer");
    drawMode = Deferred;
    RenderTargetBase::bind(gBuffer);
    GL_ASSERT(glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT));
    ContainerObject::draw();
    Debugger::popMark(); //deferred

    //Shadowmap pass
    Debugger::pushMark("Shadowmap Pass", "Time spent rendering geometry to the layered shadowmap");
    glEnable(GL_DEPTH_CLAMP);
    drawMode = ShadowMap;
    RenderTargetBase::bind(sunTarget);
    GL_ASSERT(glClear(GL_DEPTH_BUFFER_BIT));
    ContainerObject::draw();
    glDisable(GL_DEPTH_CLAMP);
    Debugger::popMark(); //shadow

    //Transparent shadowmap pass
    Debugger::pushMark("Transparent ShadowMap Pass", "Time spent rendering transparent geometry to the layered shadowmap");
    glEnable(GL_DEPTH_CLAMP);
    drawMode = TransShadowMap;
    RenderTargetBase::bind(sunTargetTrans);
    GL_ASSERT(glClear(GL_DEPTH_BUFFER_BIT));
    ContainerObject::draw();
    glDisable(GL_DEPTH_CLAMP);
    Debugger::popMark(); //transparent shadow

    Debugger::pushMark("Light Pass", "Time spent rendering deferred lights");
    //bind output texture (screen)
    RenderTargetBase::bind(screen);
    GL_ASSERT(glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT));

    //Light pass
    GL_ASSERT(glEnable(GL_BLEND));
    GL_ASSERT(glBlendFunc(GL_ONE, GL_ONE)); //additive
    GL_ASSERT(glDepthMask(GL_FALSE));
    GL_ASSERT(glDepthFunc(GL_ALWAYS));
    drawMode = Light;
    ContainerObject::draw();
    Debugger::popMark(); //lights

    //Ambient+Visibility pass
    Debugger::pushMark("Ambient+Visibility Pass", "Time spent rendering ambient light and sunlight contribution to the scene");
    GL_ASSERT(glDepthMask(GL_TRUE));
    const Camera* cam = (Camera*)getGame()->getObjectByName("playerCam");
    Sun* sun = (Sun*)getGame()->getObjectByName("sun");
    glm::mat4 biasMatrix( //gets coords from [-1..1] to [0..1]
                          0.5, 0.0, 0.0, 0.0,
                          0.0, 0.5, 0.0, 0.0,
                          0.0, 0.0, 0.5, 0.0,
                          0.5, 0.5, 0.5, 1.0
                          );
    //compute each of the cascaded cameras's matrices
    std::vector<mat4f> depthMVP(NUM_SUN_CASCADES);
    for(int i = 0; i < NUM_SUN_CASCADES; ++i)
        depthMVP[i] = biasMatrix*(sun->getVPMatrices()[i]*fullTransform);
    Programs.get("ambientPass").uniform("MVP")->set(mat4f(1.0f));
    Programs.get("ambientPass").uniform("camMV")->set(cam->getView()*fullTransform);
    Programs.get("ambientPass").uniform("color0")->set(getColor0());
    Programs.get("ambientPass").uniform("color1")->set(getColor1());
    Programs.get("ambientPass").uniform("invResolution")->set(vec2f(1.0f/screen->getSize().x, 1.0f/screen->getSize().y));
    Programs.get("ambientPass").uniform("invCamProj")->set(glm::inverse(cam->projection));
    Programs.get("ambientPass").uniform("invCamView")->set(glm::inverse(cam->getView()));
    Programs.get("ambientPass").uniform("lightDir")->set(sun->getCam(0)->getForward());
    Programs.get("ambientPass").uniform("worldsize")->set(WORLDSIZE);
    Programs.get("ambientPass").uniform("depthMVP")->set(depthMVP);
    Programs.get("ambientPass").uniform("depthPlanes")->set(sun->getDepthPlanes());
    Programs.get("ambientPass").uniform("depth")->set(gBuffer.getTexture(RenderTargetBase::DEPTH));
    Programs.get("ambientPass").uniform("sunDepth")->set(sunTarget.getTexture(RenderTargetBase::DEPTH));
    Programs.get("ambientPass").uniform("sunDepthTrans")->set(sunTargetTrans.getTexture(RenderTargetBase::DEPTH));
    quad->draw(Programs.get("ambientPass"));
    Debugger::popMark(); //ambient+shadowmap

    //Forward pass
    Debugger::pushMark("Forward Pass", "Time spent rendering forward-render stuff");
    GL_ASSERT(glDepthMask(GL_TRUE));
    GL_ASSERT(glDepthFunc(GL_LEQUAL));
    GL_ASSERT(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); //forward rendering blending
    drawMode = Forward;
    ContainerObject::draw();
    Debugger::popMark();
}