OSGCubeMapGenerator.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 <cstdlib>
00044 #include <cstdio>
00045
00046 #include "OSGConfig.h"
00047
00048 #include "OSGCubeMapGenerator.h"
00049 #include "OSGCubeMapGeneratorStageData.h"
00050
00051 #include "OSGFrameBufferObject.h"
00052 #include "OSGFrameBufferAttachment.h"
00053 #include "OSGRenderBuffer.h"
00054 #include "OSGTextureBuffer.h"
00055 #include "OSGTextureEnvChunk.h"
00056 #include "OSGTexGenChunk.h"
00057 #include "OSGTextureTransformChunk.h"
00058 #include "OSGRenderAction.h"
00059 #include "OSGPerspectiveCamera.h"
00060
00061 OSG_BEGIN_NAMESPACE
00062
00063 // Documentation for this class is emitted in the
00064 // OSGCubeMapGeneratorBase.cpp file.
00065 // To modify it, please change the .fcd file (OSGCubeMapGenerator.fcd) and
00066 // regenerate the base file.
00067
00068 /***************************************************************************\
00069  *                           Class variables                               *
00070 \***************************************************************************/
00071
00072 /***************************************************************************\
00073  *                           Class methods                                 *
00074 \***************************************************************************/
00075
00076 void CubeMapGenerator::initMethod(InitPhase ePhase)
00077 {
00078     Inherited::initMethod(ePhase);
00079
00080     if(ePhase == TypeObject::SystemPost)
00081     {
00082         RenderAction::registerEnterDefault(
00083             CubeMapGenerator::getClassType(),
00084             reinterpret_cast<Action::Callback>(
00085                 &CubeMapGenerator::renderEnter));
00086
00087         RenderAction::registerLeaveDefault(
00088             CubeMapGenerator::getClassType(),
00089             reinterpret_cast<Action::Callback>(
00090                 &CubeMapGenerator::renderLeave));
00091     }
00092 }
00093
00094
00095 /***************************************************************************\
00096  *                           Instance methods                              *
00097 \***************************************************************************/
00098
00099 /*-------------------------------------------------------------------------*\
00100  -  private                                                                 -
00101 \*-------------------------------------------------------------------------*/
00102
00103 /*----------------------- constructors & destructors ----------------------*/
00104
00105 CubeMapGenerator::CubeMapGenerator(void) :
00106     Inherited()
00107 {
00108 }
00109
00110 CubeMapGenerator::CubeMapGenerator(const CubeMapGenerator &source) :
00111     Inherited(source)
00112 {
00113 }
00114
00115 CubeMapGenerator::~CubeMapGenerator(void)
00116 {
00117 }
00118
00119 /*----------------------------- class specific ----------------------------*/
00120
00121 void CubeMapGenerator::changed(ConstFieldMaskArg whichField,
00122                             UInt32            origin,
00123                             BitVector         details)
00124 {
00125     Inherited::changed(whichField, origin, details);
00126 }
00127
00128 void CubeMapGenerator::dump(      UInt32    ,
00129                          const BitVector ) const
00130 {
00131     SLOG << "Dump CubeMapGenerator NI" << std::endl;
00132 }
00133
00134 ActionBase::ResultE CubeMapGenerator::renderEnter(Action *action)
00135 {
00136     static Matrix transforms[] =
00137     {
00138         Matrix( 1,  0,  0,  0,
00139                 0, -1,  0,  0,
00140                 0,  0, -1,  0,
00141                 0,  0,  0,  1),
00142
00143         Matrix(-1,  0,  0,  0,
00144                 0, -1,  0,  0,
00145                 0,  0,  1,  0,
00146                 0,  0,  0,  1),
00147
00148         Matrix( 1,  0,  0,  0,
00149                 0,  0, -1,  0,
00150                 0,  1,  0,  0,
00151                 0,  0,  0,  1),
00152
00153         Matrix( 1,  0,  0,  0,
00154                 0,  0,  1,  0,
00155                 0, -1,  0,  0,
00156                 0,  0,  0,  1),
00157
00158         Matrix( 0,  0, -1,  0,
00159                 0, -1,  0,  0,
00160                -1,  0,  0,  0,
00161                 0,  0,  0,  1),
00162
00163         Matrix( 0,  0,  1,  0,
00164                 0, -1,  0,  0,
00165                 1,  0,  0,  0,
00166                 0,  0,  0,  1)
00167     };
00168
00169     RenderAction *a = dynamic_cast<RenderAction *>(action);
00170
00171     Action::ResultE  returnValue = Action::Continue;
00172
00173     Background      *pBack    = a->getBackground();
00174
00175     Viewport        *pPort    = a->getViewport();
00176
00177     Node            *pActNode = a->getActNode();
00178
00179     CubeMapGeneratorStageData *pData =
00180         a->getData<CubeMapGeneratorStageData *>(_iDataSlotId);
00181
00182     if(pData == NULL)
00183     {
00184         pData = this->initData(a);
00185     }
00186
00187     a->beginPartitionGroup();
00188     {
00189         FrameBufferObject *pTarget  = this->getRenderTarget();
00190
00191         if(pTarget == NULL)
00192         {
00193             pTarget  = pData->getRenderTarget();
00194         }
00195
00196         Pnt3f oOrigin;
00197
00198         if(this->getOriginMode() == CubeMapGenerator::UseStoredValue)
00199         {
00200             oOrigin = this->getOrigin();
00201         }
00202         else if(this->getOriginMode() == CubeMapGenerator::UseBeacon)
00203         {
00204             fprintf(stderr, "CubemapGen::UseBeacon NYI\n");
00205         }
00206         else if(this->getOriginMode() ==
00207                                        CubeMapGenerator::UseCurrentVolumeCenter)
00208         {
00209             BoxVolume oWorldVol;
00210
00211             commitChanges();
00212
00213             pActNode->updateVolume();
00214
00215             pActNode->getWorldVolume(oWorldVol);
00216
00217             oWorldVol.getCenter(oOrigin);
00218         }
00219         else if(this->getOriginMode() ==
00220                                        CubeMapGenerator::UseParentsVolumeCenter)
00221         {
00222             fprintf(stderr, "CubemapGen::UseParentsCenter NYI\n");
00223         }
00224
00225         Camera *pCam = pData->getCamera();
00226
00227         for(UInt32 i = 0; i < 6; ++i)
00228         {
00229             a->pushPartition();
00230             {
00231                 RenderPartition   *pPart    = a->getActivePartition();
00232
00233                 pPart->setVolumeDrawing(false);
00234
00235                 pPart->setRenderTarget(pTarget       );
00236                 pPart->setWindow      (a->getWindow());
00237
00238                 pPart->calcViewportDimension(0,
00239                                              0,
00240                                              1,
00241                                              1,
00242                                              this->getWidth (),
00243                                              this->getHeight());
00244
00245                 Matrix m, t;
00246
00247                 // set the projection
00248                 pCam->getProjection          (m,
00249                                               pPart->getViewportWidth (),
00250                                               pPart->getViewportHeight());
00251
00252                 pCam->getProjectionTranslation(t,
00253                                                pPart->getViewportWidth (),
00254                                                pPart->getViewportHeight());
00255
00256                 pPart->setupProjection(m, t);
00257
00258                 m = transforms[i];
00259
00260                 m[3][0] = oOrigin[0];
00261                 m[3][1] = oOrigin[1];
00262                 m[3][2] = oOrigin[2];
00263
00264                 m.invert();
00265
00266                 pPart->setupViewing(m);
00267
00268                 pPart->setNear     (pCam->getNear());
00269                 pPart->setFar      (pCam->getFar ());
00270
00271                 pPart->calcFrustum();
00272
00273                 if(this->getBackground() == NULL)
00274                 {
00275                     pPart->setBackground(pBack);
00276                 }
00277                 else
00278                 {
00279                     pPart->setBackground(this->getBackground());
00280                 }
00281
00282
00283                 pActNode->setTravMask(0);
00284
00285                 if(this->getRoot() != NULL)
00286                 {
00287                     this->recurse(a, this->getRoot());
00288                 }
00289                 else
00290                 {
00291                     this->recurse(a, pPort->getRoot());
00292                 }
00293
00294                 pActNode->setTravMask(~0);
00295
00296                 pPart->setDrawBuffer(GL_COLOR_ATTACHMENT0_EXT + i);
00297
00298 #ifdef OSG_DEBUGX
00299                 std::string szMessage("CubeX\n");
00300                 pPart->setDebugString(szMessage          );
00301 #endif
00302             }
00303             a->popPartition();
00304         }
00305     }
00306     a->endPartitionGroup();
00307
00308     OSG_ASSERT(pActNode == a->getActNode());
00309
00310     if(0x0000 != (_sfSetupMode.getValue() & SetupTexGen))
00311     {
00312         Matrix m = a->getActivePartition()->getCameraToWorld();
00313
00314         m[3][0] = 0.f;
00315         m[3][1] = 0.f;
00316         m[3][2] = 0.f;
00317
00318         CubeMapGeneratorStageData *pData =
00319             a->getData<CubeMapGeneratorStageData *>(_iDataSlotId);
00320
00321         pData->getTexTransform()->setMatrix(m);
00322     }
00323
00324     returnValue = Inherited::renderEnter(action);
00325
00326     action->useNodeList(false);
00327
00328     return returnValue;
00329 }
00330
00331 ActionBase::ResultE CubeMapGenerator::renderLeave(Action *action)
00332 {
00333     Action::ResultE returnValue = Action::Continue;
00334
00335     returnValue = Inherited::renderLeave(action);
00336
00337     return returnValue;
00338 }
00339
00340
00341 CubeMapGeneratorStageDataTransitPtr CubeMapGenerator::setupStageData(
00342     RenderActionBase *pAction)
00343 {
00344     CubeMapGeneratorStageDataTransitPtr returnValue =
00345         CubeMapGeneratorStageData::createLocal();
00346
00347     if(returnValue == NULL)
00348         return returnValue;
00349
00350     FrameBufferObjectUnrecPtr pCubeTarget  = NULL;
00351     RenderBufferUnrecPtr      pDepthBuffer = NULL;
00352
00353     if(this->getRenderTarget() == NULL)
00354     {
00355         pCubeTarget  = FrameBufferObject::createLocal();
00356         pDepthBuffer = RenderBuffer     ::createLocal();
00357
00358         pDepthBuffer->setInternalFormat (GL_DEPTH_COMPONENT24);
00359
00360         pCubeTarget ->setDepthAttachment(pDepthBuffer        );
00361
00362         returnValue ->setRenderTarget   (pCubeTarget         );
00363     }
00364     else
00365     {
00366         pCubeTarget = this->getRenderTarget();
00367     }
00368
00369     TextureObjChunkUnrecPtr   pCubeTex     = NULL;
00370
00371     if(0x0000 != (_sfSetupMode.getValue() & SetupTexture))
00372     {
00373         pCubeTex = TextureObjChunk::createLocal();
00374
00375         ImageUnrecPtr pImg = Image::createLocal();
00376
00377         pImg->set(Image::OSG_RGB_PF,
00378                   getWidth (),
00379                   getHeight(),
00380                   1,
00381                   1,
00382                   1,
00383                   0.0,
00384                   0,
00385                   Image::OSG_UINT8_IMAGEDATA,
00386                   false,
00387                   6);
00388
00389         pCubeTex   ->setImage         (pImg              );
00390         pCubeTex   ->setMinFilter     (GL_LINEAR         );
00391         pCubeTex   ->setMagFilter     (GL_LINEAR         );
00392         pCubeTex   ->setWrapS         (GL_REPEAT         );
00393         pCubeTex   ->setWrapT         (GL_REPEAT         );
00394         pCubeTex   ->setInternalFormat(getTextureFormat());
00395     }
00396     else
00397     {
00398         pCubeTex = _sfTexture.getValue();
00399     }
00400
00401     TextureEnvChunkUnrecPtr pCubeTexEnv  = NULL;
00402
00403     if(0x0000 != (_sfSetupMode.getValue() & SetupTexEnv))
00404     {
00405         pCubeTexEnv = TextureEnvChunk::createLocal();
00406
00407         pCubeTexEnv->setEnvMode       (GL_REPLACE       );
00408     }
00409
00410     TexGenChunkUnrecPtr           pCubeTexGen   = NULL;
00411     TextureTransformChunkUnrecPtr pCubeTexTrans = NULL;
00412
00413     if(0x0000 != (_sfSetupMode.getValue() & SetupTexGen))
00414     {
00415         pCubeTexGen = TexGenChunk::createLocal();
00416
00417         pCubeTexGen->setGenFuncS(GL_REFLECTION_MAP);
00418         pCubeTexGen->setGenFuncT(GL_REFLECTION_MAP);
00419         pCubeTexGen->setGenFuncR(GL_REFLECTION_MAP);
00420
00421         pCubeTexTrans = TextureTransformChunk::createLocal();
00422     }
00423
00424
00425     static GLenum targets[6] =
00426     {
00427         GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB,
00428         GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB,
00429         GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB,
00430         GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB,
00431         GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB,
00432         GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
00433     };
00434
00435     for(UInt32 i = 0; i < 6; ++i)
00436     {
00437         TextureBufferUnrecPtr pCubeTexBuffer = TextureBuffer::createLocal();
00438
00439         pCubeTexBuffer->setTexture  (pCubeTex  );
00440         pCubeTexBuffer->setTexTarget(targets[i]);
00441
00442         pCubeTarget->setColorAttachment(pCubeTexBuffer,    i);
00443     }
00444
00445     pCubeTarget->setSize(getWidth (),
00446                          getHeight());
00447
00448     if(0x0000 != (_sfSetupMode.getValue() & OverrideTex))
00449     {
00450         returnValue->addChunk(pCubeTex,
00451                               getTexUnit());
00452     }
00453
00454     if(0x0000 != (_sfSetupMode.getValue() & SetupTexEnv))
00455     {
00456         returnValue->addChunk(pCubeTexEnv,
00457                               getTexUnit());
00458     }
00459
00460     if(0x0000 != (_sfSetupMode.getValue() & SetupTexGen))
00461     {
00462         returnValue->addChunk(pCubeTexGen,
00463                               getTexUnit());
00464         returnValue->addChunk(pCubeTexTrans,
00465                               getTexUnit());
00466
00467         returnValue->setTexTransform(pCubeTexTrans);
00468     }
00469
00470     if(this->getCamera() == NULL)
00471     {
00472         PerspectiveCameraUnrecPtr pCam = PerspectiveCamera::createLocal();
00473
00474         pCam->setNear(pAction->getCamera()->getNear());
00475         pCam->setFar (pAction->getCamera()->getFar ());
00476
00477         pCam->setFov (osgDegree2Rad(90.f));
00478
00479         returnValue->setCamera(pCam);
00480     }
00481
00482     return returnValue;
00483 }
00484
00485 CubeMapGeneratorStageData *CubeMapGenerator::initData(RenderActionBase *pAction)
00486 {
00487     CubeMapGeneratorStageDataUnrecPtr pData =
00488         pAction->getData<CubeMapGeneratorStageData *>(_iDataSlotId);
00489
00490     if(pData == NULL)
00491     {
00492         pData = setupStageData(pAction);
00493
00494         this->setData(pData, _iDataSlotId, pAction);
00495     }
00496
00497     return pData;
00498 }
00499
00500
00501 OSG_END_NAMESPACE