OSGVarianceShadowMapHandler.cpp

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002  *                                OpenSG                                     *
00003  *                                                                           *
00004  *                                                                           *
00005  *               Copyright (C) 2000-2002 by the OpenSG Forum                 *
00006  *                                                                           *
00007  *                            www.opensg.org                                 *
00008  *                                                                           *
00009  *   contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de          *
00010  *                                                                           *
00011 \*---------------------------------------------------------------------------*/
00012 /*---------------------------------------------------------------------------*\
00013  *                                License                                    *
00014  *                                                                           *
00015  * This library is free software; you can redistribute it and/or modify it   *
00016  * under the terms of the GNU Library General Public License as published    *
00017  * by the Free Software Foundation, version 2.                               *
00018  *                                                                           *
00019  * This library is distributed in the hope that it will be useful, but       *
00020  * WITHOUT ANY WARRANTY; without even the implied warranty of                *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
00022  * Library General Public License for more details.                          *
00023  *                                                                           *
00024  * You should have received a copy of the GNU Library General Public         *
00025  * License along with this library; if not, write to the Free Software       *
00026  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 *
00027  *                                                                           *
00028 \*---------------------------------------------------------------------------*/
00029 /*---------------------------------------------------------------------------*\
00030  *                                Changes                                    *
00031  *                                                                           *
00032  *                                                                           *
00033  *                                                                           *
00034  *                                                                           *
00035  *                                                                           *
00036  *                                                                           *
00037 \*---------------------------------------------------------------------------*/
00038
00039 #include <stdlib.h>
00040 #include <stdio.h>
00041
00042 #include "OSGVarianceShadowMapHandler.h"
00043 #include "OSGRenderAction.h"
00044 #include "OSGShadowStage.h"
00045 #include "OSGShadowStageData.h"
00046 #include "OSGSpotLight.h"
00047 #include "OSGRenderBuffer.h"
00048 #include "OSGTextureBuffer.h"
00049 #include "OSGGLFuncProtos.h"
00050
00051 OSG_BEGIN_NAMESPACE
00052
00053 #include "ShaderCode/OSGVarianceShadowMapShaderCode.cinl"
00054
00055 VarianceShadowMapHandler::VarianceShadowMapHandler(ShadowStage     *pSource,
00056                                                    ShadowStageData *pData  ) :
00057      Inherited     (pSource,
00058                     pData  ),
00059     _pClearSMapBack(NULL   ),
00060     _shadowSHL     (NULL   ),
00061     _depthSHL      (NULL   ),
00062     _firstRun      (1      )
00063 {
00064     _uiMode = ShadowStage::VARIANCE_SHADOW_MAP;
00065
00066     //SHL Chunk 1
00067
00068     _shadowSHL = SimpleSHLChunk::createLocal();
00069     _shadowSHL->setVertexProgram  (_variance_vp);
00070     _shadowSHL->setFragmentProgram(_variance_fp);
00071
00072
00073     //SHL Depth
00074     _depthSHL = SimpleSHLChunk::createLocal();
00075     _depthSHL->setVertexProgram  (_depth_vp);
00076     _depthSHL->setFragmentProgram(_depth_fp);
00077
00078     _pClearSMapBack = SolidBackground::createLocal();
00079
00080     _pClearSMapBack->setColor(Color3f(1.f, 1.f, 1.f));
00081 }
00082
00083 VarianceShadowMapHandler::~VarianceShadowMapHandler(void)
00084 {
00085     _pClearSMapBack  = NULL;
00086     _shadowSHL       = NULL;
00087     _depthSHL        = NULL;
00088
00089     _vShadowCmat  .clear();
00090     _vShadowSHLVar.clear();
00091
00092     _vDepthCmat   .clear();
00093     _vDepthSHLVar .clear();
00094 }
00095
00096
00097 void VarianceShadowMapHandler::createShadowMapsFBO(RenderAction *a,
00098                                                    DrawEnv      *pEnv)
00099 {
00100     UInt32  mSize = _pStage->getMapSize();
00101
00102     if(mSize > 2048)
00103         mSize = 2048;
00104
00105     //------Setting up Window to fit size of ShadowMap----------------
00106
00107
00108     // disable all lights more speed
00109     std::vector<bool> vLocalLightStates;
00110
00111     const ShadowStageData::LightStore  &vLights      =
00112         _pStageData->getLights();
00113
00114     const ShadowStageData::LStateStore &vLightStates =
00115         _pStageData->getLightStates();
00116
00117     const ShadowStageData::CamStore    &vLCams       =
00118         _pStageData->getLightCameras();
00119
00120     const ShadowStageData::StatusStore &vExclActive  =
00121         _pStageData->getExcludeNodeActive();
00122
00123     for(UInt32 i = 0;i < vLights.size();++i)
00124     {
00125         // store old states.
00126         vLocalLightStates.push_back(vLights[i].second->getOn());
00127         vLights[i].second->setOn(false);
00128     }
00129
00130     // activate exclude nodes:
00131     for(UInt32 i = 0;i < _pStage->getMFExcludeNodes()->size();++i)
00132     {
00133         Node *exnode = _pStage->getExcludeNodes(i);
00134
00135         if(exnode != NULL)
00136         {
00137             if(vExclActive[i])
00138             {
00139                 exnode->setTravMask(0);
00140             }
00141         }
00142     }
00143
00144     UInt32 uiActiveLightCount = 0;
00145
00146     ShadowStageData::ShadowMapStore &vShadowMaps = _pStageData->getShadowMaps();
00147
00148     for(UInt32 i = 0;i < vLights.size();++i)
00149     {
00150         if(vLightStates[i] != 0)
00151         {
00152             if(_pStage->getGlobalShadowIntensity()    != 0.0 ||
00153                 vLights[i].second->getShadowIntensity() != 0.0)
00154             {
00155
00156                 GLenum  *buffers = NULL;
00157                 buffers = new GLenum[1];
00158                 buffers[0] = GL_COLOR_ATTACHMENT0_EXT;
00159
00160                 Pnt3f   lPos;
00161                 bool    isDirLight;
00162                 Real32  sceneDiagLength;
00163
00164                 if(vLights[i].second->getType() == PointLight::getClassType())
00165                 {
00166                     PointLight *tmpPoint;
00167                     tmpPoint =
00168                         dynamic_cast<PointLight *>(vLights[i].second.get());
00169
00170                     lPos = tmpPoint->getPosition();
00171
00172                     if(tmpPoint->getBeacon() != NULL)
00173                     {
00174                         Matrix  m = tmpPoint->getBeacon()->getToWorld();
00175                         m.mult(lPos, lPos);
00176                     }
00177                     isDirLight = false;
00178
00179                     Pnt3f           center;
00180                     _pStageData->getLightRoot(i)->getVolume().getCenter(center);
00181
00182                     Vec3f           dir = lPos - center;
00183                     Real32          dirLength = dir.length();
00184
00185                     Vec3f           diff =
00186                         (_pStageData->getLightRoot(i)->getVolume().getMax() -
00187                          center);
00188                     Real32          diffLength = diff.length();
00189
00190                     sceneDiagLength = dirLength + diffLength;
00191                 }
00192
00193                 else if(vLights[i].second->getType() ==
00194                                                      SpotLight::getClassType())
00195                 {
00196                     SpotLight *tmpSpot;
00197                     tmpSpot =
00198                         dynamic_cast<SpotLight *>(vLights[i].second.get());
00199
00200                     lPos = tmpSpot->getPosition();
00201                     if(tmpSpot->getBeacon() != NULL)
00202                     {
00203                         Matrix  m = tmpSpot->getBeacon()->getToWorld();
00204                         m.mult(lPos, lPos);
00205                     }
00206                     isDirLight = false;
00207                     Pnt3f           center;
00208                     _pStageData->getLightRoot(i)->getVolume().getCenter(center);
00209
00210                     Vec3f           dir = lPos - center;
00211                     Real32          dirLength = dir.length();
00212
00213                     Vec3f           diff =
00214                         (_pStageData->getLightRoot(i)->getVolume().getMax() -
00215                          center);
00216                     Real32          diffLength = diff.length();
00217
00218                     sceneDiagLength = dirLength + diffLength;
00219                 }
00220
00221                 else
00222                 {
00223                     isDirLight = true;
00224                     sceneDiagLength = 1.0;
00225                 }
00226
00227                 if(_vDepthCmat.size() == uiActiveLightCount)
00228                 {
00229                     _vDepthCmat.push_back(ChunkMaterial::createLocal());
00230                 }
00231
00232                 OSG_ASSERT(uiActiveLightCount < _vDepthCmat.size());
00233
00234                 if(_vDepthSHLVar.size() == uiActiveLightCount)
00235                 {
00236                     _vDepthSHLVar.push_back(
00237                         SimpleSHLVariableChunk::createLocal());
00238
00239 #ifndef OSG_NEW_SHADER
00240                     _vDepthSHLVar[uiActiveLightCount]->setSHLChunk(_depthSHL);
00241 #endif
00242                 }
00243
00244                 OSG_ASSERT(uiActiveLightCount < _vDepthSHLVar.size());
00245
00246                 _vDepthSHLVar[uiActiveLightCount]->addUniformVariable(
00247                     "sceneDiagLength",
00248                     Real32(sceneDiagLength));
00249
00250                 _vDepthSHLVar[uiActiveLightCount]->addUniformVariable(
00251                     "isDirLight", bool(isDirLight));
00252
00253
00254                 _vDepthCmat[uiActiveLightCount]->clearChunks();
00255                 _vDepthCmat[uiActiveLightCount]->addChunk(_depthSHL);
00256                 _vDepthCmat[uiActiveLightCount]->addChunk(
00257                     _vDepthSHLVar[uiActiveLightCount]);
00258
00259                 commitChanges();
00260
00261                 a->pushPartition();
00262                 {
00263                     RenderPartition   *pPart    = a->getActivePartition();
00264
00265                     pPart->addPreRenderCallback(
00266                         &ShadowTreeHandler::setupAmbientModel);
00267                     pPart->addPostRenderCallback(
00268                         &ShadowTreeHandler::endAmbientModel);
00269
00270                     pPart->setRenderTarget(vShadowMaps[i].pFBO);
00271
00272                     pPart->setDrawBuffer  (*buffers                      );
00273
00274                     pPart->setWindow  (a->getWindow());
00275
00276                     pPart->calcViewportDimension(0.f,
00277                                                  0.f,
00278                                                  mSize - 1,
00279                                                  mSize - 1,
00280
00281                                                  mSize,
00282                                                  mSize);
00283
00284
00285                     RenderFunctor f =
00286                         boost::bind(&VarianceShadowMapHandler::genMipMapCB,
00287                                     this,
00288                                     _1,
00289                                     i);
00290
00291                     pPart->addPreRenderCallback(f);
00292
00293                     Matrix m, t;
00294
00295                     // set the projection
00296                     vLCams[i]->getProjection(
00297                         m,
00298                         pPart->getViewportWidth (),
00299                         pPart->getViewportHeight());
00300
00301                     vLCams[i]->getProjectionTranslation(
00302                         t,
00303                         pPart->getViewportWidth (),
00304                         pPart->getViewportHeight());
00305
00306                     pPart->setupProjection(m, t);
00307
00308                     vLCams[i]->getViewing(
00309                         m,
00310                         pPart->getViewportWidth (),
00311                         pPart->getViewportHeight());
00312
00313
00314                     pPart->setupViewing(m);
00315
00316                     pPart->setNear     (vLCams[i]->getNear());
00317                     pPart->setFar      (vLCams[i]->getFar ());
00318
00319                     pPart->calcFrustum();
00320
00321                     pPart->setBackground(_pClearSMapBack);
00322
00323                     Node *light  = vLights[i].first;
00324                     Node *parent = light->getParent();
00325
00326                     if(parent != NULL)
00327                     {
00328                         a->pushMatrix(parent->getToWorld());
00329                     }
00330
00331
00332                     a->overrideMaterial(_vDepthCmat[uiActiveLightCount],
00333                                          a->getActNode());
00334                     _pStage->recurse(a, light);
00335                     a->overrideMaterial( NULL,
00336                                          a->getActNode());
00337
00338                     if(parent != NULL)
00339                     {
00340                         a->popMatrix();
00341                     }
00342                 }
00343                 a->popPartition();
00344
00345                 ++uiActiveLightCount;
00346             }
00347         }
00348     }
00349
00350     //-------Restoring old states of Window and Viewport----------
00351
00352     // enable all lights.
00353     for(UInt32 i = 0;i < vLights.size();++i)
00354     {
00355         // restore old states.
00356         vLights[i].second->setOn(vLocalLightStates[i]);
00357     }
00358
00359     // activate exclude nodes:
00360     for(UInt32 i = 0;i < _pStage->getMFExcludeNodes()->size();++i)
00361     {
00362         Node *exnode = _pStage->getExcludeNodes(i);
00363
00364         if(exnode != NULL)
00365         {
00366             if(vExclActive[i])
00367             {
00368                 exnode->setTravMask(TypeTraits<UInt32>::BitsSet);
00369             }
00370         }
00371     }
00372 }
00373
00374 void VarianceShadowMapHandler::genMipMapCB(DrawEnv *pEnv,
00375                                            UInt32   uiLightIdx)
00376 {
00377     ShadowStageData::ShadowMapStore &vShadowMaps = _pStageData->getShadowMaps();
00378
00379     glBindTexture(GL_TEXTURE_2D,
00380                   pEnv->getWindow()->getGLObjectId(
00381                       vShadowMaps[uiLightIdx].pTexO->getGLId()));
00382
00383     OSGGETGLFUNC(OSGglGenerateMipmapEXTProc,
00384                  osgGlGenerateMipmap,
00385                  ShadowStage::FuncIdGenMipmaps);
00386
00387     osgGlGenerateMipmap(GL_TEXTURE_2D);
00388
00389     glBindTexture(GL_TEXTURE_2D, 0);
00390 }
00391
00392
00393 void VarianceShadowMapHandler::createColorMapFBO(RenderAction *a,
00394                                                  DrawEnv      *pEnv)
00395 {
00396     a->pushPartition((RenderPartition::CopyWindow      |
00397                       RenderPartition::CopyViewing     |
00398                       RenderPartition::CopyProjection  |
00399                       RenderPartition::CopyFrustum     |
00400                       RenderPartition::CopyNearFar     |
00401                       RenderPartition::CopyViewportSize),
00402                      RenderPartition::StateSorting);
00403     {
00404         RenderPartition *pPart = a->getActivePartition();
00405
00406         pPart->addPreRenderCallback (&ShadowTreeHandler::setupAmbientModel);
00407         pPart->addPostRenderCallback(&ShadowTreeHandler::endAmbientModel  );
00408
00409         pPart->setRenderTarget(_pSceneFBO);
00410         pPart->setDrawBuffer  (GL_COLOR_ATTACHMENT0_EXT);
00411
00412         Node *parent = a->getActNode()->getParent();
00413
00414         if(parent != NULL)
00415         {
00416             a->pushMatrix(parent->getToWorld());
00417         }
00418
00419         pPart->setBackground(a->getBackground());
00420
00421         _pStage->recurseFromThis(a);
00422
00423         if(parent != NULL)
00424         {
00425             a->popMatrix();
00426         }
00427     }
00428     a->popPartition();
00429
00430 }
00431
00432
00433 void VarianceShadowMapHandler::createShadowFactorMapFBO(
00434     RenderAction *a,
00435     DrawEnv      *pEnv,
00436     UInt32        num,
00437     UInt32        uiActiveLightCount)
00438 {
00439     glClearColor(0.0, 0.0, 0.0, 1.0);
00440
00441     //Finde alle aktiven Lichtquellen
00442     Real32  activeLights = 0;
00443
00444     const ShadowStageData::LightStore  &vLights      =
00445         _pStageData->getLights();
00446
00447     const ShadowStageData::LStateStore &vLightStates =
00448         _pStageData->getLightStates();
00449
00450     const ShadowStageData::CamStore    &vLCams       =
00451         _pStageData->getLightCameras();
00452
00453
00454     if(_pStage->getGlobalShadowIntensity() != 0.0)
00455     {
00456         for(UInt32 i = 0;i < vLights.size();i++)
00457         {
00458             if(vLightStates[i] != 0)
00459                 activeLights++;
00460         }
00461     }
00462     else
00463     {
00464         for(UInt32 i = 0;i < vLights.size();i++)
00465         {
00466             if(vLightStates[i]                              != 0 &&
00467                vLights     [i].second->getShadowIntensity() != 0.0)
00468             {
00469                 activeLights++;
00470             }
00471         }
00472     }
00473
00474     Real32  shadowIntensity;
00475
00476     if(_pStage->getGlobalShadowIntensity() != 0.0)
00477     {
00478         shadowIntensity = (_pStage->getGlobalShadowIntensity() /
00479                            activeLights);
00480     }
00481     else
00482     {
00483         shadowIntensity =
00484             (vLights[num].second->getShadowIntensity() /
00485              activeLights);
00486     }
00487
00488     if(vLights[num].second->getShadowIntensity() != 0.0 ||
00489        _pStage->getGlobalShadowIntensity() != 0.0)
00490     {
00491
00492         Matrix  LVM, LPM, CVM;
00493         vLCams[num]->getViewing(LVM,
00494                                 pEnv->getPixelWidth(),
00495                                 pEnv->getPixelHeight());
00496
00497         vLCams[num]->getProjection(LPM,
00498                                    pEnv->getPixelWidth(),
00499                                    pEnv->getPixelHeight());
00500
00501         CVM = pEnv->getCameraViewing();
00502
00503         Matrix  iCVM = CVM;
00504         iCVM.invert();
00505
00506         Real32  texFactor;
00507         if(vLights[num].second->getType() == SpotLight ::getClassType() ||
00508            vLights[num].second->getType() == PointLight::getClassType())
00509         {
00510             texFactor = Real32(_width) / Real32(_height);
00511         }
00512         else
00513         {
00514             texFactor = 1.0;
00515         }
00516
00517         Matrix  shadowMatrix = LPM;
00518         shadowMatrix.mult(LVM);
00519         shadowMatrix.mult(iCVM);
00520
00521         Matrix  shadowMatrix2 = LVM;
00522         shadowMatrix2.mult(iCVM);
00523
00524
00525         Real32  xFactor = 1.0;
00526         Real32  yFactor = 1.0;
00527
00528         Pnt3f   lPos;
00529         bool    isDirLight;
00530         Real32  sceneDiagLength;
00531
00532         if(vLights[num].second->getType() == PointLight::getClassType())
00533         {
00534             PointLight *tmpPoint;
00535
00536             tmpPoint = dynamic_cast<PointLight *>(
00537                 vLights[num].second.get());
00538
00539             lPos = tmpPoint->getPosition();
00540
00541             if(tmpPoint->getBeacon() != NULL)
00542             {
00543                 Matrix  m = tmpPoint->getBeacon()->getToWorld();
00544                 m.mult(lPos, lPos);
00545             }
00546
00547             isDirLight = false;
00548             Pnt3f           center;
00549
00550             _pStageData->getLightRoot(num)->getVolume().getCenter(center);
00551
00552             Vec3f           dir = lPos - center;
00553             Real32          dirLength = dir.length();
00554
00555             Vec3f           diff = (_pStageData->getLightRoot(num)->getVolume
00556                                     ().getMax() - center);
00557             Real32          diffLength = diff.length();
00558
00559             sceneDiagLength = dirLength + diffLength;
00560         }
00561
00562         else if(vLights[num].second->getType() == SpotLight::getClassType())
00563         {
00564             SpotLight *tmpSpot;
00565             tmpSpot = dynamic_cast<SpotLight *>(
00566                 vLights[num].second.get());
00567
00568             lPos = tmpSpot->getPosition();
00569
00570             if(tmpSpot->getBeacon() != NULL)
00571             {
00572                 Matrix  m = tmpSpot->getBeacon()->getToWorld();
00573                 m.mult(lPos, lPos);
00574             }
00575
00576             isDirLight = false;
00577             Pnt3f           center;
00578             _pStageData->getLightRoot(num)->getVolume().getCenter(center);
00579
00580             Vec3f           dir = lPos - center;
00581             Real32          dirLength = dir.length();
00582
00583             Vec3f           diff = (_pStageData->getLightRoot(num)->getVolume
00584                                     ().getMax() - center);
00585             Real32          diffLength = diff.length();
00586
00587             sceneDiagLength = dirLength + diffLength;
00588         }
00589
00590         else
00591         {
00592             isDirLight = true;
00593             sceneDiagLength = 1.0;
00594         }
00595
00596
00597         Real32  lod;
00598
00599         if(_pStage->getShadowSmoothness() <= 0.1999)
00600             lod = 0.5;
00601         else if(_pStage->getShadowSmoothness() <= 0.3999)
00602             lod = 1.5;
00603         else if(_pStage->getShadowSmoothness() <= 0.5999)
00604             lod = 2.5;
00605         else if(_pStage->getShadowSmoothness() <= 0.7999)
00606             lod = 3.5;
00607         else
00608             lod = 4.5;
00609
00610         if(_vShadowCmat.size() == uiActiveLightCount)
00611         {
00612             _vShadowCmat.push_back(ChunkMaterial::createLocal());
00613         }
00614
00615         OSG_ASSERT( uiActiveLightCount < _vShadowCmat.size());
00616
00617         if(_vShadowSHLVar.size() == uiActiveLightCount)
00618         {
00619             _vShadowSHLVar.push_back(SimpleSHLVariableChunk::createLocal());
00620
00621 #ifndef OSG_NEW_SHADER
00622             _vShadowSHLVar[uiActiveLightCount]->setSHLChunk(_shadowSHL);
00623 #endif
00624         }
00625
00626         OSG_ASSERT(uiActiveLightCount < _vShadowSHLVar.size());
00627
00628         _shadowSHL->addUniformVariable("shadowMap",    0);
00629         _shadowSHL->addUniformVariable("oldFactorMap", 1);
00630
00631         _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
00632             "firstRun",
00633             (uiActiveLightCount == 0) ? Int32(1) : Int32(0));
00634
00635         _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
00636             "intensity", shadowIntensity);
00637
00638         _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
00639             "texFactor", texFactor);
00640         //_shadowSHL->addUniformVariable("shadowBias", 0.0075f);
00641
00642         _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
00643             "lightPM", shadowMatrix);
00644
00645         _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
00646             "lightPM2", shadowMatrix2);
00647
00648         //_shadowSHL->addUniformVariable("shadowRange", Real32(shadowRange));
00649         _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
00650             "xFactor", Real32(xFactor));
00651
00652         _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
00653             "yFactor", Real32(yFactor));
00654
00655         _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
00656             "sceneDiagLength", Real32(sceneDiagLength));
00657
00658         _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
00659             "Lod", Real32(lod));
00660
00661         _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
00662             "isDirLight", bool(isDirLight));
00663
00664
00665         ShadowStageData::ShadowMapStore &vShadowMaps =
00666             _pStageData->getShadowMaps();
00667
00668         _vShadowCmat[uiActiveLightCount]->clearChunks();
00669
00670         _vShadowCmat[uiActiveLightCount]->addChunk(
00671             _shadowSHL);
00672
00673         _vShadowCmat[uiActiveLightCount]->addChunk(
00674             _vShadowSHLVar[uiActiveLightCount]);
00675
00676         _vShadowCmat[uiActiveLightCount]->addChunk(
00677             vShadowMaps[num].pTexO);
00678
00679         _vShadowCmat[uiActiveLightCount]->addChunk(
00680             vShadowMaps[num].pTexE);
00681
00682         _vShadowCmat[uiActiveLightCount]->addChunk(
00683             _shadowFactorMapO);
00684
00685         a->pushPartition((RenderPartition::CopyWindow      |
00686                           RenderPartition::CopyViewing     |
00687                           RenderPartition::CopyProjection  |
00688                           RenderPartition::CopyFrustum     |
00689                           RenderPartition::CopyNearFar     |
00690                           RenderPartition::CopyViewportSize),
00691                          RenderPartition::StateSorting);
00692         {
00693             RenderPartition *pPart = a->getActivePartition();
00694
00695             pPart->addPreRenderCallback (&ShadowTreeHandler::setupAmbientModel);
00696             pPart->addPostRenderCallback(&ShadowTreeHandler::endAmbientModel  );
00697
00698             pPart->setRenderTarget(_pSceneFBO);
00699             pPart->setDrawBuffer  (GL_COLOR_ATTACHMENT1_EXT);
00700
00701             Node *light  = vLights[num].first;
00702             Node *parent = light->getParent();
00703
00704             if(parent != NULL)
00705             {
00706                 a->pushMatrix(parent->getToWorld());
00707             }
00708
00709             if(uiActiveLightCount == 0)
00710             {
00711                 pPart->setBackground(_pClearBackground);
00712             }
00713
00714             commitChanges();
00715
00716             a->overrideMaterial(_vShadowCmat[uiActiveLightCount],
00717                                  a->getActNode());
00718             _pStage->recurse(a, light);
00719             a->overrideMaterial( NULL,
00720                                  a->getActNode());
00721
00722             if(parent != NULL)
00723             {
00724                 a->popMatrix();
00725             }
00726         }
00727         a->popPartition();
00728
00729         _firstRun = 0;
00730     }
00731 }
00732
00733 void VarianceShadowMapHandler::initShadowMaps(void)
00734 {
00735     ShadowStageData::ShadowMapStore &vShadowMaps = _pStageData->getShadowMaps();
00736
00737     const ShadowStageData::LightStore  &vLights  = _pStageData->getLights();
00738
00739
00740     if(vLights.size() < vShadowMaps.size())
00741     {
00742         vShadowMaps.resize(vLights.size());
00743     }
00744     else
00745     {
00746         Real32 maximumAnistropy;
00747
00748         glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maximumAnistropy);
00749
00750         maximumAnistropy = osgMin(maximumAnistropy, Real32(8.0));
00751
00752
00753         UInt32 uiLSize   =  vLights.size();
00754         UInt32 uiMapSize = _pStage-> getMapSize ();
00755
00756         if(vShadowMaps.size() == 0)
00757         {
00758             _uiMapSize = uiMapSize;
00759         }
00760
00761         for(UInt32 i = vShadowMaps.size(); i < uiLSize; ++i)
00762         {
00763             ShadowStageData::ShadowMapElem tmpElem;
00764
00765             tmpElem.uiType = ShadowStageData::ShadowMapElem::ColorShadowMap;
00766
00767             tmpElem.pImage = Image            ::createLocal();
00768             tmpElem.pTexO  = TextureObjChunk  ::createLocal();
00769             tmpElem.pTexE  = TextureEnvChunk  ::createLocal();
00770             tmpElem.pFBO   = FrameBufferObject::createLocal();
00771
00772             tmpElem.pImage->set(Image::OSG_RGBA_PF,
00773                                 uiMapSize, uiMapSize, 1,
00774                                 1, 1, 0.f,
00775                                 NULL,
00776                                 Image::OSG_FLOAT16_IMAGEDATA,
00777                                 false);
00778
00779             TextureBufferUnrecPtr pDepthTex = TextureBuffer::createLocal();
00780
00781             pDepthTex->setTexture(tmpElem.pTexO);
00782
00783             tmpElem.pFBO ->setColorAttachment(pDepthTex, 0);
00784
00785             tmpElem.pTexO->setImage(tmpElem.pImage);
00786
00787             tmpElem.pTexO->setInternalFormat(GL_RGBA16F_ARB);
00788             tmpElem.pTexO->setExternalFormat(GL_RGBA);
00789
00790             tmpElem.pTexO->setMinFilter     (GL_LINEAR_MIPMAP_LINEAR);
00791             tmpElem.pTexO->setMagFilter     (GL_LINEAR              );
00792
00793             tmpElem.pTexO->setAnisotropy    (maximumAnistropy       );
00794
00795             tmpElem.pTexO->setWrapS         (GL_REPEAT              );
00796             tmpElem.pTexO->setWrapT         (GL_REPEAT              );
00797
00798             tmpElem.pTexO->setTarget(GL_TEXTURE_2D);
00799
00800
00801
00802             RenderBufferUnrecPtr pDepthRB = RenderBuffer::create();
00803
00804             pDepthRB->setInternalFormat(GL_DEPTH_COMPONENT24);
00805
00806             tmpElem.pFBO->setDepthAttachment(pDepthRB);
00807
00808             tmpElem.pFBO->setSize(uiMapSize, uiMapSize);
00809
00810
00811             vShadowMaps.push_back(tmpElem);
00812         }
00813     }
00814 }
00815
00816 void VarianceShadowMapHandler::updateShadowMapSize(void)
00817 {
00818     ShadowStageData::ShadowMapStore &vShadowMaps = _pStageData->getShadowMaps();
00819
00820     UInt32 uiSHMSize    =  vShadowMaps.size();
00821      Int32 uiNewMapSize = _pStage->getMapSize();
00822
00823     for(UInt32 i = 0; i < uiSHMSize; ++i)
00824     {
00825         if(vShadowMaps[i].pImage->getWidth() != uiNewMapSize)
00826         {
00827             vShadowMaps[i].pImage->set(Image::OSG_RGBA_PF,
00828                                        uiNewMapSize, uiNewMapSize, 1,
00829                                        1, 1, 0.f,
00830                                        NULL,
00831                                        Image::OSG_FLOAT16_IMAGEDATA,
00832                                        false);
00833         }
00834
00835         if(vShadowMaps[i].pFBO->getWidth() != uiNewMapSize)
00836         {
00837             vShadowMaps[i].pFBO->setSize(uiNewMapSize, uiNewMapSize);
00838         }
00839     }
00840
00841     _uiMapSize = uiNewMapSize;
00842 }
00843
00844 void VarianceShadowMapHandler::configureShadowMaps(void)
00845 {
00846     ShadowStageData::ShadowMapStore &vShadowMaps = _pStageData->getShadowMaps();
00847
00848     UInt32 uiSHMSize = vShadowMaps.size();
00849
00850     UInt32 uiMapSize = _pStage-> getMapSize ();
00851
00852     Real32 maximumAnistropy;
00853
00854     glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maximumAnistropy);
00855
00856     maximumAnistropy = osgMin(maximumAnistropy, Real32(8.0));
00857
00858     for(UInt32 i = 0; i < uiSHMSize; ++i)
00859     {
00860         if(vShadowMaps[i].uiType ==
00861                                 ShadowStageData::ShadowMapElem::DepthShadowMap)
00862         {
00863             vShadowMaps[i].pTexO->setCompareMode(GL_NONE);
00864
00865             vShadowMaps[i].pTexO->setMinFilter     (GL_LINEAR_MIPMAP_LINEAR);
00866             vShadowMaps[i].pTexO->setMagFilter     (GL_LINEAR              );
00867
00868             vShadowMaps[i].pTexO->setInternalFormat(GL_RGBA16F_ARB);
00869             vShadowMaps[i].pTexO->setExternalFormat(GL_RGBA);
00870
00871             vShadowMaps[i].pTexO->setAnisotropy    (maximumAnistropy       );
00872
00873             vShadowMaps[i].pTexO->setWrapS         (GL_REPEAT              );
00874             vShadowMaps[i].pTexO->setWrapT         (GL_REPEAT              );
00875
00876
00877             vShadowMaps[i].pImage->set(Image::OSG_RGBA_PF,
00878                                 uiMapSize, uiMapSize, 1,
00879                                 1, 1, 0.f,
00880                                 NULL,
00881                                 Image::OSG_FLOAT16_IMAGEDATA,
00882                                 false);
00883
00884             vShadowMaps[i].pFBO->setColorAttachment(
00885                 vShadowMaps[i].pFBO->getDepthAttachment(), 0);
00886
00887
00888             RenderBufferUnrecPtr pDepthRB = RenderBuffer::createLocal();
00889
00890             pDepthRB->setInternalFormat(GL_DEPTH_COMPONENT24);
00891
00892             vShadowMaps[i].pFBO->setDepthAttachment(pDepthRB);
00893
00894             vShadowMaps[i].pFBO->setSize(uiMapSize, uiMapSize);
00895
00896             vShadowMaps[i].uiType =
00897                                 ShadowStageData::ShadowMapElem::ColorShadowMap;
00898
00899         }
00900     }
00901
00902     _bShadowMapsConfigured = true;
00903 }
00904
00905 void VarianceShadowMapHandler::render(RenderAction *a,
00906                                       DrawEnv      *pEnv)
00907 {
00908     const ShadowStageData::LightStore  &vLights      =
00909         _pStageData->getLights();
00910
00911     const ShadowStageData::NodeStore   &vTransparents =
00912         _pStageData->getTransparents();
00913
00914     const ShadowStageData::LStateStore &vLightStates =
00915         _pStageData->getLightStates();
00916
00917     if(_pStageData->getShadowMaps().size() != vLights.size())
00918     {
00919         initShadowMaps();
00920     }
00921
00922     if(_bShadowMapsConfigured == false)
00923     {
00924         configureShadowMaps();
00925     }
00926
00927     if(_uiMapSize != _pStage->getMapSize())
00928     {
00929         updateShadowMapSize();
00930     }
00931
00932     if(_pSceneFBO == NULL)
00933         initSceneFBO(pEnv, false);
00934
00935     if(_width  != pEnv->getPixelWidth () ||
00936        _height != pEnv->getPixelHeight()  )
00937     {
00938         updateSceneFBOSize(pEnv, false);
00939     }
00940
00941     commitChanges();
00942
00943     //Used for ShadowFactorMap
00944     _firstRun = 1;
00945
00946
00947     if(_pStage->getMapAutoUpdate() == true ||
00948        _pStage->_trigger_update    == true  )
00949     {
00950         createColorMapFBO(a, pEnv);
00951
00952
00953         //deactivate transparent Nodes
00954         for(UInt32 t = 0;t < vTransparents.size();++t)
00955         {
00956             vTransparents[t]->setTravMask(0);
00957         }
00958
00959
00960         createShadowMapsFBO(a, pEnv);
00961
00962
00963         // switch on all transparent geos
00964         for(UInt32 t = 0;t < vTransparents.size();++t)
00965         {
00966             vTransparents[t]->setTravMask(TypeTraits<UInt32>::BitsSet);
00967         }
00968
00969
00970         //filterShadowMaps(pEnv);
00971
00972         bool   bClear             = true;
00973         UInt32 uiActiveLightCount = 0;
00974
00975         for(UInt32 i = 0;i < vLights.size();i++)
00976         {
00977             if(vLightStates[i] != 0)
00978             {
00979                 if(_pStage->getGlobalShadowIntensity()      != 0.0 ||
00980                     vLights[i].second->getShadowIntensity() != 0.0)
00981                 {
00982                     createShadowFactorMapFBO(a,
00983                                              pEnv,
00984                                              i,
00985                                              uiActiveLightCount);
00986
00987                     bClear = false;
00988                     ++uiActiveLightCount;
00989                 }
00990             }
00991         }
00992
00993         _pStage->_trigger_update = false;
00994     }
00995
00996     setupDrawCombineMap1(a);
00997 }
00998
00999 OSG_END_NAMESPACE