00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
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
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
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
00097
00098
00099
00100
00101
00102
00103
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
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
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