OSGShadowTreeHandler.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 "OSGShadowTreeHandler.h"
00040 #include "OSGShadowStage.h"
00041 #include "OSGRenderBuffer.h"
00042 #include "OSGTextureBuffer.h"
00043 #include "OSGShadowStageData.h"
00044
00045 #include "OSGPointLight.h"
00046 #include "OSGRenderAction.h"
00047 #include "OSGMatrixUtility.h"
00048
00049 OSG_BEGIN_NAMESPACE
00050
00051
00052 std::string ShadowTreeHandler::_shadow_combine_vp =
00053     "varying vec2 texCoord;\n"
00054     "\n"
00055     "void main(void)\n"
00056     "{\n"
00057     "    texCoord = gl_MultiTexCoord0.xy;\n"
00058     "    gl_Position = ftransform();\n"
00059     "}\n";
00060
00061 std::string ShadowTreeHandler::_shadow_combine_fp =
00062     "uniform sampler2D colorMap;\n"
00063     "uniform sampler2D shadowFactorMap;\n"
00064     "uniform float xFactor;\n"
00065     "uniform float yFactor;\n"
00066     "uniform bool hasFactorMap;\n"
00067     "varying vec2 texCoord;\n"
00068     "\n"
00069     "void main(void)\n"
00070     "{\n"
00071     "    vec2 tc = texCoord * vec2(xFactor, yFactor);\n"
00072     "    vec3 color = texture2D(colorMap, tc).rgb;\n"
00073     "    color *= hasFactorMap ? (1.0 - texture2D(shadowFactorMap, tc).r) : 1.0;\n"
00074     "    gl_FragColor = vec4(color, 1.0);\n"
00075     "}\n";
00076
00077
00078
00079
00080 ShadowTreeHandler::ShadowTreeHandler(ShadowStage     *pSource,
00081                                      ShadowStageData *pData) :
00082      Inherited            (                      ),
00083
00084     _uiMode               (ShadowStage::NO_SHADOW),
00085     _uiMapSize            (0                     ),
00086     _bShadowMapsConfigured(false                 ),
00087     _activeFactorMap      (1                     ),
00088
00089     _width                (1                     ),
00090     _height               (1                     ),
00091
00092     _maxPLMapSize         (0                     ),
00093     _PLMapSize            (1                     ),
00094     _maxTexSize           (0                     ),
00095
00096     _pStage               (pSource               ),
00097     _pStageData           (pData                 ),
00098
00099     _colorMapO            (NULL                  ),
00100     _shadowFactorMapO     (NULL                  ),
00101     _shadowFactorMap2O    (NULL                  ),
00102
00103     _colorMapImage        (NULL                  ),
00104     _shadowFactorMapImage (NULL                  ),
00105     _shadowFactorMapImage2(NULL                  ),
00106
00107     _pSceneFBO            (NULL                  ),
00108
00109     _pClearBackground     (NULL                  ),
00110
00111     _unlitMat             (NULL                  ),
00112
00113     _combineSHL           (NULL                  ),
00114     _combineDepth         (NULL                  ),
00115     _combineCmat          (NULL                  ),
00116
00117     _aCubeTrans           (                      )
00118 {
00119     GLint   max_tex_size = 0;
00120
00121     glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_tex_size);
00122
00123     _maxTexSize   = max_tex_size;
00124     _maxPLMapSize = _maxTexSize / 4;
00125
00126     _unlitMat = SimpleMaterial::createLocal();
00127
00128     _unlitMat->setLit(false);
00129
00130     _pClearBackground = SolidBackground::createLocal();
00131
00132
00133     _aCubeTrans[0] = Matrix(1,  0,  0, 0,
00134                             0, -1,  0, 0,
00135                             0,  0, -1, 0,
00136                             0,  0,  0, 1);
00137
00138     _aCubeTrans[1] = Matrix(1, 0, 0, 0,
00139                             0, 1, 0, 0,
00140                             0, 0, 1, 0,
00141                             0, 0, 0, 1);
00142
00143     _aCubeTrans[2] = Matrix(1,  0, 0, 0,
00144                             0,  0, 1, 0,
00145                             0, -1, 0, 0,
00146                             0,  0, 0, 1);
00147
00148     _aCubeTrans[3] = Matrix(1, 0,  0, 0,
00149                             0, 0, -1, 0,
00150                             0, 1,  0, 0,
00151                             0, 0,  0, 1);
00152
00153     _aCubeTrans[4] = Matrix( 0, 0, 1, 0,
00154                              0, 1, 0, 0,
00155                             -1, 0, 0, 0,
00156                              0, 0, 0, 1);
00157
00158     _aCubeTrans[5] = Matrix(0, 0, -1, 0,
00159                             0, 1,  0, 0,
00160                             1, 0,  0, 0,
00161                             0, 0,  0, 1);
00162
00163     //Prepare Color Map grabbing
00164     _colorMapO     = TextureObjChunk::createLocal();
00165     _colorMapImage = Image          ::createLocal();
00166
00167     _colorMapO->setImage         (_colorMapImage);
00168     _colorMapO->setInternalFormat(GL_RGB);
00169     _colorMapO->setExternalFormat(GL_RGB);
00170     _colorMapO->setMinFilter     (GL_NEAREST);
00171     _colorMapO->setMagFilter     (GL_NEAREST);
00172     _colorMapO->setWrapS         (GL_REPEAT);
00173     _colorMapO->setWrapT         (GL_REPEAT);
00174     _colorMapO->setTarget        (GL_TEXTURE_2D);
00175
00176     //Prepare Shadow Factor Map grabbing
00177     _shadowFactorMapO     = TextureObjChunk::createLocal();
00178     _shadowFactorMapImage = Image          ::createLocal();
00179
00180     _shadowFactorMapO->setImage         (_shadowFactorMapImage);
00181     _shadowFactorMapO->setInternalFormat(GL_RGB);
00182     _shadowFactorMapO->setExternalFormat(GL_RGB);
00183     _shadowFactorMapO->setMinFilter     (GL_LINEAR);
00184     _shadowFactorMapO->setMagFilter     (GL_LINEAR);
00185     _shadowFactorMapO->setWrapS         (GL_REPEAT);
00186     _shadowFactorMapO->setWrapT         (GL_REPEAT);
00187     _shadowFactorMapO->setTarget        (GL_TEXTURE_2D);
00188
00189     //SHL Chunk 2
00190     _combineSHL = SimpleSHLChunk::createLocal();
00191     _combineSHL->setVertexProgram  (_shadow_combine_vp);
00192     _combineSHL->setFragmentProgram(_shadow_combine_fp);
00193
00194     _combineDepth = DepthChunk::createLocal();
00195     _combineDepth->setReadOnly(true);
00196
00197     //Combine Shader
00198     _combineCmat = ChunkMaterial::createLocal();
00199     _combineCmat->addChunk(_combineSHL);
00200     _combineCmat->addChunk(_colorMapO);
00201     _combineCmat->addChunk(_shadowFactorMapO);
00202     _combineCmat->addChunk(_combineDepth);
00203 }
00204
00205
00206 ShadowTreeHandler::~ShadowTreeHandler(void)
00207 {
00208     _pStage               = NULL;
00209     _pStageData           = NULL;
00210
00211     _colorMapO            = NULL;
00212     _shadowFactorMapO     = NULL;
00213     _shadowFactorMap2O    = NULL;
00214
00215     _colorMapImage         = NULL;
00216     _shadowFactorMapImage  = NULL;
00217     _shadowFactorMapImage2 = NULL;
00218
00219     _pSceneFBO             = NULL;
00220
00221     _pClearBackground      = NULL;
00222
00223     _unlitMat              = NULL;
00224
00225     _combineSHL            = NULL;
00226     _combineDepth          = NULL;
00227     _combineCmat           = NULL;
00228 }
00229
00230
00231
00232
00233
00234
00235
00236
00237 bool ShadowTreeHandler::initSceneFBO(DrawEnv *pEnv,
00238                                      bool     bHaveTwoFactorMaps)
00239 {
00240     Int32   width  = pEnv->getPixelWidth();
00241     Int32   height = pEnv->getPixelHeight();
00242
00243     if(width <= 0 || height <= 0)
00244         return false;
00245
00246     _width  = pEnv->getPixelWidth();
00247     _height = pEnv->getPixelHeight();
00248
00249
00250     _colorMapImage->set        (GL_RGB,
00251                                 _width, _height, 1,
00252                                 1, 1, 0.f,
00253                                 NULL,
00254                                 Image::OSG_UINT8_IMAGEDATA,
00255                                 false);
00256
00257     _shadowFactorMapImage->set (GL_RGB,
00258                                 _width, _height, 1,
00259                                 1, 1, 0.f,
00260                                 NULL,
00261                                 Image::OSG_UINT8_IMAGEDATA,
00262                                 false);
00263
00264     if(bHaveTwoFactorMaps == true)
00265     {
00266         _shadowFactorMapImage2->set( GL_RGB,
00267                                     _width, _height, 1,
00268                                      1, 1, 0.f,
00269                                      NULL,
00270                                      Image::OSG_UINT8_IMAGEDATA,
00271                                      false);
00272     }
00273
00274     _pSceneFBO = FrameBufferObject::createLocal();
00275
00276     _pSceneFBO->setSize(_width, _height);
00277
00278
00279     RenderBufferUnrecPtr pDepthRB = RenderBuffer::createLocal();
00280
00281     pDepthRB->setInternalFormat(GL_DEPTH_COMPONENT24);
00282
00283
00284     TextureBufferUnrecPtr pTexBuffer = TextureBuffer::createLocal();
00285
00286     pTexBuffer->setTexture(_colorMapO);
00287
00288     _pSceneFBO->setColorAttachment(pTexBuffer, 0);
00289
00290
00291     pTexBuffer = TextureBuffer::createLocal();
00292
00293     pTexBuffer->setTexture(_shadowFactorMapO);
00294
00295     _pSceneFBO->setColorAttachment(pTexBuffer, 1);
00296
00297
00298     if(bHaveTwoFactorMaps == true)
00299     {
00300         pTexBuffer = TextureBuffer::createLocal();
00301
00302         pTexBuffer->setTexture(_shadowFactorMap2O);
00303
00304         _pSceneFBO->setColorAttachment(pTexBuffer, 2);
00305     }
00306
00307     _pSceneFBO->setDepthAttachment(pDepthRB);
00308
00309
00310     commitChanges();
00311
00312     return true;
00313 }
00314
00315 void ShadowTreeHandler::updateSceneFBOSize(DrawEnv *pEnv,
00316                                            bool     bHaveTwoFactorMaps)
00317 {
00318     _width  = pEnv->getPixelWidth();
00319     _height = pEnv->getPixelHeight();
00320
00321
00322     _colorMapImage->set        (GL_RGB,
00323                                 _width, _height, 1,
00324                                 1, 1, 0.f,
00325                                 NULL,
00326                                 Image::OSG_UINT8_IMAGEDATA,
00327                                 false);
00328
00329     _shadowFactorMapImage->set (GL_RGB,
00330                                 _width, _height, 1,
00331                                 1, 1, 0.f,
00332                                 NULL,
00333                                 Image::OSG_UINT8_IMAGEDATA,
00334                                 false);
00335
00336     if(bHaveTwoFactorMaps == true)
00337     {
00338         _shadowFactorMapImage2->set( GL_RGB,
00339                                     _width, _height, 1,
00340                                      1, 1, 0.f,
00341                                      NULL,
00342                                      Image::OSG_UINT8_IMAGEDATA,
00343                                      false);
00344     }
00345
00346     _pSceneFBO->setSize(_width, _height);
00347 }
00348
00349
00350 void ShadowTreeHandler::initShadowMaps(void)
00351 {
00352     ShadowStageData::ShadowMapStore &vShadowMaps = _pStageData->getShadowMaps();
00353
00354     const ShadowStageData::LightStore  &vLights  = _pStageData->getLights();
00355
00356     if(vLights.size() < vShadowMaps.size())
00357     {
00358         vShadowMaps.resize(vLights.size());
00359     }
00360     else
00361     {
00362         UInt32 uiLSize   = vLights.size();
00363         UInt32 uiMapSize = _pStage->getMapSize ();
00364
00365         if(vShadowMaps.size() == 0)
00366         {
00367             _uiMapSize = uiMapSize;
00368         }
00369
00370         for(UInt32 i = vShadowMaps.size(); i < uiLSize; ++i)
00371         {
00372             if(vLights[i].second->getType() != PointLight::getClassType())
00373             {
00374                 ShadowStageData::ShadowMapElem tmpElem;
00375
00376                 tmpElem.pImage = Image            ::createLocal();
00377                 tmpElem.pTexO  = TextureObjChunk  ::createLocal();
00378                 tmpElem.pTexE  = TextureEnvChunk  ::createLocal();
00379                 tmpElem.pFBO   = FrameBufferObject::createLocal();
00380
00381
00382                 // creates a image without allocating main memory.
00383                 tmpElem.pImage->set(Image::OSG_L_PF,
00384                                     uiMapSize, uiMapSize, 1,
00385                                     1, 1, 0.f,
00386                                     NULL,
00387                                     Image::OSG_UINT8_IMAGEDATA,
00388                                     false);
00389
00390
00391
00392                 TextureBufferUnrecPtr pDepthTex = TextureBuffer::createLocal();
00393
00394                 pDepthTex->setTexture(tmpElem.pTexO);
00395
00396                 tmpElem.pFBO->setDepthAttachment(pDepthTex);
00397
00398             // Preparation of Texture be a Depth-Texture
00399                 tmpElem.pTexO->setImage         (tmpElem.pImage);
00400
00401                 tmpElem.pTexO->setInternalFormat(GL_DEPTH_COMPONENT);
00402                 tmpElem.pTexO->setExternalFormat(GL_DEPTH_COMPONENT);
00403
00404                 tmpElem.pTexO->setMinFilter     (GL_LINEAR);
00405                 tmpElem.pTexO->setMagFilter     (GL_LINEAR);
00406
00407                 tmpElem.pTexO->setWrapS         (GL_CLAMP_TO_EDGE);
00408                 tmpElem.pTexO->setWrapT         (GL_CLAMP_TO_EDGE);
00409
00410                 tmpElem.pTexO->setTarget        (GL_TEXTURE_2D);
00411
00412                 tmpElem.pTexE->setEnvMode       (GL_MODULATE);
00413
00414                 vShadowMaps.push_back(tmpElem);
00415             }
00416             else   //Light is a point light
00417             {
00418 #if 0
00419                 //TODO: Texturgr�se anpassen, je nach Bedarf
00420
00421                 GLint   max_texture_size;
00422
00423                 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
00424
00425 #endif
00426                 ShadowStageData::ShadowMapElem tmpElem;
00427
00428                 tmpElem.pImage = Image            ::createLocal();
00429                 tmpElem.pTexO  = TextureObjChunk  ::createLocal();
00430                 tmpElem.pTexE  = TextureEnvChunk  ::createLocal();
00431                 tmpElem.pFBO   = FrameBufferObject::createLocal();
00432
00433                 // creates a image without allocating main memory.
00434                 if((_uiMode == ShadowStage::STD_SHADOW_MAP         ||
00435                     _uiMode == ShadowStage::PERSPECTIVE_SHADOW_MAP ||
00436                     _uiMode == ShadowStage::DITHER_SHADOW_MAP      ||
00437                     _uiMode == ShadowStage::PCF_SHADOW_MAP         ))
00438                 {
00439                     tmpElem.pImage->set(Image::OSG_L_PF,
00440                                         uiMapSize, uiMapSize, 1,
00441                                         1, 1, 0.f,
00442                                         NULL,
00443                                         Image::OSG_UINT8_IMAGEDATA,
00444                                         false);
00445                 }
00446                 else
00447                 {
00448                     tmpElem.pImage->set(Image::OSG_L_PF,
00449                                         uiMapSize, uiMapSize, 1,
00450                                         1, 1, 0.f,
00451                                         NULL,
00452                                         Image::OSG_UINT8_IMAGEDATA,
00453                                         false);
00454                 }
00455
00456                 TextureBufferUnrecPtr pDepthTex = TextureBuffer::createLocal();
00457
00458                 pDepthTex->setTexture(tmpElem.pTexO);
00459
00460                 tmpElem.pFBO->setDepthAttachment(pDepthTex);
00461
00462                 // Preparation of Texture be a Depth-Texture
00463                 tmpElem.pTexO->setImage(tmpElem.pImage);
00464
00465                 tmpElem.pTexO->setInternalFormat(GL_DEPTH_COMPONENT);
00466                 tmpElem.pTexO->setExternalFormat(GL_DEPTH_COMPONENT);
00467
00468                 tmpElem.pTexO->setMinFilter     (GL_LINEAR);
00469                 tmpElem.pTexO->setMagFilter     (GL_LINEAR);
00470
00471                 tmpElem.pTexO->setWrapS         (GL_CLAMP_TO_BORDER);
00472                 tmpElem.pTexO->setWrapT         (GL_CLAMP_TO_BORDER);
00473
00474                 tmpElem.pTexE->setEnvMode       (GL_MODULATE);
00475
00476                 tmpElem.pTexO->setTarget        (GL_TEXTURE_2D);
00477
00478                 vShadowMaps.push_back(tmpElem);
00479             }
00480
00481         }
00482     }
00483 }
00484
00485 void ShadowTreeHandler::updateShadowMapSize(void)
00486 {
00487     ShadowStageData::ShadowMapStore &vShadowMaps = _pStageData->getShadowMaps();
00488
00489     UInt32 uiSHMSize    =  vShadowMaps.size();
00490      Int32 uiNewMapSize = _pStage->getMapSize();
00491
00492     for(UInt32 i = 0; i < uiSHMSize; ++i)
00493     {
00494         if(vShadowMaps[i].pImage->getWidth() != uiNewMapSize)
00495         {
00496             vShadowMaps[i].pImage->set(Image::OSG_L_PF,
00497                                        uiNewMapSize, uiNewMapSize, 1,
00498                                        1, 1, 0.f,
00499                                        NULL,
00500                                        Image::OSG_UINT8_IMAGEDATA,
00501                                        false);
00502         }
00503     }
00504
00505     _uiMapSize = uiNewMapSize;
00506 }
00507
00508 void ShadowTreeHandler::configureShadowMaps(void)
00509 {
00510     ShadowStageData::ShadowMapStore &vShadowMaps = _pStageData->getShadowMaps();
00511
00512     const ShadowStageData::LightStore  &vLights  = _pStageData->getLights();
00513
00514     UInt32 uiSHMSize = vShadowMaps.size();
00515
00516     UInt32 uiMapSize = _pStage-> getMapSize ();
00517
00518     for(UInt32 i = 0; i < uiSHMSize; ++i)
00519     {
00520         vShadowMaps[i].pTexO->setCompareMode(GL_COMPARE_R_TO_TEXTURE);
00521         vShadowMaps[i].pTexO->setCompareFunc(GL_LEQUAL              );
00522         vShadowMaps[i].pTexO->setDepthMode  (GL_LUMINANCE           );
00523
00524         vShadowMaps[i].pTexO->setMinFilter  (GL_LINEAR);
00525         vShadowMaps[i].pTexO->setMagFilter  (GL_LINEAR);
00526
00527         if(vShadowMaps[i].uiType ==
00528                                 ShadowStageData::ShadowMapElem::ColorShadowMap)
00529         {
00530             vShadowMaps[i].pTexO->setInternalFormat(GL_DEPTH_COMPONENT);
00531             vShadowMaps[i].pTexO->setExternalFormat(GL_DEPTH_COMPONENT);
00532
00533             if(vLights[i].second->getType() != PointLight::getClassType())
00534             {
00535                 vShadowMaps[i].pTexO->setWrapS(GL_CLAMP_TO_EDGE);
00536                 vShadowMaps[i].pTexO->setWrapT(GL_CLAMP_TO_EDGE);
00537             }
00538             else
00539             {
00540                 vShadowMaps[i].pTexO->setWrapS(GL_CLAMP_TO_BORDER);
00541                 vShadowMaps[i].pTexO->setWrapT(GL_CLAMP_TO_BORDER);
00542             }
00543
00544             vShadowMaps[i].pTexO->setAnisotropy(1.0);
00545
00546             vShadowMaps[i].pImage->set(Image::OSG_L_PF,
00547                                        uiMapSize, uiMapSize, 1,
00548                                        1, 1, 0.f,
00549                                        NULL,
00550                                        Image::OSG_UINT8_IMAGEDATA,
00551                                        false);
00552
00553             vShadowMaps[i].pFBO->setDepthAttachment(
00554                 vShadowMaps[i].pFBO->getColorAttachments(0));
00555
00556             vShadowMaps[i].pFBO->setColorAttachment(NULL, 0);
00557
00558             vShadowMaps[i].uiType =
00559                                 ShadowStageData::ShadowMapElem::DepthShadowMap;
00560         }
00561     }
00562
00563     _bShadowMapsConfigured = true;
00564 }
00565
00566
00567 void ShadowTreeHandler::setupDrawCombineMap2(Action  *pAction)
00568 {
00569     RenderAction *a = dynamic_cast<RenderAction *>(pAction);
00570
00571     a->pushPartition((RenderPartition::CopyWindow       |
00572                       RenderPartition::CopyViewportSize |
00573                       RenderPartition::CopyTarget       ),
00574                      RenderPartition::SimpleCallback);
00575     {
00576         RenderPartition *pPart  = a->getActivePartition();
00577
00578         pPart->addPreRenderCallback (
00579             &ShadowTreeHandler::setupAmbientModel);
00580         pPart->addPostRenderCallback(
00581             &ShadowTreeHandler::endAmbientModel  );
00582
00583         Matrix m, t;
00584
00585         m.setIdentity();
00586         t.setIdentity();
00587
00588         MatrixOrthogonal( m,
00589                           0.f, 1.f,
00590                           0.f, 1.f,
00591                          -1.f, 1.f);
00592
00593         pPart->setupProjection(m, t);
00594
00595         RenderPartition::SimpleDrawCallback f;
00596
00597         f = boost::bind(&ShadowTreeHandler::doDrawCombineMap2, this, _1);
00598
00599         pPart->dropFunctor(f);
00600     }
00601     a->popPartition();
00602 }
00603
00604 void ShadowTreeHandler::doDrawCombineMap2(DrawEnv *pEnv)
00605 {
00606     Real32  xFactor = 1.0f;
00607     Real32  yFactor = 1.0f;
00608
00609     _combineCmat->clearChunks();
00610
00611     _combineCmat->addChunk(_combineSHL);
00612     _combineCmat->addChunk(_colorMapO);
00613
00614     if(_activeFactorMap == 0)
00615     {
00616         _combineCmat->addChunk(_shadowFactorMap2O);
00617     }
00618     else
00619     {
00620         _combineCmat->addChunk(_shadowFactorMapO);
00621     }
00622
00623     _combineCmat->addChunk(_combineDepth);
00624
00625     _combineSHL->addUniformVariable("colorMap",        0);
00626     _combineSHL->addUniformVariable("shadowFactorMap", 1);
00627     _combineSHL->addUniformVariable("xFactor",         Real32(xFactor));
00628     _combineSHL->addUniformVariable("yFactor",         Real32(yFactor));
00629     _combineSHL->addUniformVariable("hasFactorMap",    hasFactorMap());
00630
00631     commitChanges();
00632
00633     glMatrixMode(GL_MODELVIEW);
00634     glPushMatrix();
00635
00636     glLoadIdentity();
00637
00638     State *pCombineState = _combineCmat->getState();
00639
00640     pEnv->activateState(pCombineState, NULL);
00641
00642     glBegin(GL_QUADS);
00643     {
00644         glTexCoord2f(0.00, 0.00);
00645         glVertex2f  (0.00, 0.00);
00646
00647         glTexCoord2f(1.00, 0.00);
00648         glVertex2f  (1.00, 0.00);
00649
00650         glTexCoord2f(1.00, 1.00);
00651         glVertex2f  (1.00, 1.00);
00652
00653         glTexCoord2f(0.00, 1.00);
00654         glVertex2f  (0.00, 1.00);
00655     }
00656     glEnd();
00657
00658     pEnv->deactivateState();
00659
00660     glPopMatrix();
00661 }
00662
00663
00664 void ShadowTreeHandler::setupDrawCombineMap1(Action  *pAction)
00665 {
00666     RenderAction *a = dynamic_cast<RenderAction *>(pAction);
00667
00668     a->pushPartition((RenderPartition::CopyWindow      |
00669                       RenderPartition::CopyViewportSize |
00670                       RenderPartition::CopyTarget       ),
00671                      RenderPartition::SimpleCallback);
00672     {
00673         RenderPartition *pPart  = a->getActivePartition();
00674
00675         pPart->addPreRenderCallback (
00676             &ShadowTreeHandler::setupAmbientModel);
00677         pPart->addPostRenderCallback(
00678             &ShadowTreeHandler::endAmbientModel  );
00679
00680         Matrix m, t;
00681
00682         m.setIdentity();
00683         t.setIdentity();
00684
00685         MatrixOrthogonal( m,
00686                           0.f, 1.f,
00687                           0.f, 1.f,
00688                          -1.f, 1.f);
00689
00690         pPart->setupProjection(m, t);
00691
00692         RenderPartition::SimpleDrawCallback f;
00693
00694         f = boost::bind(&ShadowTreeHandler::doDrawCombineMap1, this, _1);
00695
00696         pPart->dropFunctor(f);
00697     }
00698     a->popPartition();
00699 }
00700
00701 void ShadowTreeHandler::doDrawCombineMap1(DrawEnv *pEnv)
00702 {
00703     Real32  xFactor = 1.0f;
00704     Real32  yFactor = 1.0f;
00705
00706     _combineSHL->addUniformVariable("colorMap",        0);
00707     _combineSHL->addUniformVariable("shadowFactorMap", 1);
00708     _combineSHL->addUniformVariable("xFactor",         Real32(xFactor));
00709     _combineSHL->addUniformVariable("yFactor",         Real32(yFactor));
00710     _combineSHL->addUniformVariable("hasFactorMap",    hasFactorMap());
00711
00712     commitChanges();
00713
00714     glMatrixMode(GL_MODELVIEW);
00715     glPushMatrix();
00716
00717     glLoadIdentity();
00718
00719     State *pCombineState = _combineCmat->getState();
00720
00721     pEnv->activateState(pCombineState, NULL);
00722
00723     glBegin(GL_QUADS);
00724     {
00725         glTexCoord2f(0.00, 0.00);
00726         glVertex2f  (0.00, 0.00);
00727
00728         glTexCoord2f(1.00, 0.00);
00729         glVertex2f  (1.00, 0.00);
00730
00731         glTexCoord2f(1.00, 1.00);
00732         glVertex2f  (1.00, 1.00);
00733
00734         glTexCoord2f(0.00, 1.00);
00735         glVertex2f  (0.00, 1.00);
00736     }
00737     glEnd();
00738
00739     pEnv->deactivateState();
00740
00741     glPopMatrix();
00742 }
00743
00744 bool ShadowTreeHandler::hasFactorMap(void)
00745 {
00746     const ShadowStageData::LightStore  &vLights      =
00747         _pStageData->getLights();
00748
00749     const ShadowStageData::LStateStore &vLightStates =
00750         _pStageData->getLightStates();
00751
00752     for(UInt32 i = 0;i < vLights.size();i++)
00753     {
00754         if (vLightStates[i] != 0 &&
00755             (vLights[i].second->getShadowIntensity() != 0.0 ||
00756              _pStage->getGlobalShadowIntensity() != 0.0))
00757         {
00758             return true;
00759         }
00760     }
00761
00762     return false;
00763 }
00764
00765 void ShadowTreeHandler::setupAmbientModel(DrawEnv *pEnv)
00766 {
00767     glPushAttrib(GL_ENABLE_BIT);
00768
00769     GLfloat globalAmbient[] =
00770     {
00771         0.0, 0.0, 0.0, 1.0
00772     };
00773
00774     glLightModelfv(GL_LIGHT_MODEL_AMBIENT, globalAmbient);
00775 }
00776
00777 void ShadowTreeHandler::setupAmbientModelAndMasks(DrawEnv *pEnv)
00778 {
00779     glPushAttrib(GL_ENABLE_BIT);
00780
00781     GLfloat globalAmbient[] =
00782     {
00783         0.0, 0.0, 0.0, 1.0
00784     };
00785
00786     glLightModelfv(GL_LIGHT_MODEL_AMBIENT, globalAmbient);
00787
00788     glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
00789     glShadeModel(GL_FLAT                               );
00790     glDisable   (GL_LIGHTING                           );
00791     glDepthMask (GL_TRUE                               );
00792 }
00793
00794 void ShadowTreeHandler::endAmbientModel(DrawEnv *pEnv)
00795 {
00796     glPopAttrib();
00797 }
00798
00799 void ShadowTreeHandler::endAmbientModelAndMasks(DrawEnv *pEnv)
00800 {
00801     glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
00802     glShadeModel(GL_SMOOTH                         );
00803
00804     glPopAttrib();
00805 }
00806
00807 OSG_END_NAMESPACE