void ShaderShadowMapEngine::updatePointLightRenderTargets(SSMEngineData *data)
{
    if(data->getMFRenderTargets()->empty() == true)
    {
        for(UInt16 i = 0; i < 6; ++i)
        {
            FrameBufferObjectUnrecPtr newTarget =
                FrameBufferObject::createLocal();
            newTarget->setWidth          (this->getWidth           ( ));
            newTarget->setHeight         (this->getHeight          ( ));
            newTarget->setDepthAttachment(data->getShadowTexBuffers(i));

            data->editMFRenderTargets()->push_back(newTarget);
        }
    }
    else
    {
        for(UInt16 i = 0; i < 6; ++i)
        {
            FrameBufferObject *target = data->getRenderTargets(i);

            if((target->getWidth () != this->getWidth ()) ||
               (target->getHeight() != this->getHeight())   )
            {
                target->setWidth (this->getWidth ());
                target->setHeight(this->getHeight());
            }
        }
    }
}
void ShaderShadowMapEngine::handleDirectionalLightEnter(
    DirectionalLight *dirL, RenderAction *ract, SSMEngineData *data)
{
    RenderPartition *parentPart = ract      ->getActivePartition();
    FrustumVolume    camFrust   = parentPart->getFrustum        ();

    Matrix matEyeToWorld  (parentPart->getCameraToWorld());
    Matrix matWorldToLight;
    Matrix matEyeToLight;

    calcDirectionalLightMatrices(matWorldToLight, matEyeToLight,
                                 dirL,            matEyeToWorld );

    // place light camera outside the scene bounding box:
    //  - project camera frustum and scene bounding box into a
    //    coordinate system where the directional light shines
    //    along the -z axis.
    //  - compute 2 AABBs that contain the projected frustum and
    //    scene BB
    //  - width and height of the ortho projection are determined from
    //    the frustum AABB, while near and far are determined by the
    //    scene AABB (offscreen objects cast shadows into the view volume)
          Pnt3f      camVerts  [10];
          Pnt3f      sceneVerts[10];
    const Matrix    &matSceneToWorld = ract->topMatrix ();
          BoxVolume  sceneBB         = ract->getActNode()->getVolume();

    camFrust.getCorners(camVerts  [0], camVerts  [1],
                        camVerts  [2], camVerts  [3],
                        camVerts  [4], camVerts  [5],
                        camVerts  [6], camVerts  [7] );
    sceneBB .getCorners(sceneVerts[0], sceneVerts[1],
                        sceneVerts[2], sceneVerts[3],
                        sceneVerts[4], sceneVerts[5],
                        sceneVerts[6], sceneVerts[7] );

    camVerts  [8].setValues(TypeTraits<Real32>::getMax(),
                            TypeTraits<Real32>::getMax(),
                            TypeTraits<Real32>::getMax() );
    camVerts  [9].setValues(TypeTraits<Real32>::getMin(),
                            TypeTraits<Real32>::getMin(),
                            TypeTraits<Real32>::getMin() );
    sceneVerts[8].setValues(TypeTraits<Real32>::getMax(),
                            TypeTraits<Real32>::getMax(),
                            TypeTraits<Real32>::getMax() );
    sceneVerts[9].setValues(TypeTraits<Real32>::getMin(),
                            TypeTraits<Real32>::getMin(),
                            TypeTraits<Real32>::getMin() );

    for(UInt32 i = 0; i < 8; ++i)
    {
        matWorldToLight.mult(camVerts  [i], camVerts  [i]);

        matSceneToWorld.mult(sceneVerts[i], sceneVerts[i]);
        matWorldToLight.mult(sceneVerts[i], sceneVerts[i]);

        camVerts  [8][0] = osgMin(camVerts  [8][0], camVerts  [i][0]);
        camVerts  [9][0] = osgMax(camVerts  [9][0], camVerts  [i][0]);
        camVerts  [8][1] = osgMin(camVerts  [8][1], camVerts  [i][1]);
        camVerts  [9][1] = osgMax(camVerts  [9][1], camVerts  [i][1]);

        sceneVerts[8][0] = osgMin(sceneVerts[8][0], sceneVerts[i][0]);
        sceneVerts[9][0] = osgMax(sceneVerts[9][0], sceneVerts[i][0]);
        sceneVerts[8][1] = osgMin(sceneVerts[8][1], sceneVerts[i][1]);
        sceneVerts[9][1] = osgMax(sceneVerts[9][1], sceneVerts[i][1]);
        sceneVerts[8][2] = osgMin(sceneVerts[8][2], sceneVerts[i][2]);
        sceneVerts[9][2] = osgMax(sceneVerts[9][2], sceneVerts[i][2]);
    }

    // these points are the corners of the ortho shadow view volume
    Pnt3f lightMin(osgMax(camVerts[8][0], sceneVerts[8][0]),
                   osgMax(camVerts[8][1], sceneVerts[8][1]),
                   -sceneVerts[9][2]);
    
    Pnt3f lightMax(osgMin(camVerts[9][0], sceneVerts[9][0]),
                   osgMin(camVerts[9][1], sceneVerts[9][1]),
                   -sceneVerts[8][2]);

    // enlarge by 2% in x, y, z direction
    lightMin[0] -= (lightMax[0] - lightMin[0]) * 0.01f;
    lightMin[1] -= (lightMax[1] - lightMin[1]) * 0.01f; 
    lightMin[2] -= (lightMax[2] - lightMin[2]) * 0.01f;

    lightMax[0] += (lightMax[0] - lightMin[0]) * 0.01f;
    lightMax[1] += (lightMax[1] - lightMin[1]) * 0.01f;
    lightMax[2] += (lightMax[2] - lightMin[2]) * 0.01f;

    Matrix matLightProj;
    Matrix matLightProjTrans;

    MatrixOrthogonal(matLightProj,
                     lightMin[0], lightMax[0],
                     lightMin[1], lightMax[1],
                     lightMin[2], lightMax[2] );

    updateShadowTexImage  (data);
    updateShadowTexBuffers(data);
    updateRenderTargets   (data);

    Int32 shadowTexUnit = (this->getForceTextureUnit() > 0) ?
                           this->getForceTextureUnit()      : 7;

    ShaderProgram *shadowFP = this->getShadowFragmentProgram();

    if(shadowFP == NULL)
    {
        ShaderProgramUnrecPtr newShadowFP = ShaderProgram::createLocal();
        newShadowFP->setShaderType(GL_FRAGMENT_SHADER);
        newShadowFP->setProgram   (_dirFPCode        );

        newShadowFP->addUniformVariable("SSME_matEyeToLight", matEyeToLight);
        newShadowFP->addUniformVariable("SSME_matLightProj",  matLightProj );
        newShadowFP->addUniformVariable("SSME_texShadow",     shadowTexUnit);

        this->setShadowFragmentProgram(newShadowFP);
        shadowFP = newShadowFP;
    }
    else
    {
        shadowFP->updateUniformVariable("SSME_matEyeToLight", matEyeToLight);
        shadowFP->updateUniformVariable("SSME_matLightProj",  matLightProj );
    }

    commitChanges();

    this->pushPartition(ract);
    {
        RenderPartition   *part   = ract->getActivePartition( );
        Window            *win    = ract->getWindow         ( );
        FrameBufferObject *target = data->getRenderTargets  (0);
        Background        *back   = data->getBackground     ( );

        part->setRenderTarget(target);
        part->setWindow      (win   );

        part->calcViewportDimension(0.f, 0.f, 1.f, 1.f,
                                    target->getWidth (),
                                    target->getHeight() );

        part->setupProjection(matLightProj, matLightProjTrans);
        part->setupViewing   (matWorldToLight                );

        part->setNear        (parentPart->getNear());
        part->setFar         (parentPart->getFar ());

        part->calcFrustum    (                     );

        part->setBackground  (back                 );

        // force material for shadow map generation
        part->overrideMaterial(data->getLightPassMaterials(0),
                               ract->getActNode           ( ) );

        this->recurseFrom(ract, dirL);
        ract->useNodeList(false     );

        // undo override
        part->overrideMaterial(NULL,
                               ract->getActNode           ( ) );
    }
    this->popPartition(ract);
}
void ShaderShadowMapEngine::handleSpotLightEnter(
    SpotLight *spotL, RenderAction *ract, SSMEngineData *data)
{
    RenderPartition *parentPart    = ract->getActivePartition();
//    Real             cosSpotCutOff = osgCos(spotL->getSpotCutOff());

    Matrix matEyeToWorld  (parentPart->getCameraToWorld());
    Matrix matWorldToLight;
    Matrix matEyeToLight;

    calcSpotLightMatrices(matWorldToLight, matEyeToLight, 
                          spotL,           matEyeToWorld );

    Real32  lightNear;
    Real32  lightFar;

    calcPointLightRange(spotL, 0.001f,
                        parentPart->getNear(), parentPart->getFar(),
                        lightNear,             lightFar             );

    if(getShadowNear() != 0.f)
    {
        lightNear = getShadowNear();
    }

    if(getShadowFar() != 0.f)
    {
        lightFar  = getShadowFar();
    }

    Matrix matLightProj;
    Matrix matLightProjTrans;

    MatrixPerspective(matLightProj, 
                      spotL->getSpotCutOff(), 1.f,
                      lightNear, lightFar         );
    
    updateShadowTexImage  (data);
    updateShadowTexBuffers(data);
    updateRenderTargets   (data);

    Int32          shadowTexUnit = (this->getForceTextureUnit() > 0) ?
                                    this->getForceTextureUnit()      : 7;
    ShaderProgram *shadowFP      = this->getShadowFragmentProgram();

    if(shadowFP == NULL)
    {
        ShaderProgramUnrecPtr newShadowFP = ShaderProgram::createLocal();
        newShadowFP->setShaderType(GL_FRAGMENT_SHADER);
        newShadowFP->setProgram   (_spotFPCode       );

        newShadowFP->addUniformVariable("SSME_matEyeToLight", matEyeToLight);
        newShadowFP->addUniformVariable("SSME_matLightProj",  matLightProj );
        newShadowFP->addUniformVariable("SSME_texShadow",     shadowTexUnit);

        this->setShadowFragmentProgram(newShadowFP);
        shadowFP = newShadowFP;
    }
    else
    {
        shadowFP->updateUniformVariable("SSME_matEyeToLight", matEyeToLight);
        shadowFP->updateUniformVariable("SSME_matLightProj",  matLightProj );
    }

    commitChanges();

    this->pushPartition(ract);
    {
        RenderPartition   *part   = ract->getActivePartition( );
        Window            *win    = ract->getWindow         ( );
        FrameBufferObject *target = data->getRenderTargets  (0);
        Background        *back   = data->getBackground     ( );

        part->setRenderTarget(target);
        part->setWindow      (win   );

        part->calcViewportDimension(0.f, 0.f, 1.f, 1.f,
                                    target->getWidth (),
                                    target->getHeight() );

        part->setupProjection(matLightProj, matLightProjTrans);
        part->setupViewing   (matWorldToLight                );

        part->setNear        (parentPart->getNear());
        part->setFar         (parentPart->getFar ());

        part->calcFrustum    (                     );

        part->setBackground  (back                 );

        // force material for shadow map generation
        part->overrideMaterial(data->getLightPassMaterials(0),
                               ract->getActNode           ( ) );

        this->recurseFrom(ract, spotL);
        ract->useNodeList(false      );

        // undo override
        part->overrideMaterial(NULL,
                               ract->getActNode           ( ) );
    }
    this->popPartition(ract);
}
void
DepthPeelingStage::setupRenderScene(RenderAction* a,
                                    Int32         iVPWidth,
                                    Int32         iVPHeight,
                                    bool          isInitial,
                                    bool          isPing    )
{
    this->pushPartition(a);
    {
        RenderPartition   *pPart   = a->getActivePartition();
        FrameBufferObject *pTarget = NULL;
        Viewarea          *pArea   = a->getViewarea       ();
        Camera            *pCam    = a->getCamera         ();
        Background        *pBack   = NULL;


        DepthPeelingStageDataUnrecPtr pData =
            a->getData<DepthPeelingStageData *>(_iDataSlotId);

        if(!pData)
        {
            this->initData(a, iVPWidth, iVPHeight);
        }
        else
        {
            this->updateData(a, iVPWidth, iVPHeight);
        }
        pData = a->getData<DepthPeelingStageData *>(_iDataSlotId);

        if (isInitial)
        {
            pTarget = pData->getBlendFBO();
            pBack   = a->getBackground  ();
        }
        else
        {
            if (isPing)
                pTarget = pData->getPeelPingFBO();
            else
                pTarget = pData->getPeelPongFBO();

            pBack = pData->getBackground();
        }
        pPart->setRenderTarget(pTarget);

        if(pArea != NULL)
        {
            pPart->setWindow  (a->getWindow());

            if(pTarget != NULL)
            {
                pPart->calcViewportDimension(pArea->getLeft  (),
                                                pArea->getBottom(),
                                                pArea->getRight (),
                                                pArea->getTop   (),

                                                pTarget->getWidth    (),
                                                pTarget->getHeight   ());
            }
            else
            {
                pPart->calcViewportDimension(pArea->getLeft  (),
                                                pArea->getBottom(),
                                                pArea->getRight (),
                                                pArea->getTop   (),

                                                a->getWindow()->getWidth (),
                                                a->getWindow()->getHeight());
            }

            if(pCam != NULL)
            {
                Matrix m, t;

                // set the projection
                pCam->getProjection          (m,
                                                pPart->getViewportWidth (),
                                                pPart->getViewportHeight());

                pCam->getProjectionTranslation(t,
                                                pPart->getViewportWidth (),
                                                pPart->getViewportHeight());

                pPart->setupProjection(m, t);

                pCam->getViewing(m,
                                    pPart->getViewportWidth (),
                                    pPart->getViewportHeight());


                pPart->setupViewing(m);

                pPart->setNear     (pCam->getNear());
                pPart->setFar      (pCam->getFar ());

                pPart->calcFrustum();
            }

            pPart->setBackground(pBack);
        }

        pPart->addSetupModeBit(RenderPartition::BackgroundSetup);

        pPart->pushState();
        if (!isInitial)
        {
            FrameBufferObject* fbo           =
                isPing ? pData->getPeelPongFBO() : pData->getPeelPingFBO();
            TextureBuffer*     texbuf        =
                static_cast<TextureBuffer *>(fbo->getDepthAttachment());
            TextureObjChunk*   depthTexChunk = texbuf->getTexture();

            pPart->addOverride(depthTexChunk->getClassId() + getDepthTexUnit(),
                               depthTexChunk                                   );
            pPart->addOverride(pData->getSpvIsPeelChunk()->getClassId(),
                               pData->getSpvIsPeelChunk()               );
        }
        else
        {
            pPart->addOverride(pData->getSpvIsInitialChunk()->getClassId(),
                               pData->getSpvIsInitialChunk()               );
        }

        pPart->addOverride(pData->getDepthChunk()->getClassId(),
                           pData->getDepthChunk()               );

        this->recurseFromThis(a);
        a->useNodeList(false);

        pPart->popState();
    }
    this->popPartition(a);
}
void ShaderShadowMapEngine::handlePointLightEnter(
    PointLight *pointL, RenderAction *ract, SSMEngineData *data)
{
    RenderPartition *parentPart = ract->getActivePartition();

    Matrix matEyeToWorld(parentPart->getCameraToWorld());
    Matrix matLightProj;

    Real32 lightNear;
    Real32 lightFar;

    calcPointLightRange(pointL, 0.001f,
                        parentPart->getNear(), parentPart->getFar(),
                        lightNear,             lightFar             );

    MatrixPerspective(matLightProj, Pi / 4.f, 1.f,
                      lightNear, lightFar         );

    Matrix matWorldToLight;
    Matrix matEyeToLight;

    calcPointLightMatrices(matWorldToLight, matEyeToLight,
                           pointL,          matEyeToWorld );

    updatePointLightShadowTexImage  (data);
    updatePointLightShadowTexBuffers(data);
    updatePointLightRenderTargets   (data);

    Int32 shadowTexUnit = (this->getForceTextureUnit() > 0) ?
                           this->getForceTextureUnit()      : 7;

    ShaderProgram *shadowFP = this->getShadowFragmentProgram();

    if(shadowFP == NULL)
    {
        ShaderProgramUnrecPtr newShadowFP = ShaderProgram::createLocal();
        newShadowFP->setShaderType(GL_FRAGMENT_SHADER);
        newShadowFP->setProgram   (_pointFPCode      );

        newShadowFP->addUniformVariable("SSME_matEyeToLight", matEyeToLight);
        newShadowFP->addUniformVariable("SSME_matLightProj",  matLightProj );
        newShadowFP->addUniformVariable("SSME_texShadow",     shadowTexUnit);

        this->setShadowFragmentProgram(newShadowFP);
        shadowFP = newShadowFP;
    }
    else
    {
        shadowFP->updateUniformVariable("SSME_matEyeToLight", matEyeToLight);
        shadowFP->updateUniformVariable("SSME_matLightProj",  matLightProj );
    }

    commitChanges();

    // schedule rendering of cube faces
    for(UInt16 i = 0; i < 6; ++i)
    {
        Matrix matWorldToLightFace(matWorldToLight);
        matWorldToLightFace.multLeft(_matCubeFaceInv[i]);

        this->pushPartition(ract);
        {
            RenderPartition   *part   = ract->getActivePartition( );
            Window            *win    = ract->getWindow         ( );
            FrameBufferObject *target = data->getRenderTargets  (i);
            Background        *back   = data->getBackground     ( );

            part->setRenderTarget(target);
            part->setWindow      (win   );

            part->calcViewportDimension(0.f, 0.f, 1.f, 1.f,
                                        target->getWidth (),
                                        target->getHeight() );

            part->setupProjection(matLightProj, Matrix::identity());
            part->setupViewing   (matWorldToLightFace             );

            part->setNear        (parentPart->getNear());
            part->setFar         (parentPart->getFar ());

            part->calcFrustum    (                     );

            part->setBackground  (back                 );

            // force material for shadow map generation
            part->overrideMaterial(data->getLightPassMaterials(0),
                                   ract->getActNode           ( ) );

            this->recurseFrom(ract, pointL);
            ract->useNodeList(false       );

            // undo override
            part->overrideMaterial(NULL,
                                   ract->getActNode           ( ) );
        }
        this->popPartition(ract);
    }
}
void DeferredShadingStage::setupShadingPartition(
    RenderPartition *part, RenderAction *ract, DSStageData *data)
{
    Window            *win    = ract->getWindow           ();
    FrameBufferObject *target = data->getShadingTarget    ();
    Camera            *cam    = this->getCamera           ();
    Background        *back   = this->getBackground       ();

    part->setRenderTarget(target);
    part->setWindow      (win   );

    if(target != NULL)
    {
        part->calcViewportDimension(this->getLeft    (),
                                    this->getBottom  (),
                                    this->getRight   (),
                                    this->getTop     (),

                                    target->getWidth (),
                                    target->getHeight() );
    }
    else if(win != NULL)
    {
        part->calcViewportDimension(this->getLeft  (),
                                    this->getBottom(),
                                    this->getRight (),
                                    this->getTop   (),

                                    win->getWidth  (),
                                    win->getHeight () );
    }
    else
    {
        SWARNING << "DeferredShadingStage::setupShadingPartition: "
                 << "No target or window." << std::endl;
    }

    // setup ortho projection
    Matrix matProjection;
    Matrix matProjectionTranslation;
    Matrix matViewing;

    matProjectionTranslation.setIdentity();
    matViewing              .setIdentity();

    MatrixOrthogonal(matProjection,
                     -1.f, 1.f,
                     -1.f, 1.f,
                     -1.f, 1.f );

    part->setupProjection(matProjection, matProjectionTranslation);
    part->setupViewing   (matViewing                             );

    part->setNear(-1.f);
    part->setFar ( 1.f);

    // setup VPCamera matrices to original projection -- TODO copy from GBuffer pass?
    cam->getProjection           (matProjection,
                                  part->getViewportWidth (),
                                  part->getViewportHeight() );
    cam->getProjectionTranslation(matProjectionTranslation,
                                  part->getViewportWidth (),
                                  part->getViewportHeight() );

    Matrix matProjectionFull = matProjection;
    matProjectionFull.mult(matProjectionTranslation);

    Matrix matToWorld;
    Matrix matWorldToScreen;

    cam->getViewing(matViewing, part->getViewportWidth (),
                                part->getViewportHeight() );
    matToWorld.invertFrom(matViewing);

    matWorldToScreen = matProjectionFull;
    matWorldToScreen.mult(matToWorld);

    part->setVPCameraMatrices(matProjectionFull,
                              matProjection,
                              matProjectionTranslation,
                              matViewing,
                              matToWorld,
                              matWorldToScreen          );

    part->setBackground(back);

    part->setSetupMode(RenderPartition::ProjectionSetup |
                       RenderPartition::BackgroundSetup  );
}
Ejemplo n.º 7
0
Action::ResultE PostShaderStage::renderEnter(Action *action)
{
    RenderAction *a = dynamic_cast<RenderAction *>(action);

    a->disableDefaultPartition();

    this->beginPartitionGroup(a);
    {
        this->pushPartition(a);
        {
            RenderPartition   *pPart    = a->getActivePartition();
            FrameBufferObject *pTarget  = this->getRenderTarget();
            Viewarea          *pArea    = a->getViewarea();
            Camera            *pCam     = a->getCamera  ();
            Background        *pBack    = a->getBackground();
            
            if(pTarget == NULL)
            {
                this->initData(a);

                pTarget  = this->getRenderTarget();
            }

            pPart->setRenderTarget(pTarget);
            
#ifdef OSG_DEBUGX
            std::string szMessage("RenderPartition\n");
            pPart->setDebugString(szMessage          );
#endif

            if(pArea != NULL)
            {
//                pPart->setViewport(pPort         );
                pPart->setWindow  (a->getWindow());
                
                if(pTarget != NULL)
                {
#if 0
                    pPart->calcViewportDimension(pArea->getLeft  (),
                                                 pArea->getBottom(),
                                                 pArea->getRight (),
                                                 pArea->getTop   (),
                                                 
                                                 pTarget->getWidth    (),
                                                 pTarget->getHeight   ());

#endif
                    pPart->calcViewportDimension(0.f,
                                                 0.f,
                                                 1.f,
                                                 1.f,
                                                 
                                                 pTarget->getWidth    (),
                                                 pTarget->getHeight   ());

                }
                else
                {
                    pPart->calcViewportDimension(pArea->getLeft  (),
                                                 pArea->getBottom(),
                                                 pArea->getRight (),
                                                 pArea->getTop   (),
                                                 
                                                 a->getWindow()->getWidth (),
                                                 a->getWindow()->getHeight());
                }
                
                if(pCam != NULL)
                {
                    Matrix m, t;
                    
                    // set the projection
                    pCam->getProjection          (m, 
                                                  pPart->getViewportWidth (), 
                                                  pPart->getViewportHeight());
                    
                    pCam->getProjectionTranslation(t, 
                                                   pPart->getViewportWidth (), 
                                                   pPart->getViewportHeight());
                    
                    pPart->setupProjection(m, t);
                    
                    pCam->getViewing(m, 
                                     pPart->getViewportWidth (),
                                     pPart->getViewportHeight());
                    
                    
                    pPart->setupViewing(m);
                    
                    pPart->setNear     (pCam->getNear());
                    pPart->setFar      (pCam->getFar ());
                    
                    pPart->calcFrustum();
                }
                
                pPart->setBackground(pBack);
            }
            
            this->recurseFromThis(a);
        }
        this->popPartition(a);
        
        this->pushPartition(a,
                            (RenderPartition::CopyWindow      |
                             RenderPartition::CopyViewportSize),
                            RenderPartition::SimpleCallback    );
        {
            RenderPartition *pPart  = a->getActivePartition();

#ifdef OSG_DEBUGX
            std::string szMessage("PostProcessPartition\n");
            pPart->setDebugString(szMessage          );
#endif
           
            Matrix m, t;
                
            m.setIdentity();
            t.setIdentity();
                
            MatrixOrthogonal( m,
                              0.f, 1.f,
                              0.f, 1.f,
                             -1.f, 1.f);
            
            pPart->setupProjection(m, t);
                
            RenderPartition::SimpleDrawCallback f;
                
            f = boost::bind(&PostShaderStage::postProcess, this, _1);
                
            pPart->dropFunctor(f);
        }
        this->popPartition(a);
    }
    this->endPartitionGroup(a);

    RenderPassVector::iterator passIt = _vPostProcessPasses.begin();

    //Update the uniform parameters to the shader
    for(; passIt != _vPostProcessPasses.end(); ++passIt)
    {
        (*passIt)->updateUniformVariables(a);
    }

    return Action::Skip;
}
Ejemplo n.º 8
0
Action::ResultE HDRStage::renderEnter(Action *action)
{
    RenderAction *a = dynamic_cast<RenderAction *>(action);

    a->disableDefaultPartition();

    Int32 iVPWidth  = a->getActivePartition()->getViewportWidth ();
    Int32 iVPHeight = a->getActivePartition()->getViewportHeight();

    this->beginPartitionGroup(a);
    {
        this->pushPartition(a);
        {
            RenderPartition   *pPart    = a   ->getActivePartition();
            FrameBufferObject *pTarget  = this->getRenderTarget   ();
            Viewarea          *pArea    = a   ->getViewarea       ();
            Camera            *pCam     = a   ->getCamera         ();
            Background        *pBack    = a   ->getBackground     ();
            
            if(pTarget == NULL)
            {
                this->initData(a, iVPWidth, iVPHeight);

                pTarget  = this->getRenderTarget();
            }
            else
            {
                this->updateData(a, iVPWidth, iVPHeight);
            }

            pPart->setRenderTarget(pTarget);
            pPart->getDrawEnv().setTargetBufferFormat(this->getBufferFormat());

#ifdef OSG_DEBUGX
            std::string szMessage("HDR: RenderPartition\n");
            pPart->setDebugString(szMessage          );
#endif

            if(pArea != NULL)
            {
                pPart->setWindow  (a->getWindow());
                
                if(pTarget != NULL)
                {
#if 0
                    pPart->calcViewportDimension(pArea->getLeft  (),
                                                 pArea->getBottom(),
                                                 pArea->getRight (),
                                                 pArea->getTop   (),
                                                 
                                                 pTarget->getWidth    (),
                                                 pTarget->getHeight   ());
#endif
                    pPart->calcViewportDimension(0.f,
                                                 0.f,
                                                 1.f,
                                                 1.f,
                                                 
                                                 pTarget->getWidth    (),
                                                 pTarget->getHeight   ());

                }
                else
                {
                    pPart->calcViewportDimension(pArea->getLeft  (),
                                                 pArea->getBottom(),
                                                 pArea->getRight (),
                                                 pArea->getTop   (),
                                                 
                                                 a->getWindow()->getWidth (),
                                                 a->getWindow()->getHeight());
                }

                if(pCam != NULL)
                {
                    Matrix m, t;
                    
                    // set the projection
                    pCam->getProjection          (m, 
                                                  pPart->getViewportWidth (), 
                                                  pPart->getViewportHeight());
                    
                    pCam->getProjectionTranslation(t, 
                                                   pPart->getViewportWidth (), 
                                                   pPart->getViewportHeight());
                    
                    pPart->setupProjection(m, t);
                    
                    pCam->getViewing(m, 
                                     pPart->getViewportWidth (),
                                     pPart->getViewportHeight());
                    
                    
                    pPart->setupViewing(m);
                    
                    pPart->setNear     (pCam->getNear());
                    pPart->setFar      (pCam->getFar ());
                    
                    pPart->calcFrustum();
                }
                
                pPart->setBackground(pBack);
            }
            
            this->recurseFromThis(a);
        }
        this->popPartition(a);

        a->getActivePartition()->disable();

        this->pushPartition(a,
                            (RenderPartition::CopyWindow       |
                             RenderPartition::CopyViewportSize |
                             RenderPartition::CopyTarget       ),
                            RenderPartition::SimpleCallback    );
        {
            RenderPartition *pPart  = a->getActivePartition();

#ifdef OSG_DEBUGX
            std::string szMessage("HDR: PostProcessPartition\n");
            pPart->setDebugString(szMessage          );
#endif

            Matrix m, t;
                
            m.setIdentity();
            t.setIdentity();
                
            MatrixOrthogonal( m,
                              0.f, 1.f,
                              0.f, 1.f,
                             -1.f, 1.f);
            
            pPart->setupProjection(m, t);
                
            RenderPartition::SimpleDrawCallback f;
                
            f = boost::bind(&HDRStage::postProcess, this, _1);
                
            pPart->dropFunctor(f);
        }
        this->popPartition(a);
    }
    this->endPartitionGroup(a);

    return Action::Skip;
}
void DeferredShadingStage::updateStageData(
    DSStageData         *data,
    FrameBufferObject   *shadingTarget,
    RenderPartition     *parentPart    )
{
    FrameBufferObject *gBufferTarget = data->getGBufferTarget();

    Int32 targetWidth;
    Int32 targetHeight;
    Int32 targetLeft;
    Int32 targetBottom;

    if(shadingTarget != NULL)
    {
        targetWidth  = shadingTarget->getWidth ();
        targetHeight = shadingTarget->getHeight();

        targetLeft   = 0;
        targetBottom = 0;
    }
    else
    {
        targetWidth  = parentPart->getDrawEnv().getPixelWidth ();
        targetHeight = parentPart->getDrawEnv().getPixelHeight();

        targetLeft   = parentPart->getDrawEnv().getPixelLeft  ();
        targetBottom = parentPart->getDrawEnv().getPixelBottom();
    }

    if(gBufferTarget->getWidth () != targetWidth ||
       gBufferTarget->getHeight() != targetHeight  )
    {
        _targetSizeChanged = true;
    }

    if(_targetSizeChanged == true)
    {
        gBufferTarget->setSize(targetWidth, targetHeight);
    }

    if(getMFPixelFormats()->size() != getMFPixelTypes()->size())
    {
        SWARNING << "DeferredShadingStage::updateStageData: "
                 << "Number of PixelFormats and PixelTypes inconsistent."
                 << std::endl;
    }

    UInt32 lightCount  =        getMFLights      ()->size();
    UInt32 bufferCount = osgMin(getMFPixelFormats()->size(),
                                getMFPixelTypes  ()->size() );

    // buffers changed - remove them here, recreate below
    if((_changeCache & (PixelFormatsFieldMask |
                        PixelTypesFieldMask    )) != 0)
    {
        gBufferTarget->editMFColorAttachments()->clear (                    );
        gBufferTarget->editMFColorAttachments()->resize(bufferCount, NULL   );
        gBufferTarget->editMFDrawBuffers     ()->clear (                    );
        gBufferTarget->editMFDrawBuffers     ()->resize(bufferCount, GL_NONE);
    }

    for(UInt32 i = 0; i < bufferCount; ++i)
    {
        TextureBuffer *buf =
            dynamic_cast<TextureBuffer *>(gBufferTarget->getColorAttachments(i));

        if(buf == NULL)
        {
            TextureBufferUnrecPtr newBuf =
                createGBuffer(i, targetWidth, targetHeight);
            buf = newBuf;

            gBufferTarget->editMFColorAttachments()->replace(i, newBuf                      );
            gBufferTarget->editMFDrawBuffers     ()->replace(i, GL_COLOR_ATTACHMENT0_EXT + i);
        }
        else
        {
            updateGBuffer(buf, i, targetWidth, targetHeight);
        }
    }

    if((_changeCache & LightsFieldMask) != 0)
    {
        data->editMFLightChunks         ()->resize(    lightCount, NULL);
        data->editMFShadingStates       ()->resize(1 + lightCount, NULL);
        data->editMFShadingProgramChunks()->resize(1 + lightCount, NULL);
    }

    // update shading states
    if((_changeCache & (PixelFormatsFieldMask   |
                        PixelTypesFieldMask     |
                        AmbientProgramFieldMask |
                        LightProgramsFieldMask  |
                        LightsFieldMask          )) != 0)
    {
        // copy ambient and light programs
        DSStageData::MFShadingProgramChunksType::const_iterator spcIt  =
            data->editMFShadingProgramChunks()->begin();
        DSStageData::MFShadingProgramChunksType::const_iterator spcEnd =
            data->editMFShadingProgramChunks()->end  ();

        for(UInt32 progIdx = 0; spcIt != spcEnd; ++spcIt, ++progIdx)
        {
            if(*spcIt == NULL)
            {
                ShaderProgramChunkUnrecPtr newSPC =
                    ShaderProgramChunk::createLocal();
                //*spcIt = newSPC;

                data->editMFShadingProgramChunks()->replace(progIdx, newSPC);
            }

            (*spcIt)->clearVertexShaders  ();
            (*spcIt)->clearGeometryShaders();
            (*spcIt)->clearFragmentShaders();

            if(progIdx == 0 && getAmbientProgram() != NULL)
            {
                // ambient program
                copyProgramChunk(*spcIt, getAmbientProgram());

                // TODO: there must be a better way to add this uniform
                (*spcIt)->getFragmentShader(0)->addUniformVariable(
                    "vpOffset", Vec2f(targetLeft,
                                      targetBottom));
            }
            else
            {
                // light programs
                if(_mfLightPrograms.size() == 1)
                {
                    copyProgramChunk(*spcIt, getLightPrograms(0));

                    // TODO: there must be a better way to add this uniform
                    (*spcIt)->getFragmentShader(0)->addUniformVariable(
                        "vpOffset", Vec2f(targetLeft,
                                          targetBottom));
                }
                else if(_mfLightPrograms.size() == _mfLights.size())
                {
                    copyProgramChunk(*spcIt, getLightPrograms(progIdx - 1));

                    // TODO: there must be a better way to add this uniform
                    (*spcIt)->getFragmentShader(0)->addUniformVariable(
                        "vpOffset", Vec2f(targetLeft,
                                          targetBottom));
                }
                else
                {
                    SWARNING << "DeferredShadingStage::updateStageData: "
                             << "Number of Lights and LightPrograms "
                             << "inconsistent." << std::endl;
                }
            }
        }

        // create light chunks
        DSStageData::MFLightChunksType::const_iterator lcIt  =
            data->editMFLightChunks()->begin();
        DSStageData::MFLightChunksType::const_iterator lcEnd =
            data->editMFLightChunks()->end  ();

        for(UInt32 lightIdx = 0; lcIt != lcEnd; ++lcIt, ++lightIdx)
        {
            if(*lcIt == NULL)
            {
                DSLightChunkUnrecPtr newLC = DSLightChunk::createLocal();
                //*lcIt = newLC;
                data->editMFLightChunks()->replace(lightIdx, newLC);
            }

            updateLightChunk(*lcIt, getLights(lightIdx));
        }

        // populate shading states
        DSStageData::MFShadingStatesType::const_iterator stateIt  =
            data->editMFShadingStates()->begin();
        DSStageData::MFShadingStatesType::const_iterator stateEnd =
            data->editMFShadingStates()->end  ();

        for(UInt32 stateIdx = 0; stateIt != stateEnd; ++stateIt, ++stateIdx)
        {
            if(*stateIt == NULL)
            {
                StateUnrecPtr newState = State::createLocal();
                //*stateIt = newState;
                data->editMFShadingStates()->replace(stateIdx, newState);
            }

            // remove all chunks
            (*stateIt)->clearChunks();

            // add G Buffer textures
            for(UInt32 bufferIdx = 0;
                bufferIdx < bufferCount; ++bufferIdx)
            {
                TextureBuffer   *buf    = static_cast<TextureBuffer *>(
                    gBufferTarget->getColorAttachments(bufferIdx));
                TextureObjChunk *bufTex = buf->getTexture();

                (*stateIt)->addChunk(bufTex, bufferIdx);
            }

            // add ambient/light programs and light chunks
            if(stateIdx == 0)
            {
                if(getAmbientProgram() != NULL)
                {
                    (*stateIt)->addChunk(
                        data->getShadingProgramChunks(stateIdx));
                }
            }
            else
            {
                (*stateIt)->addChunk(
                    data->getShadingProgramChunks(stateIdx    ));
                (*stateIt)->addChunk(
                    data->getLightChunks         (stateIdx - 1));
            }

            // add blend chunk to light states
            if(stateIdx > 0)
            {
                (*stateIt)->addChunk(data->getBlendChunk());
            }
        }
    }

    _changeCache       = TypeTraits<BitVector>::BitsClear;
    _targetSizeChanged = false;
}
void TrapezoidalShadowMapEngine::handlePointLightEnter(
    PointLight *pointL, RenderAction *ract, TSMEngineData *data)
{
    RenderPartition *parentPart = ract->getActivePartition();
    
    Matrixr matEyeToWorld(parentPart->getCameraToWorld());  
    Matrixr matLightProj;

    Real    shadowNear = (getShadowNear() != 0.f ? 
                          getShadowNear()       : 
                          parentPart->getNear()  );
    Real    shadowFar  = (getShadowFar () != 0.f ?
                          getShadowFar ()       :
                          parentPart->getFar()   );

    Inherited::calcPointLightRange(
        pointL, 0.01f,
        shadowNear, shadowFar, shadowNear, shadowFar);

    MatrixPerspective(matLightProj, Pi / 4.f, 1.f,
                      shadowNear, shadowFar       );
    
    Matrixr   matWorldToLight;
    Matrixr   matEyeToLight;
    MFMatrixr mfMatNT;

    mfMatNT.resize(6);

    Inherited::calcPointLightMatrices(matWorldToLight, matEyeToLight,
                                      pointL,          matEyeToWorld );

    Inherited::updatePointLightShadowTexImage  (data);
    Inherited::updatePointLightShadowTexBuffers(data);
    Inherited::updatePointLightRenderTargets   (data);

    Int32          shadowTexUnit = (this->getForceTextureUnit() >= 0) ?
                                    this->getForceTextureUnit()       : 7;
    ShaderProgram *shadowFP      = this->getShadowFragmentProgram();

    if(shadowFP == NULL)
    {
        ShaderProgramUnrecPtr newShadowFP = ShaderProgram::createLocal();
        newShadowFP->setShaderType(GL_FRAGMENT_SHADER);
        newShadowFP->setProgram   (_pointFPCode      );
        
        newShadowFP->addUniformVariable("TSME_matEyeToLight", matEyeToLight);
        newShadowFP->addUniformVariable("TSME_matLightProj",  matLightProj );
        newShadowFP->addUniformVariable("TSME_matNT",         mfMatNT      );
        newShadowFP->addUniformVariable("TSME_texShadow",     shadowTexUnit);
        newShadowFP->addUniformVariable("TSME_texShadowSizeInv",
                                        Vec2f(1.f / getWidth (), 
                                              1.f / getHeight() )          );
        
        this->setShadowFragmentProgram(newShadowFP);
        shadowFP = newShadowFP;
    }
    else
    {
        shadowFP->updateUniformVariable("TSME_matEyeToLight", matEyeToLight);
        shadowFP->updateUniformVariable("TSME_matLightProj",  matLightProj );
    }

    const FrustumVolume &eyeFrust = parentPart->getFrustum();

    for(UInt16 faceIdx = 0; faceIdx < 6; ++faceIdx)
    {
        Matrixr matWorldToLightFace (matWorldToLight         );
        matWorldToLightFace.multLeft(_matCubeFaceInv[faceIdx]);

        Matrixr matLightFull(matWorldToLightFace);
        matLightFull.multLeft(matLightProj);

        FrustumVolume lightFrust;
        Matrixr       matNT;

        lightFrust.setPlanes(matLightFull);

        bool matNTValid = 
            calcTrapezoidalTransform(mfMatNT[faceIdx],
                                     matEyeToWorld,    matLightFull,
                                     eyeFrust,         lightFrust   );

        if(matNTValid == false)
        {
            // setup a minimal partition to clear the cube face

            commitChanges();

            this->pushPartition(ract,
                                RenderPartition::CopyNothing,
                                RenderPartition::SimpleCallback);
            {
                RenderPartition   *part   = ract->getActivePartition(       );
                Window            *win    = ract->getWindow         (       );
                FrameBufferObject *target = data->getRenderTargets  (faceIdx);
                Background        *back   = data->getBackground     (       );

                part->setSetupMode(RenderPartition::ViewportSetup  |
                                   RenderPartition::BackgroundSetup );

                part->setRenderTarget(target);
                part->setWindow      (win   );

                part->calcViewportDimension(0.f, 0.f, 1.f, 1.f,
                                            target->getWidth (),
                                            target->getHeight() );
                
                part->setBackground(back);

                RenderPartition::SimpleDrawCallback emptyCubeFaceDraw =
                    boost::bind(
                        &TrapezoidalShadowMapEngine::emptyCubeFaceDrawFunc,
                        this, _1);

                part->dropFunctor(emptyCubeFaceDraw);
            }
            this->popPartition(ract);
        }
        else
        {
            updateLightPassMaterial(data, faceIdx, mfMatNT[faceIdx]);
        
            commitChanges();

            this->pushPartition(ract);
            {
                RenderPartition   *part   = ract->getActivePartition(       );
                Window            *win    = ract->getWindow         (       );
                FrameBufferObject *target = data->getRenderTargets  (faceIdx);
                Background        *back   = data->getBackground     (       );

                part->setRenderTarget(target);
                part->setWindow      (win   );

                part->calcViewportDimension(0.f, 0.f, 1.f, 1.f,
                                            target->getWidth (),
                                            target->getHeight() );

                part->setupProjection(matLightProj, Matrixr::identity());
                part->setupViewing   (matWorldToLightFace              );

                part->setNear        (parentPart->getNear());
                part->setFar         (parentPart->getFar ());
            
                part->setFrustum     (lightFrust           );
                
                part->setBackground  (back                 );

                part->overrideMaterial(data->getLightPassMaterials(faceIdx),
                                       ract->getActNode           (       ) );

                this->recurseFrom(ract, pointL);
                ract->useNodeList(false       );

                part->overrideMaterial(NULL,
                                       ract->getActNode           (       ) );
            }
            this->popPartition(ract);
        }
    }

    shadowFP->updateUniformVariable("TSME_matNT", mfMatNT);
}
void TrapezoidalShadowMapEngine::handleSpotLightEnter(
    SpotLight *spotL, RenderAction *ract, TSMEngineData *data)
{
    RenderPartition *parentPart = ract->getActivePartition();

    Matrixr matEyeToWorld(parentPart->getCameraToWorld());
    Matrixr matWorldToLight;
    Matrixr matEyeToLight;

    Inherited::calcSpotLightMatrices(matWorldToLight, matEyeToLight,
                                     spotL,           matEyeToWorld );

    Matrixr matLightProj;
    Matrixr matLightFull(matWorldToLight);

    Real    shadowNear = (getShadowNear() != 0.f ? 
                          getShadowNear()       : 
                          parentPart->getNear()  );
    Real    shadowFar  = (getShadowFar () != 0.f ?
                          getShadowFar ()       :
                          parentPart->getFar()   );

    Inherited::calcPointLightRange(
        spotL, 0.01f,
        shadowNear, shadowFar, shadowNear, shadowFar);

    MatrixPerspective(matLightProj,
                      spotL->getSpotCutOff(), 1.f,
                      shadowNear, shadowFar       );

    matLightFull.multLeft(matLightProj);

    Inherited::updateShadowTexImage  (data);
    Inherited::updateShadowTexBuffers(data);
    Inherited::updateRenderTargets   (data);

    const FrustumVolume &eyeFrust   = parentPart->getFrustum();
          FrustumVolume  lightFrust;
          Matrixr        matNT;

    lightFrust.setPlanes(matLightFull);

    bool matNTValid = calcTrapezoidalTransform(matNT,
                                               matEyeToWorld, matLightFull,
                                               eyeFrust,      lightFrust   );

    if(matNTValid == false)
        return;

//    Real           cosSpotCutOff = osgCos(spotL->getSpotCutOff());

    Int32          shadowTexUnit = (this->getForceTextureUnit() >= 0) ?
                                    this->getForceTextureUnit()       : 7;
    ShaderProgram *shadowFP      = this->getShadowFragmentProgram();

    if(shadowFP == NULL)
    {
        ShaderProgramUnrecPtr newShadowFP = ShaderProgram::createLocal();
        newShadowFP->setShaderType(GL_FRAGMENT_SHADER);
        newShadowFP->setProgram   (_spotFPCode       );

        newShadowFP->addUniformVariable("TSME_matEyeToLight", matEyeToLight);
        newShadowFP->addUniformVariable("TSME_matLightProj",  matLightProj );
        newShadowFP->addUniformVariable("TSME_matNT",         matNT        );
        newShadowFP->addUniformVariable("TSME_texShadow",     shadowTexUnit);
        newShadowFP->addUniformVariable("TSME_texShadowSizeInv",
                                        Vec2f(1.f / getWidth (), 
                                              1.f / getHeight() )          );

        this->setShadowFragmentProgram(newShadowFP);
        shadowFP = newShadowFP;
    }
    else
    {
        shadowFP->updateUniformVariable("TSME_matEyeToLight", matEyeToLight);
        shadowFP->updateUniformVariable("TSME_matLightProj",  matLightProj );
        shadowFP->updateUniformVariable("TSME_matNT",         matNT        );
    }

    updateLightPassMaterial(data, 0, matNT);

    commitChanges();
    
    this->pushPartition(ract);
    {
        RenderPartition   *part   = ract->getActivePartition( );
        Window            *win    = ract->getWindow         ( );
        FrameBufferObject *target = data->getRenderTargets  (0);
        Background        *back   = data->getBackground     ( );

        part->setRenderTarget(target);
        part->setWindow      (win   );

        part->calcViewportDimension(0.f, 0.f, 1.f, 1.f,
                                    target->getWidth (),
                                    target->getHeight() );

        part->setupProjection(matLightProj, Matrixr::identity());
        part->setupViewing   (matWorldToLight                  );
        
        part->setNear        (parentPart->getNear());
        part->setFar         (parentPart->getFar ());

        part->setFrustum     (lightFrust           );

        part->setBackground  (back                 );

        part->overrideMaterial(data->getLightPassMaterials(0),
                               ract->getActNode           ( ) );

        this->recurseFrom(ract, spotL);
        ract->useNodeList(false      );

        part->overrideMaterial(NULL,
                               ract->getActNode           ( ) );
    }
    this->popPartition(ract);
}
Ejemplo n.º 12
0
void VRShadowEngine::doFinalPass(Light         *pLight,
                                        RenderAction  *pAction,
                                        EngineDataPtr  pEngineData)
{
    this->pushPartition(pAction,
                        (RenderPartition::CopyViewing      |
                         RenderPartition::CopyProjection   |
                         RenderPartition::CopyWindow       |
                         RenderPartition::CopyViewportSize |
                         RenderPartition::CopyFrustum      |
                         RenderPartition::CopyNearFar      ));

    FrameBufferObject *pTarget = pEngineData->getRenderTarget();

    if(pTarget == NULL)
    {
        FrameBufferObjectUnrecPtr pFBO = FrameBufferObject::createLocal();

        pFBO->setWidth (this->getWidth ());
        pFBO->setHeight(this->getHeight());

        pEngineData->setRenderTarget(pFBO);

        pTarget = pFBO;
    }

    BlendChunkUnrecPtr pBlender      = pEngineData->getBlendChunk();

    if(pBlender == NULL)
    {
        pBlender = BlendChunk::createLocal();

        pBlender->setSrcFactor(GL_ONE);
        pBlender->setDestFactor(GL_ONE);
        pBlender->setAlphaFunc(GL_GEQUAL);
        pBlender->setAlphaValue(0.99f);

        pEngineData->setBlendChunk(pBlender);
    }


    Matrix4f projectionMatrix, viewMatrix, biasMatrix;

    biasMatrix.setIdentity();
    biasMatrix.setScale(0.5);
    biasMatrix.setTranslate(0.5,0.5,0.5);

    MatrixCamera *pCam = dynamic_cast<MatrixCamera *>(pEngineData->getCamera());
    pCam->getProjection(projectionMatrix, this->getWidth (), this->getHeight());
    pCam->getViewing(viewMatrix, this->getWidth (), this->getHeight());

    Matrix textureMatrix = biasMatrix;
    textureMatrix.mult(projectionMatrix);
    textureMatrix.mult(viewMatrix);

    textureMatrix.transpose();
    Vec4f ps = textureMatrix[0];
    Vec4f pt = textureMatrix[1];
    Vec4f pr = textureMatrix[2];
    Vec4f pq = textureMatrix[3];

    TexGenChunkUnrecPtr pTexGen = pEngineData->getTexGenChunk();

    if(pTexGen == NULL)
    {
        pTexGen = TexGenChunk::createLocal();

        pEngineData->setTexGenChunk(pTexGen);

        pTexGen->setEyeModelViewMode(TexGenChunk::EyeModelViewCamera);

        pTexGen->setGenFuncS(GL_EYE_LINEAR);
        pTexGen->setGenFuncT(GL_EYE_LINEAR);
        pTexGen->setGenFuncR(GL_EYE_LINEAR);
        pTexGen->setGenFuncQ(GL_EYE_LINEAR);
    }

    pTexGen->setGenFuncSPlane(ps);
    pTexGen->setGenFuncTPlane(pt);
    pTexGen->setGenFuncRPlane(pr);
    pTexGen->setGenFuncQPlane(pq);

    TextureObjChunkUnrecPtr pTexChunk = pEngineData->getTexChunk();

    if(pTexChunk == NULL)
    {
        pTexChunk = TextureObjChunk::createLocal();

        pEngineData->setTexChunk(pTexChunk);

        ImageUnrecPtr pImage = Image::createLocal();

            // creates a image without allocating main memory.

        pImage->set(Image::OSG_L_PF,
                    pTarget->getWidth (), pTarget->getHeight(), 1,
                    1, 1, 0, NULL,
                    Image::OSG_UINT8_IMAGEDATA, false);


        pTexChunk->setImage         (pImage);
        pTexChunk->setInternalFormat(GL_DEPTH_COMPONENT32);
        pTexChunk->setExternalFormat(GL_DEPTH_COMPONENT);
        pTexChunk->setMinFilter     (GL_LINEAR); // tried GL_LINEAR_MIPMAP_LINEAR
        pTexChunk->setMagFilter     (GL_LINEAR);
        pTexChunk->setWrapS         (GL_CLAMP_TO_EDGE); // was GL_CLAMP_TO_BORDER
        pTexChunk->setWrapT         (GL_CLAMP_TO_EDGE); // was GL_CLAMP_TO_BORDER
//        pTexChunk->setEnvMode       (GL_MODULATE);
        pTexChunk->setTarget        (GL_TEXTURE_2D);

        pTexChunk->setCompareMode(GL_COMPARE_R_TO_TEXTURE);
        pTexChunk->setCompareFunc(GL_LEQUAL);
        pTexChunk->setDepthMode  (GL_INTENSITY);
    }

    pAction->pushState();

    UInt32 uiBlendSlot  = pBlender ->getClassId();
    UInt32 uiTexSlot    = pTexChunk->getClassId();
    UInt32 uiTexGenSlot = pTexGen  ->getClassId();

    if(this->getForceTextureUnit() != -1)
    {
        uiTexSlot    += this->getForceTextureUnit();
        uiTexGenSlot += this->getForceTextureUnit();
    }
    else
    {
        uiTexSlot    += 3;
        uiTexGenSlot += 3;
    }

    pAction->addOverride(uiBlendSlot,  pBlender );
    pAction->addOverride(uiTexSlot,    pTexChunk);
    pAction->addOverride(uiTexGenSlot, pTexGen  );

    lightRenderEnter(pLight, pAction);

    pAction->useNodeList(false);

    this->recurseFrom(pAction, pLight);

    pAction->popState();

    this->popPartition(pAction);
}
Ejemplo n.º 13
0
void VRShadowEngine::doLightPass(Light         *pLight,
                                        RenderAction  *pAction,
                                        EngineDataPtr  pEngineData)
{
    this->pushPartition(pAction);

    RenderPartition   *pPart   = pAction    ->getActivePartition();
    Viewarea          *pArea   = pAction    ->getViewarea       ();
    Background        *pBack   = pAction    ->getBackground     ();

    FrameBufferObject *pTarget = pEngineData->getRenderTarget();

    if(pTarget == NULL)
    {
        FrameBufferObjectUnrecPtr pFBO = FrameBufferObject::createLocal();

        pFBO->setWidth (this->getWidth ());
        pFBO->setHeight(this->getHeight());

        pEngineData->setRenderTarget(pFBO);

        pTarget = pFBO;
    }

    TextureObjChunk       *pTexChunk  = pEngineData->getTexChunk();


    TextureBufferUnrecPtr  pTexBuffer = pEngineData->getTexBuffer();

    if(pTexBuffer == NULL)
    {
        pTexBuffer = TextureBuffer::createLocal();

        pEngineData->setTexBuffer     (pTexBuffer);

        pTexBuffer->setTexture        (pTexChunk );
        pTarget   ->setDepthAttachment(pTexBuffer);
    }

    PolygonChunkUnrecPtr pPoly = pEngineData->getPolyChunk();

    if(pPoly == NULL)
    {
        pPoly = PolygonChunk::createLocal();

        pPoly->setOffsetBias  (this->getOffsetBias  ());
        pPoly->setOffsetFactor(this->getOffsetFactor());
        pPoly->setOffsetFill  (true                   );

        pEngineData->setPolyChunk(pPoly);
    }

    pPart->setRenderTarget(pTarget);

    if(pArea != NULL)
    {
        Camera *pCam = pEngineData->getCamera();

        pPart->setWindow  (pAction->getWindow());

        pPart->calcViewportDimension(0.f, 0.f, 1.f, 1.f,
                                     pTarget->getWidth    (),
                                     pTarget->getHeight   ());

        Matrix m, t;

        // set the projection
        pCam->getProjection          (m,
                                      pPart->getViewportWidth (),
                                      pPart->getViewportHeight());

        pCam->getProjectionTranslation(t,
                                       pPart->getViewportWidth (),
                                       pPart->getViewportHeight());


        pPart->setupProjection(m, t);

        pCam->getViewing(m,
                         pPart->getViewportWidth (),
                         pPart->getViewportHeight());


        pPart->setupViewing(m);

        pPart->setNear     (pCam->getNear());
        pPart->setFar      (pCam->getFar ());

        pPart->calcFrustum ();

        pPart->setBackground(pBack);
    }

    Node *pActNode = pAction->getActNode();

    pAction->overrideMaterial(_pLightPassMat, pActNode);

    pAction->pushState();

    UInt32 uiPolySlot  = pPoly->getClassId();

    pAction->addOverride     (uiPolySlot,     pPoly);

//    lightRenderEnter(pLight, pAction);

    pAction->useNodeList(false);

    this->recurseFrom(pAction, pLight);

    pAction->popState();

    pAction->overrideMaterial(NULL, pActNode);

    this->popPartition(pAction);
}
Action::ResultE DisplayFilterStage::renderEnter(Action *action)
{
    RenderAction *ract = dynamic_cast<RenderAction *>(action);

    if(ract == NULL)
        return Action::Continue;

    DisplayFilterStageDataUnrecPtr pData = 
        ract->getData<DisplayFilterStageData *>(_iDataSlotId);

    DrawEnv &oEnv = ract->getActivePartition()->getDrawEnv();

    bool                      bFilterActive = false;
    RenderPartition::Mode     partMode      = RenderPartition::StateSorting;

    CalibrationPatternFilter *pCalibFilter  = NULL;
    ResolutionDisplayFilter  *pResFilter    = NULL;
    DistortionDisplayFilter  *pDistFilter   = NULL;
    ColorDisplayFilter       *pColFilter    = NULL;
    bool                      bDoDraw       = true;

    if(_mfFilterGroups.size() == 0)
    {
        pCalibFilter = this->getCalibrationPatternFilter();

        pResFilter   = this->getResolutionFilter();

        pColFilter   = this->getColorFilter();

        pDistFilter  = this->getDistortionFilter();

    }
    else
    {
        // Linear search, optimize of needed

        MFFilterGroupsType::const_iterator gIt  = _mfFilterGroups.begin();
        MFFilterGroupsType::const_iterator gEnd = _mfFilterGroups.end  ();

        for(; gIt != gEnd; ++gIt)
        {
            if((*gIt)->matches(oEnv.getDrawerId(),
                               oEnv.getDrawableId()) == true)
            {
                pCalibFilter = (*gIt)->getCalibrationPatternFilter();

                pResFilter   = (*gIt)->getResolutionFilter();

                pColFilter   = (*gIt)->getColorFilter();

                pDistFilter  = (*gIt)->getDistortionFilter();
                
                bDoDraw = 
                    ((*gIt)->matches(this->getActiveGroup(),
                                     oEnv. getDrawableId ()) == true) ||
                     (this->getActiveGroup()                == -1   )  ;

                break;
            }
        }
    }


    if(pCalibFilter != NULL && pCalibFilter->getEnabled() == true)
    {
        if(pData != NULL)
            pData->setCalibFilter(pCalibFilter);
            
        bFilterActive = true;
        partMode      = RenderPartition::SimpleCallback;
    }
    else
    {
        if(pData != NULL)
            pData->setCalibFilter(NULL);
    }

    if(pColFilter               != NULL &&
       pColFilter->getEnabled() == true  )
    {
        if(pData != NULL)
            pData->setColFilter(pColFilter);
        
        bFilterActive = true;
    }
    else
    {
        if(pData != NULL)
        {
            pData->setColFilter(NULL);
            
            ColorDisplayFilter::deactivate(pData);
        }
    }        
    if(pDistFilter               != NULL &&
       pDistFilter->getEnabled() == true  )
    {
        if(pData != NULL)
            pData->setDistFilter(pDistFilter);

        bFilterActive = true;
    }
    else
    {
        if(pData != NULL)
            pData->setDistFilter(NULL);
    }

    
    UInt32 uiTargetWidth  = oEnv.getPixelWidth ();
    UInt32 uiTargetHeight = oEnv.getPixelHeight();

    Int32 iLeft   = oEnv.getPixelLeft  ();
    Int32 iRight  = oEnv.getPixelRight ();
    Int32 iBottom = oEnv.getPixelBottom();
    Int32 iTop    = oEnv.getPixelTop   ();

    if(pResFilter               != NULL &&
       pResFilter->getEnabled() == true  )
    {
        bFilterActive = true;
        
        uiTargetWidth  = UInt32(uiTargetWidth  * pResFilter->getDownScale());
        uiTargetHeight = UInt32(uiTargetHeight * pResFilter->getDownScale());

        iLeft   = Int32(iLeft   * pResFilter->getDownScale());
        iRight  = Int32(iRight  * pResFilter->getDownScale());
        iBottom = Int32(iBottom * pResFilter->getDownScale());
        iTop    = Int32(iTop    * pResFilter->getDownScale());
        
    }

    if(pData == NULL)
    {
        pData = setupStageData(uiTargetWidth,
                               uiTargetHeight);

        if(pData == NULL)
            return Action::Continue;

        this->setData(pData, _iDataSlotId, ract);

        pData->setColFilter  (pColFilter  );
        pData->setDistFilter (pDistFilter );
        pData->setCalibFilter(pCalibFilter);
    }


    if((pData->getWidth () != uiTargetWidth ) ||
       (pData->getHeight() != uiTargetHeight)  )
    {
        resizeStageData(pData, uiTargetWidth, uiTargetHeight);
    }

   


    if(bFilterActive == false)
        return Action::Continue;

    ract->disableDefaultPartition();

    this->beginPartitionGroup(ract);
    {
        this->pushPartition(ract, 0x0000, partMode);
        {
            RenderPartition   *pPart    = ract ->getActivePartition();
            FrameBufferObject *pTarget  = pData->getTarget();
            Viewarea          *pArea    = ract ->getViewarea();
            Camera            *pCam     = ract ->getCamera  ();
            Background        *pBack    = ract ->getBackground();
            

            pPart->setRenderTarget(pTarget);
            
            if(pArea != NULL)
            {
                pPart->setWindow(ract->getWindow());
                
                if(pTarget != NULL)
                {
                    pPart->calcViewportDimension(iLeft  ,
                                                 iBottom,
                                                 iRight ,
                                                 iTop   ,
                                                 
                                                 pTarget->getWidth    (),
                                                 pTarget->getHeight   ());
                }
                else
                {
                    pPart->calcViewportDimension(
                        pArea->getLeft  (),
                        pArea->getBottom(),
                        pArea->getRight (),
                        pArea->getTop   (),
                        
                        ract->getWindow()->getWidth (),
                        ract->getWindow()->getHeight());
                }
                
                if(pCam != NULL)
                {
                    Matrix m, t;
                    
                    // set the projection
                    pCam->getProjection          (m, 
                                                  pPart->getViewportWidth (), 
                                                  pPart->getViewportHeight());
                    
                    pCam->getProjectionTranslation(t, 
                                                   pPart->getViewportWidth (), 
                                                   pPart->getViewportHeight());
                    
                    pPart->setupProjection(m, t);
                    
                    pCam->getViewing(m, 
                                     pPart->getViewportWidth (),
                                     pPart->getViewportHeight());
                    
                    
                    pPart->setupViewing(m);
                    
                    pPart->setNear     (pCam->getNear());
                    pPart->setFar      (pCam->getFar ());
                    
                    pPart->calcFrustum();
                }
                
                pPart->setBackground(pBack);
            }

            if(pCalibFilter != NULL && pCalibFilter->getEnabled() == true)
            {
                RenderPartition::SimpleDrawCallback f;

                if(bDoDraw == true)
                {
                    f = boost::bind(&DisplayFilterStage::processCalibActive, 
                                    this, _1);
                }
                else
                {
                    f = boost::bind(&DisplayFilterStage::processCalibInactive, 
                                    this, _1);
                }

                pPart->dropFunctor(f);
            }
            else
            {
                MFForegroundsType::const_iterator fIt = 
                    this->getMFForegrounds()->begin();
                MFForegroundsType::const_iterator fEnd = 
                    this->getMFForegrounds()->end  ();

                for(; fIt != fEnd; ++fIt)
                {
                    pPart->pushToForegrounds(*fIt);
                }

                this->recurseFromThis(ract);
            }
        }
        this->popPartition(ract);
        
        this->pushPartition(ract,
                            (RenderPartition::CopyWindow      |
                             RenderPartition::CopyViewportSize),
                            RenderPartition::SimpleCallback);
        {
            RenderPartition *pPart  = ract->getActivePartition();

            Matrix m, t;
                
            m.setIdentity();
            t.setIdentity();
                
            MatrixOrthogonal( m,
                              0.f, 1.f,
                              0.f, 1.f,
                             -1.f, 1.f);
            
            pPart->setupProjection(m, t);
                
            RenderPartition::SimpleDrawCallback f;
                
            f = boost::bind(&DisplayFilterStage::postProcess, this, _1);
                
            pPart->dropFunctor(f);
        }
        this->popPartition(ract);
    }
    this->endPartitionGroup(ract);

    return Action::Skip;
}
Ejemplo n.º 15
0
Action::ResultE Stage::renderEnter(Action *action)
{
    RenderAction *a = dynamic_cast<RenderAction *>(action);

    if(a == NULL)
        return Action::Continue;

    RenderPartition   *pParentPart = a->getActivePartition();
    FrameBufferObject *pTarget     = this->getRenderTarget();

    if(pTarget == NULL && this->getInheritedTarget() == true)
    {
        pTarget = pParentPart->getRenderTarget();
    }

    this->pushPartition(a);

    RenderPartition   *pPart    = a->getActivePartition();
    Viewarea          *pArea    = a->getViewarea();
    Camera            *pCam     = a->getCamera  ();
    Background        *pBack    = a->getBackground();
    
    pPart->setRenderTarget(pTarget);

    if(pArea != NULL)
    {
        pPart->setWindow  (a->getWindow());
            
        if(pTarget != NULL)
        {
            pPart->calcViewportDimension(pArea->getLeft  (),
                                         pArea->getBottom(),
                                         pArea->getRight (),
                                         pArea->getTop   (),
                                         
                                         pTarget->getWidth    (),
                                         pTarget->getHeight   ());
        }
        else
        {
            pPart->calcViewportDimension(pArea->getLeft  (),
                                         pArea->getBottom(),
                                         pArea->getRight (),
                                         pArea->getTop   (),
                                         
                                         a->getWindow()->getWidth (),
                                         a->getWindow()->getHeight());
        }
        
        if(pCam != NULL)
        {
            Matrix m, t;
            
            // set the projection
            pCam->getProjection          (m, 
                                          pPart->getViewportWidth (), 
                                          pPart->getViewportHeight());
            
            pCam->getProjectionTranslation(t, 
                                           pPart->getViewportWidth (), 
                                           pPart->getViewportHeight());
                
            pPart->setupProjection(m, t);
            
            pCam->getViewing(m, 
                             pPart->getViewportWidth (),
                             pPart->getViewportHeight());
            
            
            pPart->setupViewing(m);
            
            pPart->setNear     (pCam->getNear());
            pPart->setFar      (pCam->getFar ());
            
            pPart->calcFrustum();
        }
    }

    pPart->setBackground(pBack);

    return Action::Continue;
}
ActionBase::ResultE GroupingStage::renderEnter(Action *action)
{
    RenderAction *a = dynamic_cast<RenderAction *>(action);

    if(a == NULL)
        return ActionBase::Continue;

#if 0
    RenderPartition   *pParentPart = a   ->getActivePartition();
    FrameBufferObject *pTarget     = pParentPart->getRenderTarget();
#endif

    this->pushPartition(a, RenderPartition::CopyAll);

    RenderPartition   *pPart   = a->getActivePartition();

    Inherited::addCallbacks(pPart);

#if 0
    RenderPartition   *pParentPart = a   ->getActivePartition();
    FrameBufferObject *pTarget     = this->getRenderTarget();

    Background        *pBack   = this->getBackground();
    Viewport          *pPort   = a->getViewport();
    Window            *pWin    = a->getWindow  ();


    if(pTarget == NULL && this->getInheritedTarget() == true)
    {
        pTarget = pParentPart->getRenderTarget();
    }

    
    RenderPartition   *pPart   = a->getActivePartition();
    Camera            *pCam    = this->getCamera();
    
    pPart->setRenderTarget(pTarget);
    
//    pPart->setViewport(pPort);
    pPart->setWindow  (pWin );
    
    if(pTarget != NULL)
    {
        pPart->calcViewportDimension(this->getLeft  (),
                                     this->getBottom(),
                                     this->getRight (),
                                     this->getTop   (),
                                     
                                     pTarget->getWidth    (),
                                     pTarget->getHeight   ());
    }
    else if(pWin != NULL)
    {
        pPart->calcViewportDimension(this->getLeft  (),
                                     this->getBottom(),
                                     this->getRight (),
                                     this->getTop   (),
                                     
                                     pWin->getWidth   (),
                                     pWin->getHeight  ());
    }
    
    if(pCam != NULL)
    {
        Matrix m, t;
        
        // set the projection
        pCam->getProjection          (m, 
                                      pPart->getViewportWidth (), 
                                      pPart->getViewportHeight());
        
        pCam->getProjectionTranslation(t, 
                                       pPart->getViewportWidth (), 
                                       pPart->getViewportHeight());
        
        pPart->setupProjection(m, t);
        
        pCam->getViewing(m, 
                         pPart->getViewportWidth (),
                         pPart->getViewportHeight());
        
        
        pPart->setupViewing(m              );
        
        pPart->setNear     (pCam->getNear());
        pPart->setFar      (pCam->getFar ());
        
        pPart->calcFrustum (               );
        
    }
    
    this->fillPreRenderStore(vCallbackStore);

    GroupingStage::RenderFunctorStore::const_iterator cbIt  = 
        vCallbackStore.begin();

    GroupingStage::RenderFunctorStore::const_iterator cbEnd = 
        vCallbackStore.end  ();

    while(cbIt != cbEnd)
    {
        pPart->addPreRenderCallback(*cbIt);
        
        ++cbIt;
    }


    vCallbackStore.clear();

    this->fillPostRenderStore(vCallbackStore);

    cbIt  = vCallbackStore.begin();
    cbEnd = vCallbackStore.end  ();

    while(cbIt != cbEnd)
    {
        pPart->addPostRenderCallback(*cbIt);
        
        ++cbIt;
    }


    pPart->setBackground(pBack);
#endif

    return ActionBase::Continue;
}