00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
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
00067
00068 _shadowSHL = SimpleSHLChunk::createLocal();
00069 _shadowSHL->setVertexProgram (_variance_vp);
00070 _shadowSHL->setFragmentProgram(_variance_fp);
00071
00072
00073
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
00106
00107
00108
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
00126 vLocalLightStates.push_back(vLights[i].second->getOn());
00127 vLights[i].second->setOn(false);
00128 }
00129
00130
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
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
00351
00352
00353 for(UInt32 i = 0;i < vLights.size();++i)
00354 {
00355
00356 vLights[i].second->setOn(vLocalLightStates[i]);
00357 }
00358
00359
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
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
00641
00642 _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
00643 "lightPM", shadowMatrix);
00644
00645 _vShadowSHLVar[uiActiveLightCount]->addUniformVariable(
00646 "lightPM2", shadowMatrix2);
00647
00648
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
00944 _firstRun = 1;
00945
00946
00947 if(_pStage->getMapAutoUpdate() == true ||
00948 _pStage->_trigger_update == true )
00949 {
00950 createColorMapFBO(a, pEnv);
00951
00952
00953
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
00964 for(UInt32 t = 0;t < vTransparents.size();++t)
00965 {
00966 vTransparents[t]->setTravMask(TypeTraits<UInt32>::BitsSet);
00967 }
00968
00969
00970
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