void PCSSShadowMapHandler::createColorMapFBO(RenderAction *a,
                                             DrawEnv      *pEnv)
{
    _pStage->pushPartition(a,
                           (RenderPartition::CopyWindow      |
                            RenderPartition::CopyViewing     |
                            RenderPartition::CopyProjection  |
                            RenderPartition::CopyFrustum     |
                            RenderPartition::CopyNearFar     |
                            RenderPartition::CopyViewportSize),
                           RenderPartition::StateSorting);
    {
        RenderPartition *pPart = a->getActivePartition();

        pPart->addPreRenderCallback (&ShadowTreeHandler::setupAmbientModel);
        pPart->addPostRenderCallback(&ShadowTreeHandler::endAmbientModel  );

        pPart->setRenderTarget(_pSceneFBO);
        pPart->setDrawBuffer  (GL_COLOR_ATTACHMENT0_EXT);

        Node *parent = a->getActNode()->getParent();

        if(parent != NULL)
        {
            a->pushMatrix(parent->getToWorld());
        }
        
        pPart->setBackground(a->getBackground());

        _pStage->recurseFromThis(a);

        if(parent != NULL)
        {
            a->popMatrix();
        }

        if(_pStage->getBlitZBuffer() == true)
        {
            pPart->addPostRenderCallback(&ShadowTreeHandler::blitZBufferCB);
        }
    }
    _pStage->popPartition(a);
}
void PCSSShadowMapHandler::createShadowMapsFBO(RenderAction *a,
                                               DrawEnv      *pEnv)
{
    // disable all lights more speed
    std::vector<bool> vLocalLightStates;

    const ShadowStageData::LightStore    &vLights      =
        _pStageData->getLights();

    const ShadowStageData::LStateStore   &vLightStates =
        _pStageData->getLightStates();

    const ShadowStageData::CamStore      &vLCams       =
        _pStageData->getLightCameras();

    const ShadowStageData::TravMaskStore &vExclTravMask =
        _pStageData->getExcludeNodeTravMask();

    for(UInt32 i = 0;i < vLights.size();++i)
    {
        // store old states.
        vLocalLightStates.push_back(vLights[i].second->getOn());

        vLights[i].second->setOn(false);
    }

    // deactivate exclude nodes:
    for(UInt32 i = 0;i < _pStage->getMFExcludeNodes()->size();++i)
    {
        Node *exnode = _pStage->getExcludeNodes(i);

        if(exnode != NULL)
            exnode->setTravMask(0);
    }

    ShadowStageData::ShadowMapStore &vShadowMaps = _pStageData->getShadowMaps();

    for(UInt32 i = 0;i < vLights.size();++i)
    {
        if(vLightStates[i] != 0)
        {
            if(_pStage->getGlobalShadowIntensity() != 0.0 ||
               vLights[i].second->getShadowIntensity() != 0.0)
            {
                _pStage->pushPartition(a);
                {
                    RenderPartition   *pPart    = a->getActivePartition();

                    pPart->addPreRenderCallback(
                        &ShadowTreeHandler::setupAmbientModelAndMasks);
                    pPart->addPostRenderCallback(
                        &ShadowTreeHandler::endAmbientModelAndMasks);
                    
                    pPart->setRenderTarget(vShadowMaps[i].pFBO);
                    
                    pPart->setWindow  (a->getWindow());
                    
                    pPart->calcViewportDimension(0.f,
                                                 0.f,
                                                 _pStage->getMapSize()-1,
                                                 _pStage->getMapSize()-1,
                                                 
                                                 _pStage->getMapSize(),
                                                 _pStage->getMapSize() );
                    
                    
                    Matrix m, t;
                    
                    // set the projection
                    vLCams[i]->getProjection(
                        m, 
                        pPart->getViewportWidth (), 
                        pPart->getViewportHeight());
                    
                    vLCams[i]->getProjectionTranslation(
                        t, 
                        pPart->getViewportWidth (), 
                        pPart->getViewportHeight());
                    
                    pPart->setupProjection(m, t);
                    
                    vLCams[i]->getViewing(
                        m, 
                        pPart->getViewportWidth (),
                        pPart->getViewportHeight());
                    
                    
                    pPart->setupViewing(m);
                    
                    pPart->setNear     (vLCams[i]->getNear());
                    pPart->setFar      (vLCams[i]->getFar ());
                    
                    pPart->calcFrustum();
                    
                    pPart->setBackground(_pClearSMapBack);
                    
                    Node *light  = vLights[i].first;
                    Node *parent = light->getParent();
                    
                    if(parent != NULL)
                    {
                        a->pushMatrix(parent->getToWorld());
                    }
                    
                    
                    a->overrideMaterial(_unlitMat, a->getActNode());
                    _pStage->recurse(a, light);
                    a->overrideMaterial( NULL,       a->getActNode());
                    
                    if(parent != NULL)
                    {
                        a->popMatrix();
                    }
                }
                _pStage->popPartition(a);
            }
        }
    }

    //-------Restoring old states of Window and Viewport----------
    // enable all lights.
    for(UInt32 i = 0;i < vLights.size();++i)
    {
        // restore old states.
        vLights[i].second->setOn(vLocalLightStates[i]);
    }

    // activate exclude nodes:
    for(UInt32 i = 0;i < _pStage->getMFExcludeNodes()->size();++i)
    {
        Node *exnode = _pStage->getExcludeNodes(i);
        if(exnode != NULL)
        {
            exnode->setTravMask(vExclTravMask[i]);
        }
    }
}
void PCSSShadowMapHandler::createShadowFactorMapFBO(
    RenderAction *a,
    DrawEnv      *pEnv,
    UInt32        num,
    UInt32        uiActiveLightCount)
{
    //Finde alle aktiven Lichtquellen

    Real32  activeLights = 0;

    const ShadowStageData::LightStore  &vLights      = 
        _pStageData->getLights();

    const ShadowStageData::LStateStore &vLightStates = 
        _pStageData->getLightStates();

    const ShadowStageData::CamStore    &vLCams       =
        _pStageData->getLightCameras();


    if(_pStage->getGlobalShadowIntensity() != 0.0)
    {
        for(UInt32 i = 0;i < vLights.size();i++)
        {
            if(vLightStates[i] != 0)
                activeLights++;
        }
    }
    else
    {
        for(UInt32 i = 0;i < vLights.size();i++)
        {
            if(vLightStates[i]                         != 0 &&
               vLights[i].second->getShadowIntensity() != 0.0)
            {
                activeLights++;
            }
        }
    }

    Real32  shadowIntensity;

    if(_pStage->getGlobalShadowIntensity() != 0.0)
    {
        shadowIntensity = (_pStage->getGlobalShadowIntensity() /
                           activeLights);
    }
    else
    {
        shadowIntensity = 
            (vLights[num].second->getShadowIntensity() /
             activeLights);
    }

    if(vLights[num].second->getShadowIntensity() != 0.0 ||
       _pStage->getGlobalShadowIntensity()     != 0.0)
    {

        Matrix  LVM, LPM, CVM;

        vLCams[num]->getViewing(
            LVM,
            pEnv->getPixelWidth(),
            pEnv->getPixelHeight());

        vLCams[num]->getProjection(
            LPM,
            pEnv->getPixelWidth(),
            pEnv->getPixelHeight());

        CVM = pEnv->getCameraViewing();

        Matrix  iCVM = CVM;
        iCVM.invert();

        Real32  texFactor;

        if(vLights[num].second->getType() == SpotLight::getClassType () ||
           vLights[num].second->getType() == PointLight::getClassType()  )
        {
            texFactor = Real32(_width) / Real32(_height);
        }
        else
        {
            texFactor = 1.0;
        }

        Matrix  shadowMatrix = LPM;
        shadowMatrix.mult(LVM);
        shadowMatrix.mult(iCVM);

        Real32  xFactor = 1.0;
        Real32  yFactor = 1.0;

        Real32  lightSize;

        if(vLights[num].second->getType() != DirectionalLight::getClassType())
        {
            lightSize = _pStage->getShadowSmoothness() * 10.0;
        }
        else
        {
            lightSize = _pStage->getShadowSmoothness() / 25.0;
        }

        if(_vShadowCmat.size() == uiActiveLightCount)
        {
            _vShadowCmat.push_back(ChunkMaterial::createLocal());
        }
        
        OSG_ASSERT( uiActiveLightCount < _vShadowCmat.size());

        if(_vShadowSHLVar.size() == uiActiveLightCount)
        {
            _vShadowSHLVar.push_back(SimpleSHLVariableChunk::createLocal());
        }

        _shadowSHL->addUniformVariable("shadowMap",    0);
        _shadowSHL->addUniformVariable("oldFactorMap", 1);

        _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
            "firstRun", (uiActiveLightCount == 0) ? Int32(1) : Int32(0));

        _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
            "intensity", shadowIntensity);

        _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
            "texFactor", texFactor);

        _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
            "lightPM", shadowMatrix);

        _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
            "mapSize",
            Real32(_pStage->getMapSize()));

        _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
            "lightSize", Real32(lightSize));

        _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
            "xFactor", Real32(xFactor));

        _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
            "yFactor", Real32(yFactor));


        ShadowStageData::ShadowMapStore &vShadowMaps = 
            _pStageData->getShadowMaps();


        _vShadowCmat[uiActiveLightCount]->clearChunks();

        _vShadowCmat[uiActiveLightCount]->addChunk(
            _shadowSHL);

        _vShadowCmat[uiActiveLightCount]->addChunk(
            _vShadowSHLVar[uiActiveLightCount]);

        _vShadowCmat[uiActiveLightCount]->addChunk(
            vShadowMaps[num].pTexO);

        _vShadowCmat[uiActiveLightCount]->addChunk(
            vShadowMaps[num].pTexE);

        _vShadowCmat[uiActiveLightCount]->addChunk(
            _shadowFactorMapO);

        _pStage->pushPartition(a,
                               (RenderPartition::CopyWindow      |
                                RenderPartition::CopyViewing     |
                                RenderPartition::CopyProjection  |
                                RenderPartition::CopyFrustum     |
                                RenderPartition::CopyNearFar     |
                                RenderPartition::CopyViewportSize),
                               RenderPartition::StateSorting);
        {
            RenderPartition *pPart = a->getActivePartition();

            pPart->addPreRenderCallback (&ShadowTreeHandler::setupAmbientModel);
            pPart->addPostRenderCallback(&ShadowTreeHandler::endAmbientModel  );

            pPart->setRenderTarget(_pShadowFactorFBO);
            pPart->setDrawBuffer  (GL_COLOR_ATTACHMENT1_EXT);
            
            Node *light  = vLights[num].first;
            Node *parent = light->getParent();
            
            if(parent != NULL)
            {
                a->pushMatrix(parent->getToWorld());
            }

            if(uiActiveLightCount == 0)
            {
                pPart->setBackground(_pClearBackground);
            }
                           
            commitChanges();

            a->overrideMaterial(_vShadowCmat[uiActiveLightCount], 
                                 a->getActNode());
            _pStage->recurse(a, light);
            a->overrideMaterial( NULL,                    
                                 a->getActNode());
            
            if(parent != NULL)
            {
                a->popMatrix();
            }
        }
        _pStage->popPartition(a);

        _firstRun = 0;
    }
}
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);
}
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;
}
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);
    }
}
Beispiel #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;
}
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;
}
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);
}
ActionBase::ResultE CubeMapGenerator::renderEnter(Action *action)
{
    static Matrix transforms[] = 
    { 
        Matrix( 1,  0,  0,  0,
                0, -1,  0,  0,
                0,  0, -1,  0,
                0,  0,  0,  1),
        
        Matrix(-1,  0,  0,  0,
                0, -1,  0,  0,
                0,  0,  1,  0,
                0,  0,  0,  1),
        
        Matrix( 1,  0,  0,  0,
                0,  0, -1,  0,
                0,  1,  0,  0,
                0,  0,  0,  1),
        
        Matrix( 1,  0,  0,  0,
                0,  0,  1,  0,
                0, -1,  0,  0,
                0,  0,  0,  1),
        
        Matrix( 0,  0, -1,  0,
                0, -1,  0,  0,
               -1,  0,  0,  0,
                0,  0,  0,  1),
        
        Matrix( 0,  0,  1,  0,
                0, -1,  0,  0,
                1,  0,  0,  0,
                0,  0,  0,  1)
    };

    RenderAction *a = dynamic_cast<RenderAction *>(action);

    Action::ResultE  returnValue = Action::Continue;

    Background      *pBack    = a->getBackground();

    Viewport        *pPort    = a->getViewport();

    Node            *pActNode = a->getActNode();

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

    if(pData == NULL)
    {
        pData = this->initData(a);
    }

    TraversalValidator::ValidationStatus eStatus = this->validateOnEnter(a);

    if(eStatus == TraversalValidator::Run)
    {
        this->beginPartitionGroup(a);
        {
            FrameBufferObject *pTarget  = this->getRenderTarget();
                
            if(pTarget == NULL)
            {
                pTarget  = pData->getRenderTarget();
            }

            Pnt3f oOrigin;

            if(this->getOriginMode() == CubeMapGenerator::UseStoredValue)
            {
                oOrigin = this->getOrigin();
            }
            else if(this->getOriginMode() == CubeMapGenerator::UseBeacon)
            {
                fprintf(stderr, "CubemapGen::UseBeacon NYI\n");
            }
            else if(this->getOriginMode() == 
                                       CubeMapGenerator::UseCurrentVolumeCenter)
            {
                BoxVolume oWorldVol;

                commitChanges();

                pActNode->updateVolume();
                
                pActNode->getWorldVolume(oWorldVol);
                
                oWorldVol.getCenter(oOrigin);
            }
            else if(this->getOriginMode() == 
                                       CubeMapGenerator::UseParentsVolumeCenter)
            {
                fprintf(stderr, "CubemapGen::UseParentsCenter NYI\n");
            }

            Camera *pCam = pData->getCamera();

            pActNode->setTravMask(0);

            for(UInt32 i = 0; i < 6; ++i)
            {
                this->pushPartition(a);
                {
                    RenderPartition   *pPart    = a->getActivePartition();
                
                    pPart->setVolumeDrawing(false);

                    pPart->setRenderTarget(pTarget       );
                    pPart->setWindow      (a->getWindow());

                    pPart->calcViewportDimension(0,
                                                 0,
                                                 1,
                                                 1,
                                                 this->getWidth (),
                                                 this->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);
            
                    m = transforms[i];
            
                    m[3][0] = oOrigin[0];
                    m[3][1] = oOrigin[1];
                    m[3][2] = oOrigin[2];

                    m.invert();

                    pPart->setupViewing(m);
            
                    pPart->setNear     (pCam->getNear());
                    pPart->setFar      (pCam->getFar ());
                    
                    pPart->calcFrustum();
                
                    if(this->getBackground() == NULL)
                    {
                        pPart->setBackground(pBack);
                    }
                    else
                    {
                        pPart->setBackground(this->getBackground());
                    }
                
                    if(this->getRoot() != NULL)
                    {
                        this->recurse(a, this->getRoot());
                    }
                    else
                    {
                        this->recurse(a, pPort->getRoot());
                    }

                    pPart->setDrawBuffer(GL_COLOR_ATTACHMENT0_EXT + i);

#ifdef OSG_DEBUGX
                    std::string szMessage("CubeX\n");
                    pPart->setDebugString(szMessage          );
#endif
                }
                this->popPartition(a);
            }

            pActNode->setTravMask(~0);
        }
        this->endPartitionGroup(a);
    }

    OSG_ASSERT(pActNode == a->getActNode());

    returnValue = Inherited::renderEnter(action);

    action->useNodeList(false);

    return returnValue;
}
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 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;
}
void VarianceShadowMapHandler::createShadowFactorMapFBO(
    RenderAction *a,
    DrawEnv      *pEnv,
    UInt32        num,
    UInt32        uiActiveLightCount)
{
    glClearColor(0.0, 0.0, 0.0, 1.0);

    //Finde alle aktiven Lichtquellen
    Real32  activeLights = 0;

    const ShadowStageData::LightStore  &vLights      = 
        _pStageData->getLights();

    const ShadowStageData::LStateStore &vLightStates = 
        _pStageData->getLightStates();

    const ShadowStageData::CamStore    &vLCams       =
        _pStageData->getLightCameras();


    if(_pStage->getGlobalShadowIntensity() != 0.0)
    {
        for(UInt32 i = 0;i < vLights.size();i++)
        {
            if(vLightStates[i] != 0)
                activeLights++;
        }
    }
    else
    {
        for(UInt32 i = 0;i < vLights.size();i++)
        {
            if(vLightStates[i]                              != 0 &&
               vLights     [i].second->getShadowIntensity() != 0.0)
            {
                activeLights++;
            }
        }
    }

    Real32  shadowIntensity;

    if(_pStage->getGlobalShadowIntensity() != 0.0)
    {
        shadowIntensity = (_pStage->getGlobalShadowIntensity() /
                           activeLights);
    }
    else
    {
        shadowIntensity = 
            (vLights[num].second->getShadowIntensity() /
             activeLights);
    }

    if(vLights[num].second->getShadowIntensity() != 0.0 ||
       _pStage->getGlobalShadowIntensity() != 0.0)
    {

        Matrix  LVM, LPM, CVM;
        vLCams[num]->getViewing(LVM,
                                pEnv->getPixelWidth(),
                                pEnv->getPixelHeight());

        vLCams[num]->getProjection(LPM,
                                   pEnv->getPixelWidth(),
                                   pEnv->getPixelHeight());

        CVM = pEnv->getCameraViewing();

        Matrix  iCVM = CVM;
        iCVM.invert();

        Real32  texFactor;
        if(vLights[num].second->getType() == SpotLight ::getClassType() ||
           vLights[num].second->getType() == PointLight::getClassType())
        {
            texFactor = Real32(_width) / Real32(_height);
        }
        else
        {
            texFactor = 1.0;
        }

        Matrix  shadowMatrix = LPM;
        shadowMatrix.mult(LVM);
        shadowMatrix.mult(iCVM);

        Matrix  shadowMatrix2 = LVM;
        shadowMatrix2.mult(iCVM);


        Real32  xFactor = 1.0;
        Real32  yFactor = 1.0;

        Pnt3f   lPos;
        bool    isDirLight;
        Real32  sceneDiagLength;

        if(vLights[num].second->getType() == PointLight::getClassType())
        {
            PointLight *tmpPoint;

            tmpPoint = dynamic_cast<PointLight *>(
                vLights[num].second.get());

            lPos = tmpPoint->getPosition();

            if(tmpPoint->getBeacon() != NULL)
            {
                Matrix  m = tmpPoint->getBeacon()->getToWorld();
                m.mult(lPos, lPos);
            }

            isDirLight = false;
            Pnt3f           center;

            _pStageData->getLightRoot(num)->getVolume().getCenter(center);

            Vec3f           dir = lPos - center;
            Real32          dirLength = dir.length();

            Vec3f           diff = (_pStageData->getLightRoot(num)->getVolume
                                    ().getMax() - center);
            Real32          diffLength = diff.length();

            sceneDiagLength = dirLength + diffLength;
        }

        else if(vLights[num].second->getType() == SpotLight::getClassType())
        {
            SpotLight *tmpSpot;
            tmpSpot = dynamic_cast<SpotLight *>(
                vLights[num].second.get());

            lPos = tmpSpot->getPosition();

            if(tmpSpot->getBeacon() != NULL)
            {
                Matrix  m = tmpSpot->getBeacon()->getToWorld();
                m.mult(lPos, lPos);
            }

            isDirLight = false;
            Pnt3f           center;
            _pStageData->getLightRoot(num)->getVolume().getCenter(center);

            Vec3f           dir = lPos - center;
            Real32          dirLength = dir.length();

            Vec3f           diff = (_pStageData->getLightRoot(num)->getVolume
                                    ().getMax() - center);
            Real32          diffLength = diff.length();

            sceneDiagLength = dirLength + diffLength;
        }

        else
        {
            isDirLight = true;
            sceneDiagLength = 1.0;
        }


        Real32  lod;

        if(_pStage->getShadowSmoothness() <= 0.1999)
            lod = 0.5;
        else if(_pStage->getShadowSmoothness() <= 0.3999)
            lod = 1.5;
        else if(_pStage->getShadowSmoothness() <= 0.5999)
            lod = 2.5;
        else if(_pStage->getShadowSmoothness() <= 0.7999)
            lod = 3.5;
        else
            lod = 4.5;

        if(_vShadowCmat.size() == uiActiveLightCount)
        {
            _vShadowCmat.push_back(ChunkMaterial::createLocal());
        }
        
        OSG_ASSERT( uiActiveLightCount < _vShadowCmat.size());

        if(_vShadowSHLVar.size() == uiActiveLightCount)
        {
            _vShadowSHLVar.push_back(SimpleSHLVariableChunk::createLocal());

#ifndef OSG_NEW_SHADER
            _vShadowSHLVar[uiActiveLightCount]->setSHLChunk(_shadowSHL);
#endif
        }
        
        OSG_ASSERT(uiActiveLightCount < _vShadowSHLVar.size());

        _shadowSHL->addUniformVariable("shadowMap",    0);
        _shadowSHL->addUniformVariable("oldFactorMap", 1);

        _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
            "firstRun",
            (uiActiveLightCount == 0) ? Int32(1) : Int32(0));

        _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
            "intensity", shadowIntensity);

        _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
            "texFactor", texFactor);
        //_shadowSHL->addUniformVariable("shadowBias", 0.0075f);

        _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
            "lightPM", shadowMatrix);

        _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
            "lightPM2", shadowMatrix2);

        //_shadowSHL->addUniformVariable("shadowRange", Real32(shadowRange));
        _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
            "xFactor", Real32(xFactor));

        _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
            "yFactor", Real32(yFactor));

        _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
            "sceneDiagLength", Real32(sceneDiagLength));

        _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
            "Lod", Real32(lod));
        
        _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
            "isDirLight", bool(isDirLight));


        ShadowStageData::ShadowMapStore &vShadowMaps = 
            _pStageData->getShadowMaps();

        _vShadowCmat[uiActiveLightCount]->clearChunks();

        _vShadowCmat[uiActiveLightCount]->addChunk(
            _shadowSHL);

        _vShadowCmat[uiActiveLightCount]->addChunk(
            _vShadowSHLVar[uiActiveLightCount]);

        _vShadowCmat[uiActiveLightCount]->addChunk(
            vShadowMaps[num].pTexO);

        _vShadowCmat[uiActiveLightCount]->addChunk(
            vShadowMaps[num].pTexE);

        _vShadowCmat[uiActiveLightCount]->addChunk(
            _shadowFactorMapO);

        _pStage->pushPartition(a,
                               (RenderPartition::CopyWindow      |
                                RenderPartition::CopyViewing     |
                                RenderPartition::CopyProjection  |
                                RenderPartition::CopyFrustum     |
                                RenderPartition::CopyNearFar     |
                                RenderPartition::CopyViewportSize),
                               RenderPartition::StateSorting);
        {
            RenderPartition *pPart = a->getActivePartition();

            pPart->addPreRenderCallback (&ShadowTreeHandler::setupAmbientModel);
            pPart->addPostRenderCallback(&ShadowTreeHandler::endAmbientModel  );

            pPart->setRenderTarget(_pSceneFBO);
            pPart->setDrawBuffer  (GL_COLOR_ATTACHMENT1_EXT);
            
            Node *light  = vLights[num].first;
            Node *parent = light->getParent();
            
            if(parent != NULL)
            {
                a->pushMatrix(parent->getToWorld());
            }

            if(uiActiveLightCount == 0)
            {
                pPart->setBackground(_pClearBackground);
            }
                             
            commitChanges();

            a->overrideMaterial(_vShadowCmat[uiActiveLightCount], 
                                 a->getActNode());
            _pStage->recurse(a, light);
            a->overrideMaterial( NULL,       
                                 a->getActNode());
            
            if(parent != NULL)
            {
                a->popMatrix();
            }
        }
        _pStage->popPartition(a);

        _firstRun = 0;
    }
}
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 VarianceShadowMapHandler::createShadowMapsFBO(RenderAction *a,
                                                   DrawEnv      *pEnv)
{
    UInt32  mSize = _pStage->getMapSize();

    if(mSize > 2048)
        mSize = 2048;

    //------Setting up Window to fit size of ShadowMap----------------


    // disable all lights more speed
    std::vector<bool> vLocalLightStates;

    const ShadowStageData::LightStore  &vLights      = 
        _pStageData->getLights();

    const ShadowStageData::LStateStore &vLightStates = 
        _pStageData->getLightStates();

    const ShadowStageData::CamStore    &vLCams       =
        _pStageData->getLightCameras();

    const ShadowStageData::StatusStore &vExclActive  =
        _pStageData->getExcludeNodeActive();

    for(UInt32 i = 0;i < vLights.size();++i)
    {
        // store old states.
        vLocalLightStates.push_back(vLights[i].second->getOn());
        vLights[i].second->setOn(false);
    }

    // activate exclude nodes:
    for(UInt32 i = 0;i < _pStage->getMFExcludeNodes()->size();++i)
    {
        Node *exnode = _pStage->getExcludeNodes(i);

        if(exnode != NULL)
        {
            if(vExclActive[i])
            {
                exnode->setTravMask(0);
            }
        }
    }

    UInt32 uiActiveLightCount = 0;

    ShadowStageData::ShadowMapStore &vShadowMaps = _pStageData->getShadowMaps();

    for(UInt32 i = 0;i < vLights.size();++i)
    {
        if(vLightStates[i] != 0)
        {
            if(_pStage->getGlobalShadowIntensity()    != 0.0 ||
                vLights[i].second->getShadowIntensity() != 0.0)
            {

                GLenum  *buffers = NULL;
                buffers = new GLenum[1];
                buffers[0] = GL_COLOR_ATTACHMENT0_EXT;

                Pnt3f   lPos;
                bool    isDirLight;
                Real32  sceneDiagLength;

                if(vLights[i].second->getType() == PointLight::getClassType())
                {
                    PointLight *tmpPoint;
                    tmpPoint = 
                        dynamic_cast<PointLight *>(vLights[i].second.get());

                    lPos = tmpPoint->getPosition();

                    if(tmpPoint->getBeacon() != NULL)
                    {
                        Matrix  m = tmpPoint->getBeacon()->getToWorld();
                        m.mult(lPos, lPos);
                    }
                    isDirLight = false;

                    Pnt3f           center;
                    _pStageData->getLightRoot(i)->getVolume().getCenter(center);

                    Vec3f           dir = lPos - center;
                    Real32          dirLength = dir.length();

                    Vec3f           diff =
                        (_pStageData->getLightRoot(i)->getVolume().getMax() -
                         center);
                    Real32          diffLength = diff.length();

                    sceneDiagLength = dirLength + diffLength;
                }

                else if(vLights[i].second->getType() == 
                                                     SpotLight::getClassType())
                {
                    SpotLight *tmpSpot;
                    tmpSpot = 
                        dynamic_cast<SpotLight *>(vLights[i].second.get());

                    lPos = tmpSpot->getPosition();
                    if(tmpSpot->getBeacon() != NULL)
                    {
                        Matrix  m = tmpSpot->getBeacon()->getToWorld();
                        m.mult(lPos, lPos);
                    }
                    isDirLight = false;
                    Pnt3f           center;
                    _pStageData->getLightRoot(i)->getVolume().getCenter(center);

                    Vec3f           dir = lPos - center;
                    Real32          dirLength = dir.length();

                    Vec3f           diff =
                        (_pStageData->getLightRoot(i)->getVolume().getMax() -
                         center);
                    Real32          diffLength = diff.length();

                    sceneDiagLength = dirLength + diffLength;
                }

                else
                {
                    isDirLight = true;
                    sceneDiagLength = 1.0;
                }

                if(_vDepthCmat.size() == uiActiveLightCount)
                {
                    _vDepthCmat.push_back(ChunkMaterial::createLocal());
                }
        
                OSG_ASSERT(uiActiveLightCount < _vDepthCmat.size());

                if(_vDepthSHLVar.size() == uiActiveLightCount)
                {
                    _vDepthSHLVar.push_back(
                        SimpleSHLVariableChunk::createLocal());
                    
#ifndef OSG_NEW_SHADER
                    _vDepthSHLVar[uiActiveLightCount]->setSHLChunk(_depthSHL);
#endif
                }

                OSG_ASSERT(uiActiveLightCount < _vDepthSHLVar.size());

                _vDepthSHLVar[uiActiveLightCount]->addUniformVariable(
                    "sceneDiagLength",
                    Real32(sceneDiagLength));

                _vDepthSHLVar[uiActiveLightCount]->addUniformVariable(
                    "isDirLight", bool(isDirLight));

                
                _vDepthCmat[uiActiveLightCount]->clearChunks();
                _vDepthCmat[uiActiveLightCount]->addChunk(_depthSHL);
                _vDepthCmat[uiActiveLightCount]->addChunk(
                    _vDepthSHLVar[uiActiveLightCount]);

                commitChanges();

                _pStage->pushPartition(a);
                {
                    RenderPartition   *pPart    = a->getActivePartition();

                    pPart->addPreRenderCallback(
                        &ShadowTreeHandler::setupAmbientModel);
                    pPart->addPostRenderCallback(
                        &ShadowTreeHandler::endAmbientModel);
                    
                    pPart->setRenderTarget(vShadowMaps[i].pFBO);

                    pPart->setDrawBuffer  (*buffers                      );

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

                    pPart->calcViewportDimension(0.f,
                                                 0.f,
                                                 mSize - 1,
                                                 mSize - 1,
                                                 
                                                 mSize,
                                                 mSize);


                    RenderFunctor f = 
                        boost::bind(&VarianceShadowMapHandler::genMipMapCB,
                                    this,
                                    _1,
                                    i);

                    pPart->addPreRenderCallback(f);

                    Matrix m, t;
                    
                    // set the projection
                    vLCams[i]->getProjection(
                        m, 
                        pPart->getViewportWidth (), 
                        pPart->getViewportHeight());
                    
                    vLCams[i]->getProjectionTranslation(
                        t, 
                        pPart->getViewportWidth (), 
                        pPart->getViewportHeight());
                    
                    pPart->setupProjection(m, t);
                    
                    vLCams[i]->getViewing(
                        m, 
                        pPart->getViewportWidth (),
                        pPart->getViewportHeight());
                    
                    
                    pPart->setupViewing(m);
                    
                    pPart->setNear     (vLCams[i]->getNear());
                    pPart->setFar      (vLCams[i]->getFar ());
                    
                    pPart->calcFrustum();
                    
                    pPart->setBackground(_pClearSMapBack);
                    
                    Node *light  = vLights[i].first;
                    Node *parent = light->getParent();
                    
                    if(parent != NULL)
                    {
                        a->pushMatrix(parent->getToWorld());
                    }
                    
                    
                    a->overrideMaterial(_vDepthCmat[uiActiveLightCount], 
                                         a->getActNode());
                    _pStage->recurse(a, light);
                    a->overrideMaterial( NULL,       
                                         a->getActNode());
                    
                    if(parent != NULL)
                    {
                        a->popMatrix();
                    }
                }
                _pStage->popPartition(a);

                ++uiActiveLightCount;
            }
        }
    }

    //-------Restoring old states of Window and Viewport----------

    // enable all lights.
    for(UInt32 i = 0;i < vLights.size();++i)
    {
        // restore old states.
        vLights[i].second->setOn(vLocalLightStates[i]);
    }

    // activate exclude nodes:
    for(UInt32 i = 0;i < _pStage->getMFExcludeNodes()->size();++i)
    {
        Node *exnode = _pStage->getExcludeNodes(i);

        if(exnode != NULL)
        {
            if(vExclActive[i])
            {
                exnode->setTravMask(TypeTraits<UInt32>::BitsSet);
            }
        }
    }
}
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;
}