OSGHDRStage.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 <sstream>
00043 #include <fstream>
00044
00045 #include "OSGConfig.h"
00046
00047 #include "OSGAction.h"
00048 #include "OSGCamera.h"
00049 #include "OSGRenderAction.h"
00050 #include "OSGSceneFileHandler.h"
00051 #include "OSGVolumeDraw.h"
00052
00053 #include "OSGHDRStage.h"
00054 #include "OSGHDRStageData.h"
00055
00056 #include "OSGFrameBufferObject.h"
00057 #include "OSGFrameBufferAttachment.h"
00058 #include "OSGRenderBuffer.h"
00059 #include "OSGTextureBuffer.h"
00060
00061 #include "OSGChunkMaterial.h"
00062 #include "OSGMaterialChunk.h"
00063 #include "OSGTextureObjChunk.h"
00064 #include "OSGDrawEnv.h"
00065 #include "OSGImageFunctions.h"
00066 #include "OSGStateOverride.h"
00067 #include "OSGTextureEnvChunk.h"
00068 #include "OSGSimpleSHLFunctions.h"
00069
00070 #include "OSGMatrixUtility.h"
00071
00072 OSG_USING_NAMESPACE
00073
00078 UInt32 HDRStage::_uiFramebuffer_object_extension =
00079     Window::invalidExtensionID;
00080
00081 UInt32 HDRStage::_uiFuncDrawBuffers              =
00082     Window::invalidFunctionID;
00083
00084 typedef void   (OSG_APIENTRY *GLDrawBuffersEXTProcT)(
00085           GLsizei  n,
00086     const GLenum  *buffers);
00087
00088 /*-------------------------------------------------------------------------*/
00089 /*                               Sync                                      */
00090
00091 void HDRStage::changed(ConstFieldMaskArg whichField,
00092                        UInt32            origin,
00093                        BitVector         details)
00094 {
00095     Inherited::changed(whichField, origin, details);
00096 }
00097
00098 /*-------------------------------------------------------------------------*/
00099 /*                               Dump                                      */
00100
00101 void HDRStage::dump(      UInt32    OSG_CHECK_ARG(uiIndent),
00102                     const BitVector OSG_CHECK_ARG(bvFlags )) const
00103 {
00104     SLOG << "Dump VisitSubTree NI" << std::endl;
00105 }
00106
00107 /*-------------------------------------------------------------------------*/
00108 /*                            Constructors                                 */
00109
00110 HDRStage::HDRStage(void) :
00111      Inherited  (  )
00112 {
00113 }
00114
00115 HDRStage::HDRStage(const HDRStage &source) :
00116      Inherited  (source)
00117 {
00118 }
00119
00120 /*-------------------------------------------------------------------------*/
00121 /*                             Destructor                                  */
00122
00123 HDRStage::~HDRStage(void)
00124 {
00125 }
00126
00127 /*-------------------------------------------------------------------------*/
00128 /*                                Draw                                     */
00129
00136 ActionBase::ResultE HDRStage::renderEnter(Action *action)
00137 {
00138     RenderAction *a = dynamic_cast<RenderAction *>(action);
00139
00140     a->disableDefaultPartition();
00141
00142     a->beginPartitionGroup();
00143     {
00144         a->pushPartition();
00145         {
00146             RenderPartition   *pPart    = a->getActivePartition();
00147             FrameBufferObject *pTarget  = this->getRenderTarget();
00148             Viewport          *pPort    = a->getViewport();
00149             Camera            *pCam     = a->getCamera  ();
00150             Background        *pBack    = a->getBackground();
00151
00152             if(pTarget == NULL)
00153             {
00154                 this->initData(pPort, a);
00155
00156                 pTarget  = this->getRenderTarget();
00157             }
00158
00159             pPart->setRenderTarget(pTarget);
00160
00161 #ifdef OSG_DEBUGX
00162             std::string szMessage("RenderPartition\n");
00163             pPart->setDebugString(szMessage          );
00164 #endif
00165 
00166             if(pPort != NULL)
00167             {
00168 //                pPart->setViewport(pPort         );
00169                 pPart->setWindow  (a->getWindow());
00170
00171                 if(pTarget != NULL)
00172                 {
00173                     pPart->calcViewportDimension(pPort->getLeft  (),
00174                                                  pPort->getBottom(),
00175                                                  pPort->getRight (),
00176                                                  pPort->getTop   (),
00177
00178                                                  pTarget->getWidth    (),
00179                                                  pTarget->getHeight   ());
00180                 }
00181                 else
00182                 {
00183                     pPart->calcViewportDimension(pPort->getLeft  (),
00184                                                  pPort->getBottom(),
00185                                                  pPort->getRight (),
00186                                                  pPort->getTop   (),
00187
00188                                                  a->getWindow()->getWidth (),
00189                                                  a->getWindow()->getHeight());
00190                 }
00191
00192                 if(pCam != NULL)
00193                 {
00194                     Matrix m, t;
00195
00196                     // set the projection
00197                     pCam->getProjection          (m,
00198                                                   pPart->getViewportWidth (),
00199                                                   pPart->getViewportHeight());
00200
00201                     pCam->getProjectionTranslation(t,
00202                                                    pPart->getViewportWidth (),
00203                                                    pPart->getViewportHeight());
00204
00205                     pPart->setupProjection(m, t);
00206
00207                     pCam->getViewing(m,
00208                                      pPart->getViewportWidth (),
00209                                      pPart->getViewportHeight());
00210
00211
00212                     pPart->setupViewing(m);
00213
00214                     pPart->setNear     (pCam->getNear());
00215                     pPart->setFar      (pCam->getFar ());
00216
00217                     pPart->calcFrustum();
00218                 }
00219
00220                 pPart->setBackground(pBack);
00221             }
00222
00223             this->recurseFromThis(a);
00224         }
00225         a->popPartition();
00226
00227         a->pushPartition((RenderPartition::CopyWindow      |
00228                           RenderPartition::CopyViewportSize),
00229                          RenderPartition::SimpleCallback);
00230         {
00231             RenderPartition *pPart  = a->getActivePartition();
00232
00233 #ifdef OSG_DEBUGX
00234             std::string szMessage("PostProcessPartition\n");
00235             pPart->setDebugString(szMessage          );
00236 #endif
00237 
00238             Matrix m, t;
00239
00240             m.setIdentity();
00241             t.setIdentity();
00242
00243             MatrixOrthogonal( m,
00244                               0.f, 1.f,
00245                               0.f, 1.f,
00246                              -1.f, 1.f);
00247
00248             pPart->setupProjection(m, t);
00249
00250             RenderPartition::SimpleDrawCallback f;
00251
00252             f = boost::bind(&HDRStage::postProcess, this, _1);
00253
00254             pPart->dropFunctor(f);
00255         }
00256         a->popPartition();
00257     }
00258     a->endPartitionGroup();
00259
00260     return Action::Skip;
00261 }
00262
00263 ActionBase::ResultE HDRStage::renderLeave(Action *action)
00264 {
00265     return Action::Skip;
00266 }
00267
00268 /*-------------------------------------------------------------------------*/
00269 /*                               Init                                      */
00270
00271 void HDRStage::initMethod(InitPhase ePhase)
00272 {
00273     Inherited::initMethod(ePhase);
00274
00275     if(ePhase == TypeObject::SystemPost)
00276     {
00277         RenderAction::registerEnterDefault(
00278             HDRStage::getClassType(),
00279             reinterpret_cast<Action::Callback>(&HDRStage::renderEnter));
00280
00281         RenderAction::registerLeaveDefault(
00282             HDRStage::getClassType(),
00283             reinterpret_cast<Action::Callback>(&HDRStage::renderLeave));
00284
00285         _uiFramebuffer_object_extension =
00286             Window::registerExtension("GL_EXT_framebuffer_object");
00287
00288         _uiFuncDrawBuffers  =
00289             Window::registerFunction (
00290                 OSG_DLSYM_UNDERSCORE"glDrawBuffersARB",
00291                 _uiFramebuffer_object_extension);
00292     }
00293 }
00294
00295 HDRStageDataTransitPtr HDRStage::setupStageData(Int32 iPixelWidth,
00296                                                 Int32 iPixelHeight)
00297 {
00298     HDRStageDataTransitPtr returnValue = HDRStageData::createLocal();
00299
00300     if(returnValue == NULL)
00301         return returnValue;
00302
00303     OSG::Thread::setCurrentLocalFlags();
00304
00305     // Scene Target
00306
00307     FrameBufferObjectUnrecPtr pSceneFBO    = FrameBufferObject::createLocal();
00308
00309     RenderBufferUnrecPtr      pDepthBuffer = RenderBuffer     ::createLocal();
00310
00311     pDepthBuffer->setInternalFormat(GL_DEPTH_COMPONENT24   );
00312
00313
00314     TextureObjChunkUnrecPtr pSceneTex     = TextureObjChunk::createLocal();
00315     TextureEnvChunkUnrecPtr pSceneTexEnv  = TextureEnvChunk::createLocal();
00316     ImageUnrecPtr           pImg          = Image          ::createLocal();
00317
00318     pImg->set(Image::OSG_RGB_PF,
00319               iPixelWidth,
00320               iPixelHeight,
00321               1,
00322               1,
00323               1,
00324               0.0,
00325               0,
00326               Image::OSG_FLOAT32_IMAGEDATA,
00327               false);
00328
00329     pSceneTex   ->setImage         (pImg             );
00330     pSceneTex   ->setMinFilter     (GL_LINEAR        );
00331     pSceneTex   ->setMagFilter     (GL_LINEAR        );
00332     pSceneTex   ->setWrapS         (GL_CLAMP_TO_EDGE );
00333     pSceneTex   ->setWrapT         (GL_CLAMP_TO_EDGE );
00334     pSceneTex   ->setInternalFormat(getBufferFormat());
00335
00336     pSceneTexEnv->setEnvMode       (GL_REPLACE       );
00337
00338     TextureBufferUnrecPtr pSceneTexBuffer   = TextureBuffer::createLocal();
00339
00340     pSceneTexBuffer->setTexture(pSceneTex);
00341
00342
00343
00344     pSceneFBO->setSize(iPixelWidth, iPixelHeight);
00345
00346     pSceneFBO->setColorAttachment(pSceneTexBuffer, 0);
00347     pSceneFBO->setDepthAttachment(pDepthBuffer      );
00348
00349     pSceneFBO->editMFDrawBuffers()->push_back(GL_COLOR_ATTACHMENT0_EXT);
00350
00351     setRenderTarget(pSceneFBO);
00352
00353
00354
00355
00356     // Shrink Target (w/2, h/2)
00357
00358     FrameBufferObjectUnrecPtr pShrinkFBO     = FrameBufferObject::createLocal();
00359
00360     TextureObjChunkUnrecPtr   pShrinkTex     = TextureObjChunk::createLocal();
00361     TextureEnvChunkUnrecPtr   pShrinkTexEnv  = TextureEnvChunk::createLocal();
00362                               pImg           = Image          ::createLocal();
00363
00364     pImg->set(Image::OSG_RGB_PF,
00365               iPixelWidth  / 2,
00366               iPixelHeight / 2,
00367               1,
00368               1,
00369               1,
00370               0.0,
00371               0,
00372               Image::OSG_FLOAT32_IMAGEDATA,
00373               false);
00374
00375     pShrinkTex   ->setImage         (pImg             );
00376     pShrinkTex   ->setMinFilter     (GL_LINEAR        );
00377     pShrinkTex   ->setMagFilter     (GL_LINEAR        );
00378     pShrinkTex   ->setWrapS         (GL_CLAMP_TO_EDGE );
00379     pShrinkTex   ->setWrapT         (GL_CLAMP_TO_EDGE );
00380     pShrinkTex   ->setInternalFormat(getBufferFormat());
00381
00382     pShrinkTexEnv->setEnvMode       (GL_REPLACE       );
00383
00384     TextureBufferUnrecPtr pShrinkTexBuffer   = TextureBuffer::createLocal();
00385
00386     pShrinkTexBuffer->setTexture(pShrinkTex);
00387
00388
00389
00390     pShrinkFBO->setSize(iPixelWidth / 2, iPixelHeight / 2);
00391
00392     pShrinkFBO->setColorAttachment(pShrinkTexBuffer, 0);
00393
00394     pShrinkFBO->editMFDrawBuffers()->push_back(GL_COLOR_ATTACHMENT0_EXT);
00395
00396     returnValue->setShrinkRenderTarget(pShrinkFBO);
00397
00398
00399
00400
00401
00402     // blur (w/4, h/4)
00403
00404
00405     FrameBufferObjectUnrecPtr pBlurFBO     = FrameBufferObject::createLocal();
00406
00407     TextureObjChunkUnrecPtr   pBlurTex1    = TextureObjChunk  ::createLocal();
00408     TextureEnvChunkUnrecPtr   pBlurTex1Env = TextureEnvChunk  ::createLocal();
00409
00410
00411     pImg = Image::createLocal();
00412
00413     pImg->set(Image::OSG_RGB_PF,
00414               iPixelWidth  / 4,
00415               iPixelHeight / 4,
00416               1,
00417               1,
00418               1,
00419               0.0,
00420               0,
00421               Image::OSG_FLOAT32_IMAGEDATA,
00422               false);
00423
00424     pBlurTex1   ->setImage         (pImg             );
00425     pBlurTex1   ->setMinFilter     (GL_LINEAR        );
00426     pBlurTex1   ->setMagFilter     (GL_LINEAR        );
00427     pBlurTex1   ->setWrapS         (GL_CLAMP_TO_EDGE );
00428     pBlurTex1   ->setWrapT         (GL_CLAMP_TO_EDGE );
00429     pBlurTex1   ->setInternalFormat(getBufferFormat());
00430
00431     pBlurTex1Env->setEnvMode       (GL_REPLACE       );
00432
00433     TextureBufferUnrecPtr pBlurTexBuffer1 = TextureBuffer::createLocal();
00434
00435     pBlurTexBuffer1->setTexture(pBlurTex1);
00436
00437
00438
00439     TextureObjChunkUnrecPtr pBlurTex2    = TextureObjChunk::createLocal();
00440     TextureEnvChunkUnrecPtr pBlurTex2Env = TextureEnvChunk::createLocal();
00441
00442
00443     pImg = Image::createLocal();
00444
00445     pImg->set(Image::OSG_RGB_PF,
00446               iPixelWidth  / 4,
00447               iPixelHeight / 4,
00448               1,
00449               1,
00450               1,
00451               0.0,
00452               0,
00453               Image::OSG_FLOAT32_IMAGEDATA,
00454               false);
00455
00456     pBlurTex2   ->setImage         (pImg             );
00457     pBlurTex2   ->setMinFilter     (GL_LINEAR        );
00458     pBlurTex2   ->setMagFilter     (GL_LINEAR        );
00459     pBlurTex2   ->setWrapS         (GL_CLAMP_TO_EDGE );
00460     pBlurTex2   ->setWrapT         (GL_CLAMP_TO_EDGE );
00461     pBlurTex2   ->setInternalFormat(getBufferFormat());
00462
00463     pBlurTex2Env->setEnvMode       (GL_REPLACE       );
00464
00465     TextureBufferUnrecPtr pBlurTexBuffer2 = TextureBuffer::createLocal();
00466
00467     pBlurTexBuffer2->setTexture(pBlurTex2);
00468
00469
00470     pBlurFBO->setSize(iPixelWidth  / 4,
00471                       iPixelHeight / 4);
00472
00473     pBlurFBO->setColorAttachment(pBlurTexBuffer1,  0);
00474     pBlurFBO->setColorAttachment(pBlurTexBuffer2,  1);
00475
00476     returnValue->setBlurRenderTarget(pBlurFBO);
00477
00478
00479     // general mat chunk
00480
00481
00482     MaterialChunkUnrecPtr pMatChunk = MaterialChunk::createLocal();
00483
00484     pMatChunk->setLit(false);
00485
00486
00487
00488
00489     // tone map material
00490
00491     ChunkMaterialUnrecPtr    pTonemapMat  = ChunkMaterial  ::createLocal();
00492
00493     pTonemapMat->addChunk(pMatChunk         );
00494     pTonemapMat->addChunk(pSceneTex,       0);
00495     pTonemapMat->addChunk(pSceneTexEnv,    0);
00496     pTonemapMat->addChunk(pBlurTex1,       1);
00497     pTonemapMat->addChunk(pBlurTex1Env,    1);
00498
00499     SimpleSHLChunkUnrecPtr pTonemapShader = generateHDRFragmentProgram();
00500
00501     pTonemapShader->addUniformVariable("sceneTex",     0);
00502     pTonemapShader->addUniformVariable("blurTex",      1);
00503     pTonemapShader->addUniformVariable("blurAmount",   getBlurAmount  ());
00504     pTonemapShader->addUniformVariable("exposure",     getExposure    ());
00505     pTonemapShader->addUniformVariable("effectAmount", getEffectAmount());
00506     pTonemapShader->addUniformVariable("gamma",        getGamma       ());
00507
00508     pTonemapMat->addChunk(pTonemapShader, 0);
00509
00510     returnValue->setToneMappingMaterial(pTonemapMat);
00511
00512
00513
00514
00515     // Shrink material
00516
00517     ChunkMaterialUnrecPtr pShrinkMat = ChunkMaterial::createLocal();
00518
00519     pShrinkMat->addChunk(pMatChunk   );
00520
00521     pShrinkMat->addChunk(pSceneTex,     0);
00522     pShrinkMat->addChunk(pSceneTexEnv,  0);
00523
00524     SimpleSHLChunkUnrecPtr pShrinkShader = generate2DShrinkHalfFilterFP();
00525
00526     pShrinkShader->addUniformVariable("inputTex", 0);
00527
00528     pShrinkMat->addChunk(pShrinkShader, 0);
00529
00530     returnValue->setShrinkMaterial(pShrinkMat);
00531
00532
00533
00534
00535     // Blur material
00536
00537     ChunkMaterialUnrecPtr pBlurMat = ChunkMaterial::createLocal();
00538
00539     pBlurMat->addChunk(pMatChunk   );
00540
00541     pBlurMat->addChunk(pShrinkTex,    0);
00542     pBlurMat->addChunk(pShrinkTexEnv, 0);
00543     pBlurMat->addChunk(pBlurTex1,     1);
00544     pBlurMat->addChunk(pBlurTex1Env,  1);
00545     pBlurMat->addChunk(pBlurTex2,     2);
00546     pBlurMat->addChunk(pBlurTex2Env,  2);
00547
00548     pBlurMat->addChunk(pShrinkShader, 0);
00549
00550     returnValue->setBlurMaterial(pBlurMat);
00551
00552
00553     // generate blur fragment programs
00554     SimpleSHLChunkUnrecPtr pHBlurShader =
00555         generate1DConvolutionFilterFP(getBlurWidth(),
00556                                       false,
00557                                       true,
00558                                       iPixelWidth  / 2,
00559                                       iPixelHeight / 2);
00560
00561
00562     pHBlurShader->addUniformVariable("inputTex", 0);
00563
00564     returnValue->setHBlurShader(pHBlurShader);
00565
00566
00567
00568     // VBlur Override
00569
00570
00571     SimpleSHLChunkUnrecPtr pVBlurShader =
00572         generate1DConvolutionFilterFP(getBlurWidth(),
00573                                       true,
00574                                       true,
00575                                       iPixelWidth  / 2,
00576                                       iPixelHeight / 2);
00577
00578     pVBlurShader->addUniformVariable("inputTex", 1);
00579
00580     returnValue->setVBlurShader(pVBlurShader);
00581
00582     OSG::Thread::resetCurrentLocalFlags();
00583
00584     Thread::getCurrentChangeList()->commitChanges();
00585
00586     return returnValue;
00587 }
00588
00589 void HDRStage::resizeStageData(HDRStageData *pData,
00590                                Int32         iPixelWidth,
00591                                Int32         iPixelHeight)
00592 {
00593     FWARNING(("HDRStage resize not implemented ==> wrong results\n"));
00594 }
00595
00596 void HDRStage::postProcess(DrawEnv *pEnv)
00597 {
00598     Window *win = pEnv->getWindow();
00599
00600     if(win->hasExtension(_uiFramebuffer_object_extension) == false)
00601     {
00602         FNOTICE(("Framebuffer objects not supported on Window %p!\n", win));
00603         return;
00604     }
00605
00606     GLDrawBuffersEXTProcT glDrawBuffersEXTProc =
00607         reinterpret_cast<GLDrawBuffersEXTProcT>(
00608             win->getFunction(_uiFuncDrawBuffers));
00609
00610     glColor3f(1.f, 1.f, 1.f);
00611
00612     glMatrixMode(GL_MODELVIEW);
00613     glPushMatrix();
00614
00615     glLoadIdentity();
00616
00617     HDRStageData *pData = pEnv->getData<HDRStageData *>(_iDataSlotId);
00618
00619     if(pData == NULL)
00620     {
00621         return;
00622     }
00623
00624     if((pData->getWidth () != pEnv->getPixelWidth() ) ||
00625        (pData->getHeight() != pEnv->getPixelHeight())  )
00626     {
00627         resizeStageData(pData,
00628                         pEnv->getPixelWidth(),
00629                         pEnv->getPixelHeight());
00630     }
00631
00632
00633     // Shrink to w/2 h/2
00634
00635     FrameBufferObject *pShrinkTarget = pData->getShrinkRenderTarget();
00636     ChunkMaterial     *pSHM          = pData->getShrinkMaterial();
00637
00638
00639     pShrinkTarget->activate(pEnv);
00640
00641     glViewport(0,
00642                0,
00643                pEnv->getPixelWidth () / 2,
00644                pEnv->getPixelHeight() / 2);
00645
00646
00647     State *pShrinkState = pSHM->getState();
00648
00649     pEnv->activateState(pShrinkState, NULL);
00650
00651     glBegin(GL_QUADS);
00652     {
00653         glTexCoord2f(0.00, 0.00);
00654         glVertex2f  (0.00, 0.00);
00655
00656         glTexCoord2f(1.00, 0.00);
00657         glVertex2f  (1.00, 0.00);
00658
00659         glTexCoord2f(1.00, 1.00);
00660         glVertex2f  (1.00, 1.00);
00661
00662         glTexCoord2f(0.00, 1.00);
00663         glVertex2f  (0.00, 1.00);
00664     }
00665     glEnd();
00666
00667     pShrinkTarget->deactivate(pEnv);
00668
00669
00670     // Shrink to w/4 h/4
00671
00672     FrameBufferObject *pBlurTarget = pData->getBlurRenderTarget();
00673
00674     pBlurTarget->editMFDrawBuffers()->clear();
00675
00676     pBlurTarget->editMFDrawBuffers()->push_back(GL_COLOR_ATTACHMENT0_EXT);
00677
00678     pBlurTarget->activate(pEnv);
00679
00680     glViewport(0,
00681                0,
00682                pEnv->getPixelWidth () / 4,
00683                pEnv->getPixelHeight() / 4);
00684
00685     ChunkMaterial    *pBLM       = pData->getBlurMaterial();
00686
00687     State            *pBlurState = pBLM->getState();
00688
00689     pEnv->activateState(pBlurState, NULL);
00690
00691     glBegin(GL_QUADS);
00692     {
00693         glTexCoord2f(0.00, 0.00);
00694         glVertex2f  (0.00, 0.00);
00695
00696         glTexCoord2f(1.00, 0.00);
00697         glVertex2f  (1.00, 0.00);
00698
00699         glTexCoord2f(1.00, 1.00);
00700         glVertex2f  (1.00, 1.00);
00701
00702         glTexCoord2f(0.00, 1.00);
00703         glVertex2f  (0.00, 1.00);
00704     }
00705     glEnd();
00706
00707     // HBlur
00708
00709     StateOverride oOverride;
00710
00711     GLenum aDrawBuffers[] = { GL_COLOR_ATTACHMENT1_EXT };
00712
00713     oOverride.addOverride(pData->getHBlurShader()->getClassId(),
00714                           pData->getHBlurShader());
00715
00716
00717     pEnv->activateState(pBlurState, &oOverride);
00718
00719     glDrawBuffersEXTProc(1, aDrawBuffers);
00720
00721
00722     glBegin(GL_QUADS);
00723     {
00724         glTexCoord2f(0.00, 0.00);
00725         glVertex2f  (0.00, 0.00);
00726
00727         glTexCoord2f(1.00, 0.00);
00728         glVertex2f  (1.00, 0.00);
00729
00730         glTexCoord2f(1.00, 1.00);
00731         glVertex2f  (1.00, 1.00);
00732
00733         glTexCoord2f(0.00, 1.00);
00734         glVertex2f  (0.00, 1.00);
00735     }
00736     glEnd();
00737
00738
00739
00740     // VBlur
00741
00742     StateOverride oOverride1;
00743
00744     oOverride1.addOverride(pData->getVBlurShader()->getClassId(),
00745                            pData->getVBlurShader());
00746
00747
00748     pEnv->activateState(pBlurState, &oOverride1);
00749
00750     aDrawBuffers[0] = GL_COLOR_ATTACHMENT0_EXT;
00751
00752     glDrawBuffersEXTProc(1, aDrawBuffers);
00753
00754     glBegin(GL_QUADS);
00755     {
00756         glTexCoord2f(0.00, 0.00);
00757         glVertex2f  (0.00, 0.00);
00758
00759         glTexCoord2f(1.00, 0.00);
00760         glVertex2f  (1.00, 0.00);
00761
00762         glTexCoord2f(1.00, 1.00);
00763         glVertex2f  (1.00, 1.00);
00764
00765         glTexCoord2f(0.00, 1.00);
00766         glVertex2f  (0.00, 1.00);
00767     }
00768     glEnd();
00769
00770
00771     pBlurTarget->deactivate(pEnv);
00772
00773
00774
00775     // Tonemap pass
00776
00777     glDisable(GL_DEPTH_TEST);
00778
00779     glViewport(pEnv->getPixelLeft  (),
00780                pEnv->getPixelBottom(),
00781                pEnv->getPixelWidth (),
00782                pEnv->getPixelHeight());
00783
00784     ChunkMaterial *pTCM = pData->getToneMappingMaterial();
00785
00786     State *pTState = pTCM->getState();
00787
00788     pEnv->activateState(pTState, NULL);
00789
00790     glBegin(GL_QUADS);
00791     {
00792         glTexCoord2f(0.00, 0.00);
00793         glVertex2f  (0.00, 0.00);
00794
00795         glTexCoord2f(1.00, 0.00);
00796         glVertex2f  (1.00, 0.00);
00797
00798         glTexCoord2f(1.00, 1.00);
00799         glVertex2f  (1.00, 1.00);
00800
00801         glTexCoord2f(0.00, 1.00);
00802         glVertex2f  (0.00, 1.00);
00803     }
00804     glEnd();
00805
00806     glEnable(GL_DEPTH_TEST);
00807
00808     pEnv->deactivateState();
00809
00810
00811     glPopMatrix();
00812 }
00813
00814 void HDRStage::initData(Viewport         *pViewport,
00815                         RenderActionBase *pAction  )
00816 {
00817     HDRStageDataUnrecPtr pData = pAction->getData<HDRStageData *>(_iDataSlotId);
00818
00819     if(pData == NULL)
00820     {
00821         pData = setupStageData(pViewport->getPixelWidth(),
00822                                pViewport->getPixelHeight());
00823
00824         pData->setWidth (pViewport->getPixelWidth ());
00825         pData->setHeight(pViewport->getPixelHeight());
00826
00827         this->setData(pData, _iDataSlotId, pAction);
00828     }
00829 }
00830
00831 #define OSGHDRL << std::endl
00832 
00833 SimpleSHLChunkTransitPtr HDRStage::generateHDRFragmentProgram(void)
00834 {
00835     std::ostringstream ost;
00836
00837     ost << "uniform sampler2D sceneTex;"                                 OSGHDRL
00838         << "uniform sampler2D blurTex;"                                  OSGHDRL
00839         << "uniform float     exposure;"                                 OSGHDRL
00840         << "uniform float     blurAmount;"                               OSGHDRL
00841         << "uniform float     effectAmount;"                             OSGHDRL
00842         << "uniform float     gamma;"                                    OSGHDRL
00843         << ""                                                            OSGHDRL
00844         << "float vignette(vec2 pos, float inner, float outer)"          OSGHDRL
00845         << "{"                                                           OSGHDRL
00846         << "    float r = length(pos);"                                  OSGHDRL
00847         << ""                                                            OSGHDRL
00848         << "    r = 1.0 - smoothstep(inner, outer, r);"                  OSGHDRL
00849         << ""                                                            OSGHDRL
00850         << "    return r;"                                               OSGHDRL
00851         << "}"                                                           OSGHDRL
00852         << ""                                                            OSGHDRL
00853         << "// radial blur"                                              OSGHDRL
00854         << "vec4 radial(sampler2D tex,"                                  OSGHDRL
00855         << "            vec2      texcoord,"                             OSGHDRL
00856         << "            int       samples,"                              OSGHDRL
00857         << "            float     startScale = 1.0,"                     OSGHDRL
00858         << "            float     scaleMul   = 0.9)"                     OSGHDRL
00859         << "{"                                                           OSGHDRL
00860         << "    vec4 c     = vec4(0., 0., 0., 0.);"                      OSGHDRL
00861         << "    float  scale = startScale;"                              OSGHDRL
00862         << ""                                                            OSGHDRL
00863         << "    for(int i=0; i<samples; i++) "                           OSGHDRL
00864         << "    {"                                                       OSGHDRL
00865         << "        vec2 uv = ((texcoord - 0.5)*scale)+0.5;"             OSGHDRL
00866         << "        vec4 s  = texture2D(tex, uv);"                       OSGHDRL
00867         << ""                                                            OSGHDRL
00868         << "        c += s;"                                             OSGHDRL
00869         << ""                                                            OSGHDRL
00870         << "        scale *= scaleMul;"                                  OSGHDRL
00871         << "    }"                                                       OSGHDRL
00872         << ""                                                            OSGHDRL
00873         << "    c /= float(samples);"                                    OSGHDRL
00874         << ""                                                            OSGHDRL
00875         << "    return c;"                                               OSGHDRL
00876         << "}"                                                           OSGHDRL
00877         << ""                                                            OSGHDRL
00878         << "void main(void)"                                             OSGHDRL
00879         << "{"                                                           OSGHDRL
00880         << "    vec4 scene   = texture2D(sceneTex, gl_TexCoord[0].xy);"  OSGHDRL
00881         << "    vec4 blurred = texture2D(blurTex,  gl_TexCoord[0].xy);"  OSGHDRL
00882         << "    vec4 effect  = radial   (blurTex,  gl_TexCoord[0].xy, "  OSGHDRL
00883         << "                             30, 1.0, 0.95);"                OSGHDRL
00884         << ""                                                            OSGHDRL
00885         << "    vec4 c = mix(scene, blurred, blurAmount);"               OSGHDRL
00886         << ""                                                            OSGHDRL
00887         << "    c += effect * effectAmount;"                             OSGHDRL
00888         << ""                                                            OSGHDRL
00889         << "    // exposure"                                             OSGHDRL
00890         << "    c = c * exposure;"                                       OSGHDRL
00891         << ""                                                            OSGHDRL
00892         << "    // vignette effect"                                      OSGHDRL
00893         << "    c *= vignette(gl_TexCoord[0].xy * 2.0 - 1.0, 0.7, 1.5);" OSGHDRL
00894         << ""                                                            OSGHDRL
00895         << "    // gamma correction"                                     OSGHDRL
00896         << "    c.rgb = pow(c.rgb, vec3(gamma));"                        OSGHDRL
00897         << ""                                                            OSGHDRL
00898         << "    gl_FragColor = c;"                                       OSGHDRL
00899         << "}"                                                           OSGHDRL
00900         << "";
00901
00902     SimpleSHLChunkTransitPtr returnValue = SimpleSHLChunk::createLocal();
00903
00904     returnValue->setFragmentProgram(ost.str());
00905
00906     return returnValue;
00907 }