OSGDeferredShadingStage.cpp

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002  *                                OpenSG                                     *
00003  *                                                                           *
00004  *                                                                           *
00005  *               Copyright (C) 2000-2006 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 //---------------------------------------------------------------------------
00040 //  Includes
00041 //---------------------------------------------------------------------------
00042
00043 #include "OSGConfig.h"
00044
00045 #include "OSGDeferredShadingStage.h"
00046 #include "OSGShaderShadowMapEngine.h"
00047
00048 #include "OSGBlendChunk.h"
00049 #include "OSGChunkMaterial.h"
00050 #include "OSGDirectionalLight.h"
00051 #include "OSGMatrixUtility.h"
00052 #include "OSGOrthographicCamera.h"
00053 #include "OSGPointLight.h"
00054 #include "OSGRenderBuffer.h"
00055 #include "OSGSolidBackground.h"
00056 #include "OSGSpotLight.h"
00057 #include "OSGTransform.h"
00058 #include "OSGDepthChunk.h"
00059
00060 OSG_BEGIN_NAMESPACE
00061
00062 // Documentation for this class is emitted in the
00063 // OSGDeferredShadingStageBase.cpp file.
00064 // To modify it, please change the .fcd file (OSGDeferredShadingStage.fcd) and
00065 // regenerate the base file.
00066
00067 /***************************************************************************\
00068  *                           Class variables                               *
00069 \***************************************************************************/
00070
00071 /***************************************************************************\
00072  *                           Class methods                                 *
00073 \***************************************************************************/
00074
00075 void DeferredShadingStage::initMethod(InitPhase ePhase)
00076 {
00077     Inherited::initMethod(ePhase);
00078
00079     if(ePhase == TypeObject::SystemPost)
00080     {
00081         RenderAction::registerEnterDefault(
00082             DeferredShadingStage::getClassType(),
00083             reinterpret_cast<Action::Callback>(&DeferredShadingStage::renderEnter));
00084         RenderAction::registerLeaveDefault(
00085             DeferredShadingStage::getClassType(),
00086             reinterpret_cast<Action::Callback>(&DeferredShadingStage::renderLeave));
00087     }
00088 }
00089
00090
00091 /***************************************************************************\
00092  *                           Instance methods                              *
00093 \***************************************************************************/
00094
00095 /*-------------------------------------------------------------------------*\
00096  -  private                                                                 -
00097 \*-------------------------------------------------------------------------*/
00098
00099 /*----------------------- constructors & destructors ----------------------*/
00100
00101 DeferredShadingStage::DeferredShadingStage(void) :
00102     Inherited         (                                ),
00103     _changeCache      (TypeTraits<BitVector>::BitsClear),
00104     _targetSizeChanged(false                           )
00105 {
00106 }
00107
00108 DeferredShadingStage::DeferredShadingStage(const DeferredShadingStage &source) :
00109     Inherited         (source                          ),
00110     _changeCache      (TypeTraits<BitVector>::BitsClear),
00111     _targetSizeChanged(false                           )
00112 {
00113 }
00114
00115 DeferredShadingStage::~DeferredShadingStage(void)
00116 {
00117 }
00118
00119 /*----------------------------- class specific ----------------------------*/
00120
00121 void DeferredShadingStage::changed(ConstFieldMaskArg whichField,
00122                                    UInt32            origin,
00123                                    BitVector         details)
00124 {
00125     _changeCache |= (whichField & (PixelFormatsFieldMask   |
00126                                    PixelTypesFieldMask     |
00127                                    GBufferProgramFieldMask |
00128                                    AmbientProgramFieldMask |
00129                                    LightProgramsFieldMask  |
00130                                    LightsFieldMask         |
00131                                    Inherited::RenderTargetFieldMask));
00132
00133     if((whichField & Inherited::RenderTargetFieldMask) != 0)
00134     {
00135         _targetSizeChanged = true;
00136     }
00137
00138     Inherited::changed(whichField, origin, details);
00139 }
00140
00141 void DeferredShadingStage::dump(      UInt32    ,
00142                                 const BitVector ) const
00143 {
00144     SLOG << "Dump DeferredShadingStage NI" << std::endl;
00145 }
00146
00147 ActionBase::ResultE DeferredShadingStage::renderEnter(Action *action)
00148 {
00149     RenderAction *ract = dynamic_cast<RenderAction *>(action);
00150
00151     if(ract == NULL)
00152         return Action::Continue;
00153
00154     RenderPartition   *parentPart = ract->getActivePartition();
00155     FrameBufferObject *target     = this->getRenderTarget   ();
00156
00157     if(target == NULL && this->getInheritedTarget() == true)
00158     {
00159         target = parentPart->getRenderTarget();
00160     }
00161
00162     DSStageData *data = ract->getData<DSStageData *>(_iDataSlotId);
00163
00164     if(data == NULL)
00165     {
00166         DSStageDataUnrecPtr newData = createStageData();
00167         data = newData;
00168
00169         setData(newData, _iDataSlotId, ract);
00170     }
00171
00172     updateStageData(data, target, parentPart);
00173
00174     ract->beginPartitionGroup();
00175     {
00176         // render the tree below this to gBufferTarget using gBufferShader
00177         scheduleGBufferPass(ract);
00178
00179         // render a quad to this stage's target using shadingShader
00180         scheduleShadingPass(ract);
00181     }
00182     ract->endPartitionGroup();
00183
00184     commitChanges();
00185
00186     return Action::Skip;
00187 }
00188
00189 ActionBase::ResultE DeferredShadingStage::renderLeave(Action *action)
00190 {
00191     return Action::Continue;
00192 }
00193
00194 DeferredShadingStage::DSStageDataTransitPtr
00195     DeferredShadingStage::createStageData(void)
00196 {
00197     DSStageDataTransitPtr              data              =
00198         DSStageData::createLocal();
00199     FrameBufferObjectUnrecPtr          gBufferTarget     =
00200         FrameBufferObject::createLocal();
00201     RenderBufferUnrecPtr               gBufferDepth      =
00202         RenderBuffer::createLocal();
00203     SolidBackgroundUnrecPtr            gBufferBackground =
00204         SolidBackground::createLocal();
00205     BlendChunkUnrecPtr                 shadingBlendChunk =
00206         BlendChunk::createLocal();
00207
00208     gBufferDepth     ->setInternalFormat (GL_DEPTH_COMPONENT24);
00209     gBufferTarget    ->setDepthAttachment(gBufferDepth        );
00210
00211     gBufferBackground->setColor(Color3r(0.0f, 0.0f, 0.0f));
00212
00213     shadingBlendChunk->setSrcFactor (GL_ONE);
00214     shadingBlendChunk->setDestFactor(GL_ONE);
00215
00216     data->setGBufferTarget    (gBufferTarget    );
00217     data->setGBufferBackground(gBufferBackground);
00218
00219     data->setBlendChunk       (shadingBlendChunk);
00220
00221     return data;
00222 }
00223
00224 TextureBufferTransitPtr DeferredShadingStage::createGBuffer(
00225     UInt32 index, Int32 width, Int32 height)
00226 {
00227     TextureBufferTransitPtr buf    = TextureBuffer  ::createLocal();
00228     TextureObjChunkUnrecPtr bufTex = TextureObjChunk::createLocal();
00229     ImageUnrecPtr           bufImg = Image          ::createLocal();
00230
00231     bufImg->set(_mfPixelFormats[index],
00232                 width,
00233                 height,
00234                 1,
00235                 1,
00236                 1,
00237                 0.0f,
00238                 NULL,
00239                 _mfPixelTypes[index],
00240                 false,
00241                 1);
00242
00243     bufTex->setImage    (bufImg                  );
00244     bufTex->setTarget   (GL_TEXTURE_RECTANGLE_ARB);
00245     bufTex->setMinFilter(GL_NEAREST              );
00246     bufTex->setMagFilter(GL_NEAREST              );
00247     bufTex->setWrapS    (GL_CLAMP                );
00248     bufTex->setWrapT    (GL_CLAMP                );
00249     bufTex->setScale    (false                   );
00250
00251     buf   ->setTexture  (bufTex                  );
00252
00253 // START DEBUG
00254     GLenum internalFormat;
00255     GLenum externalFormat;
00256
00257     bufTex->determineFormats(internalFormat, externalFormat);
00258
00259     FLOG(("DSStage::createGBuffer: IF [%s] EF [%s]\n",
00260         GLDefineMapper::the()->toString(internalFormat).c_str(),
00261         GLDefineMapper::the()->toString(externalFormat).c_str() ));
00262 // END DEBUG
00263
00264     return buf;
00265 }
00266
00267 void DeferredShadingStage::updateStageData(
00268     DSStageData         *data,
00269     FrameBufferObject   *shadingTarget,
00270     RenderPartition     *parentPart    )
00271 {
00272     FrameBufferObject *gBufferTarget = data->getGBufferTarget();
00273
00274     Int32 targetWidth;
00275     Int32 targetHeight;
00276     Int32 targetLeft;
00277     Int32 targetBottom;
00278
00279     if(shadingTarget != NULL)
00280     {
00281         targetWidth  = shadingTarget->getWidth ();
00282         targetHeight = shadingTarget->getHeight();
00283
00284         targetLeft   = 0;
00285         targetBottom = 0;
00286     }
00287     else
00288     {
00289         targetWidth  = parentPart->getDrawEnv().getPixelWidth ();
00290         targetHeight = parentPart->getDrawEnv().getPixelHeight();
00291
00292         targetLeft   = parentPart->getDrawEnv().getPixelLeft  ();
00293         targetBottom = parentPart->getDrawEnv().getPixelBottom();
00294     }
00295
00296     if(gBufferTarget->getWidth () != targetWidth ||
00297        gBufferTarget->getHeight() != targetHeight  )
00298     {
00299         _targetSizeChanged = true;
00300     }
00301
00302     if(_targetSizeChanged == true)
00303     {
00304         gBufferTarget->setSize(targetWidth, targetHeight);
00305     }
00306
00307     if(getMFPixelFormats()->size() != getMFPixelTypes()->size())
00308     {
00309         SWARNING << "DeferredShadingStage::updateStageData: "
00310                  << "Number of PixelFormats and PixelTypes inconsistent."
00311                  << std::endl;
00312     }
00313
00314     UInt32 lightCount  =        getMFLights      ()->size();
00315     UInt32 bufferCount = osgMin(getMFPixelFormats()->size(),
00316                                 getMFPixelTypes  ()->size() );
00317
00318     // buffers changed - remove them here, recreate below
00319     if((_changeCache & (PixelFormatsFieldMask |
00320                         PixelTypesFieldMask    )) != 0)
00321     {
00322         gBufferTarget->editMFColorAttachments()->clear (                    );
00323         gBufferTarget->editMFColorAttachments()->resize(bufferCount, NULL   );
00324         gBufferTarget->editMFDrawBuffers     ()->clear (                    );
00325         gBufferTarget->editMFDrawBuffers     ()->resize(bufferCount, GL_NONE);
00326     }
00327
00328     for(UInt32 i = 0; i < bufferCount; ++i)
00329     {
00330         TextureBuffer *buf =
00331             dynamic_cast<TextureBuffer *>(gBufferTarget->getColorAttachments(i));
00332
00333         if(buf == NULL)
00334         {
00335             TextureBufferUnrecPtr newBuf =
00336                 createGBuffer(i, targetWidth, targetHeight);
00337             buf = newBuf;
00338
00339             gBufferTarget->editMFColorAttachments()->replace(i, newBuf                      );
00340             gBufferTarget->editMFDrawBuffers     ()->replace(i, GL_COLOR_ATTACHMENT0_EXT + i);
00341         }
00342         else
00343         {
00344             updateGBuffer(buf, i, targetWidth, targetHeight);
00345         }
00346     }
00347
00348     if((_changeCache & LightsFieldMask) != 0)
00349     {
00350         data->editMFLightChunks         ()->resize(    lightCount, NULL);
00351         data->editMFShadingStates       ()->resize(1 + lightCount, NULL);
00352         data->editMFShadingProgramChunks()->resize(1 + lightCount, NULL);
00353     }
00354
00355     // update shading states
00356     if((_changeCache & (PixelFormatsFieldMask   |
00357                         PixelTypesFieldMask     |
00358                         AmbientProgramFieldMask |
00359                         LightProgramsFieldMask  |
00360                         LightsFieldMask          )) != 0)
00361     {
00362         // copy ambient and light programs
00363         DSStageData::MFShadingProgramChunksType::const_iterator spcIt  =
00364             data->editMFShadingProgramChunks()->begin();
00365         DSStageData::MFShadingProgramChunksType::const_iterator spcEnd =
00366             data->editMFShadingProgramChunks()->end  ();
00367
00368         for(UInt32 progIdx = 0; spcIt != spcEnd; ++spcIt, ++progIdx)
00369         {
00370             if(*spcIt == NULL)
00371             {
00372                 ShaderProgramChunkUnrecPtr newSPC =
00373                     ShaderProgramChunk::createLocal();
00374                 //*spcIt = newSPC;
00375
00376                 data->editMFShadingProgramChunks()->replace(progIdx, newSPC);
00377             }
00378
00379             (*spcIt)->clearVertexShaders  ();
00380             (*spcIt)->clearGeometryShaders();
00381             (*spcIt)->clearFragmentShaders();
00382
00383             if(progIdx == 0 && getAmbientProgram() != NULL)
00384             {
00385                 // ambient program
00386                 copyProgramChunk(*spcIt, getAmbientProgram());
00387
00388                 // TODO: there must be a better way to add this uniform
00389                 (*spcIt)->getFragmentShader(0)->addUniformVariable(
00390                     "vpOffset", Vec2f(targetLeft,
00391                                       targetBottom));
00392             }
00393             else
00394             {
00395                 // light programs
00396                 if(_mfLightPrograms.size() == 1)
00397                 {
00398                     copyProgramChunk(*spcIt, getLightPrograms(0));
00399
00400                     // TODO: there must be a better way to add this uniform
00401                     (*spcIt)->getFragmentShader(0)->addUniformVariable(
00402                         "vpOffset", Vec2f(targetLeft,
00403                                           targetBottom));
00404                 }
00405                 else if(_mfLightPrograms.size() == _mfLights.size())
00406                 {
00407                     copyProgramChunk(*spcIt, getLightPrograms(progIdx - 1));
00408
00409                     // TODO: there must be a better way to add this uniform
00410                     (*spcIt)->getFragmentShader(0)->addUniformVariable(
00411                         "vpOffset", Vec2f(targetLeft,
00412                                           targetBottom));
00413                 }
00414                 else
00415                 {
00416                     SWARNING << "DeferredShadingStage::updateStageData: "
00417                              << "Number of Lights and LightPrograms "
00418                              << "inconsistent." << std::endl;
00419                 }
00420             }
00421         }
00422
00423         // create light chunks
00424         DSStageData::MFLightChunksType::const_iterator lcIt  =
00425             data->editMFLightChunks()->begin();
00426         DSStageData::MFLightChunksType::const_iterator lcEnd =
00427             data->editMFLightChunks()->end  ();
00428
00429         for(UInt32 lightIdx = 0; lcIt != lcEnd; ++lcIt, ++lightIdx)
00430         {
00431             if(*lcIt == NULL)
00432             {
00433                 DSLightChunkUnrecPtr newLC = DSLightChunk::createLocal();
00434                 //*lcIt = newLC;
00435                 data->editMFLightChunks()->replace(lightIdx, newLC);
00436             }
00437
00438             updateLightChunk(*lcIt, getLights(lightIdx));
00439         }
00440
00441         // populate shading states
00442         DSStageData::MFShadingStatesType::const_iterator stateIt  =
00443             data->editMFShadingStates()->begin();
00444         DSStageData::MFShadingStatesType::const_iterator stateEnd =
00445             data->editMFShadingStates()->end  ();
00446
00447         for(UInt32 stateIdx = 0; stateIt != stateEnd; ++stateIt, ++stateIdx)
00448         {
00449             if(*stateIt == NULL)
00450             {
00451                 StateUnrecPtr newState = State::createLocal();
00452                 //*stateIt = newState;
00453                 data->editMFShadingStates()->replace(stateIdx, newState);
00454             }
00455
00456             // remove all chunks
00457             (*stateIt)->clearChunks();
00458
00459             // add G Buffer textures
00460             for(UInt32 bufferIdx = 0;
00461                 bufferIdx < bufferCount; ++bufferIdx)
00462             {
00463                 TextureBuffer   *buf    = static_cast<TextureBuffer *>(
00464                     gBufferTarget->getColorAttachments(bufferIdx));
00465                 TextureObjChunk *bufTex = buf->getTexture();
00466
00467                 (*stateIt)->addChunk(bufTex, bufferIdx);
00468             }
00469
00470             // add ambient/light programs and light chunks
00471             if(stateIdx == 0)
00472             {
00473                 if(getAmbientProgram() != NULL)
00474                 {
00475                     (*stateIt)->addChunk(
00476                         data->getShadingProgramChunks(stateIdx));
00477                 }
00478             }
00479             else
00480             {
00481                 (*stateIt)->addChunk(
00482                     data->getShadingProgramChunks(stateIdx    ));
00483                 (*stateIt)->addChunk(
00484                     data->getLightChunks         (stateIdx - 1));
00485             }
00486
00487             // add blend chunk to light states
00488             if(stateIdx > 0)
00489             {
00490                 (*stateIt)->addChunk(data->getBlendChunk());
00491             }
00492         }
00493     }
00494
00495     _changeCache       = TypeTraits<BitVector>::BitsClear;
00496     _targetSizeChanged = false;
00497 }
00498
00499 void DeferredShadingStage::updateGBuffer(
00500     TextureBuffer *buf, UInt32 index, Int32 width, Int32 height)
00501 {
00502     TextureObjChunk *bufTex = buf   ->getTexture();
00503     Image           *bufImg = bufTex->getImage  ();
00504
00505     if((_changeCache & (PixelFormatsFieldMask |
00506                         PixelTypesFieldMask    )) != 0)
00507     {
00508         bufImg->setPixelFormat(_mfPixelFormats[index]);
00509         bufImg->setDataType   (_mfPixelTypes  [index]);
00510     }
00511
00512     if(_targetSizeChanged == true)
00513     {
00514         bufImg->setWidth (width );
00515         bufImg->setHeight(height);
00516     }
00517 }
00518
00528 void DeferredShadingStage::updateLightChunk(
00529     DSLightChunk *lightChunk, Light *light)
00530 {
00531     lightChunk->setBeacon  (light->getBeacon  ());
00532     lightChunk->setAmbient (light->getAmbient ());
00533     lightChunk->setDiffuse (light->getDiffuse ());
00534     lightChunk->setSpecular(light->getSpecular());
00535
00536     if(light->getType() == DirectionalLight::getClassType())
00537     {
00538         DirectionalLight *dirL = static_cast<DirectionalLight *>(light);
00539
00540         Vec4r dir(dirL->getDirection());
00541         dir[3] = 0.f;
00542
00543         lightChunk->setPosition(dir);
00544     }
00545     else if(light->getType() == PointLight::getClassType())
00546     {
00547         PointLight *pointL = static_cast<PointLight *>(light);
00548
00549         Vec4r pos(pointL->getPosition());
00550         pos[3] = 1.f;
00551
00552         lightChunk->setPosition            (pos                              );
00553         lightChunk->setConstantAttenuation (pointL->getConstantAttenuation ());
00554         lightChunk->setLinearAttenuation   (pointL->getLinearAttenuation   ());
00555         lightChunk->setQuadraticAttenuation(pointL->getQuadraticAttenuation());
00556         lightChunk->setCutoff              (180.f                            );
00557     }
00558     else if(light->getType() == SpotLight::getClassType())
00559     {
00560         SpotLight *spotL = static_cast<SpotLight *>(light);
00561
00562         Vec4r pos(spotL->getPosition());
00563         pos[3] = 1.f;
00564
00565         lightChunk->setPosition            (pos                             );
00566         lightChunk->setConstantAttenuation (spotL->getConstantAttenuation ());
00567         lightChunk->setLinearAttenuation   (spotL->getLinearAttenuation   ());
00568         lightChunk->setQuadraticAttenuation(spotL->getQuadraticAttenuation());
00569         lightChunk->setDirection           (spotL->getDirection           ());
00570         lightChunk->setExponent            (spotL->getSpotExponent        ());
00571         lightChunk->setCutoff              (
00572             osgRad2Degree(spotL->getSpotCutOff()));
00573     }
00574     else
00575     {
00576         SWARNING << "DeferredShadingStage::updateLightChunk: "
00577                  << "Unknown light type." << endLog;
00578     }
00579 }
00580
00581 void DeferredShadingStage::copyProgramChunk(
00582     ShaderProgramChunk *spcDest, ShaderProgramChunk *spcSource)
00583 {
00584     ShaderProgramChunk::MFVertexShaderType::const_iterator vsIt  =
00585         spcSource->getMFVertexShader()->begin();
00586     ShaderProgramChunk::MFVertexShaderType::const_iterator vsEnd =
00587         spcSource->getMFVertexShader()->end  ();
00588
00589     for(; vsIt != vsEnd; ++vsIt)
00590     {
00591         spcDest->addVertexShader(*vsIt);
00592     }
00593
00594     ShaderProgramChunk::MFFragmentShaderType::const_iterator fsIt  =
00595         spcSource->getMFFragmentShader()->begin();
00596     ShaderProgramChunk::MFFragmentShaderType::const_iterator fsEnd =
00597         spcSource->getMFFragmentShader()->end  ();
00598
00599     for(; fsIt != fsEnd; ++fsIt)
00600     {
00601         spcDest->addFragmentShader(*fsIt);
00602     }
00603 }
00604
00605
00606 void DeferredShadingStage::scheduleGBufferPass(RenderAction *ract)
00607 {
00608 #if 0
00609     RenderPartition    *parentPart  = ract->getActivePartition();
00610 #endif
00611     DSStageData        *data        = ract->getData<DSStageData *>(_iDataSlotId);
00612     ShaderProgramChunk *shader      = this->getGBufferProgram();
00613 #if 0
00614     UInt32              bufferCount = osgMin(getMFPixelFormats()->size(),
00615                                              getMFPixelTypes  ()->size() );
00616 #endif
00617 
00618     // create shadow maps
00619     MFLightsType::const_iterator lIt         = _mfLights.begin();
00620     MFLightsType::const_iterator lEnd        = _mfLights.end  ();
00621
00622     for(UInt32 i = 0; lIt != lEnd; ++lIt, ++i)
00623     {
00624         (*lIt)->callLightEngineEnter(ract);
00625
00626         ShaderProgramChunk    *spc   = data->getShadingProgramChunks(1+i);
00627         State                 *state = data->getShadingStates       (1+i);
00628         ShaderShadowMapEngine *sme   = dynamic_cast<ShaderShadowMapEngine *>(
00629             (*lIt)->getLightEngine());
00630
00631         if(sme != NULL)
00632         {
00633 //             ShaderProgram *shadowVP = sme->getShadowVertexProgram  ();
00634             ShaderProgram *shadowFP = sme->getShadowFragmentProgram();
00635
00636 //             if(shadowVP                                      != NULL &&
00637 //                spc->getMFVertexShader()->findIndex(shadowVP) == -1     )
00638 //             {
00639 //                 spc->addShader(shadowVP);
00640 //             }
00641
00642             if(shadowFP                                        != NULL &&
00643                spc->getMFFragmentShader()->findIndex(shadowFP) == -1     )
00644             {
00645                 spc->addShader(shadowFP);
00646             }
00647
00648             Int32 shadowTexUnit = sme->getForceTextureUnit() > 0 ?
00649                                   sme->getForceTextureUnit()     : 7;
00650
00651             if(sme->getEnabled() == true)
00652             {
00653                 state->addChunk(sme->getShadowTexChunk(),
00654                                 shadowTexUnit            );
00655             }
00656             else
00657             {
00658                 state->subChunk(TextureObjChunk::getStaticClassId(),
00659                                 shadowTexUnit                       );
00660             }
00661         }
00662     }
00663
00664     ract->pushPartition();
00665     {
00666         RenderPartition *part = ract->getActivePartition();
00667
00668 //         part->setDebugString("DeferredShadingStage::GBufferPartition");
00669
00670         setupGBufferPartition(part, ract, data);
00671
00672         if(shader != NULL)
00673         {
00674             part->pushState  (                            );
00675             part->addOverride(shader->getClassId(), shader);
00676         }
00677
00678         this->recurseFromThis(ract);
00679
00680         if(shader != NULL)
00681             part->popState();
00682     }
00683     ract->popPartition();
00684
00685     // create shadow maps
00686     lIt  = _mfLights.begin();
00687     lEnd = _mfLights.end  ();
00688
00689     for(; lIt != lEnd; ++lIt)
00690     {
00691         (*lIt)->callLightEngineLeave(ract);
00692     }
00693 }
00694
00695 void DeferredShadingStage::scheduleShadingPass(RenderAction *ract)
00696 {
00697 #if 0
00698     RenderPartition *parentPart = ract->getActivePartition    (            );
00699 #endif
00700     DSStageData     *data       = ract->getData<DSStageData *>(_iDataSlotId);
00701
00702     ract->pushPartition((RenderPartition::CopyWindow      |
00703                          RenderPartition::CopyViewportSize) );
00704     {
00705         RenderPartition *part = ract->getActivePartition();
00706
00707 //         part->setDebugString("DeferredShadingStage::ShadingPartition");
00708
00709         setupShadingPartition(part, ract, data);
00710
00711         RenderPartition::DrawFunctor f =
00712             boost::bind(&DeferredShadingStage::executeShadingPass, this, _1);
00713
00714         DSStageData::MFShadingStatesType::const_iterator sIt  =
00715             data->getMFShadingStates()->begin();
00716         DSStageData::MFShadingStatesType::const_iterator sEnd =
00717             data->getMFShadingStates()->end();
00718
00719         for(UInt32 i = 0; sIt != sEnd; ++sIt, ++i)
00720         {
00721             if((i > 0) &&  (getLights(i-1)->getOn() == false))
00722                 continue;
00723
00724             part->dropFunctor(f, *sIt, (*sIt)->getSortKey());
00725         }
00726     }
00727     ract->popPartition();
00728 }
00729
00730 Action::ResultE DeferredShadingStage::executeShadingPass(DrawEnv *drawEnv)
00731 {
00732     glBegin(GL_QUADS);
00733     {
00734         glVertex2f(-1.f, -1.f);
00735         glVertex2f( 1.f, -1.f);
00736         glVertex2f( 1.f,  1.f);
00737         glVertex2f(-1.f,  1.f);
00738     }
00739     glEnd();
00740
00741     return Action::Continue;
00742 }
00743
00744 void DeferredShadingStage::setupGBufferPartition(
00745     RenderPartition *part, RenderAction *ract, DSStageData *data)
00746 {
00747     Window            *win    = ract->getWindow           ();
00748     FrameBufferObject *target = data->getGBufferTarget    ();
00749     Camera            *cam    = this->getCamera           ();
00750     Background        *back   = data->getGBufferBackground();
00751
00752     Inherited::setupPartition(part, win, target, cam, back);
00753 }
00754
00755 void DeferredShadingStage::setupShadingPartition(
00756     RenderPartition *part, RenderAction *ract, DSStageData *data)
00757 {
00758     Window            *win    = ract->getWindow           ();
00759     FrameBufferObject *target = data->getShadingTarget    ();
00760     Camera            *cam    = this->getCamera           ();
00761     Background        *back   = this->getBackground       ();
00762
00763     part->setRenderTarget(target);
00764     part->setWindow      (win   );
00765
00766     if(target != NULL)
00767     {
00768         part->calcViewportDimension(this->getLeft    (),
00769                                     this->getBottom  (),
00770                                     this->getRight   (),
00771                                     this->getTop     (),
00772
00773                                     target->getWidth (),
00774                                     target->getHeight() );
00775     }
00776     else if(win != NULL)
00777     {
00778         part->calcViewportDimension(this->getLeft  (),
00779                                     this->getBottom(),
00780                                     this->getRight (),
00781                                     this->getTop   (),
00782
00783                                     win->getWidth  (),
00784                                     win->getHeight () );
00785     }
00786     else
00787     {
00788         SWARNING << "DeferredShadingStage::setupShadingPartition: "
00789                  << "No target or window." << std::endl;
00790     }
00791
00792     // setup ortho projection
00793     Matrix matProjection;
00794     Matrix matProjectionTranslation;
00795     Matrix matViewing;
00796
00797     matProjectionTranslation.setIdentity();
00798     matViewing              .setIdentity();
00799
00800     MatrixOrthogonal(matProjection,
00801                      -1.f, 1.f,
00802                      -1.f, 1.f,
00803                      -1.f, 1.f );
00804
00805     part->setupProjection(matProjection, matProjectionTranslation);
00806     part->setupViewing   (matViewing                             );
00807
00808     part->setNear(-1.f);
00809     part->setFar ( 1.f);
00810
00811     // setup VPCamera matrices to original projection -- TODO copy from GBuffer pass?
00812     cam->getProjection           (matProjection,
00813                                   part->getViewportWidth (),
00814                                   part->getViewportHeight() );
00815     cam->getProjectionTranslation(matProjectionTranslation,
00816                                   part->getViewportWidth (),
00817                                   part->getViewportHeight() );
00818
00819     Matrix matProjectionFull = matProjection;
00820     matProjectionFull.mult(matProjectionTranslation);
00821
00822     Matrix matToWorld;
00823     Matrix matWorldToScreen;
00824
00825     cam->getViewing(matViewing, part->getViewportWidth (),
00826                                 part->getViewportHeight() );
00827     matToWorld.invertFrom(matViewing);
00828
00829     matWorldToScreen = matProjectionFull;
00830     matWorldToScreen.mult(matToWorld);
00831
00832     part->setVPCameraMatrices(matProjectionFull,
00833                               matProjection,
00834                               matProjectionTranslation,
00835                               matViewing,
00836                               matToWorld,
00837                               matWorldToScreen          );
00838
00839     part->setBackground(back);
00840
00841     part->setSetupMode(RenderPartition::ProjectionSetup |
00842                        RenderPartition::BackgroundSetup  );
00843 }
00844
00845 OSG_END_NAMESPACE