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 "OSGDisplayFilterStage.h"
00049 #include "OSGRenderAction.h"
00050 #include "OSGMatrixUtility.h"
00051
00052 #include "OSGRenderBuffer.h"
00053 #include "OSGTextureBuffer.h"
00054 #include "OSGTextureObjChunk.h"
00055
00056 #include "OSGResolutionDisplayFilter.h"
00057 #include "OSGColorDisplayFilter.h"
00058 #include "OSGDistortionDisplayFilter.h"
00059
00060 OSG_BEGIN_NAMESPACE
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075 void DisplayFilterStage::initMethod(InitPhase ePhase)
00076 {
00077 Inherited::initMethod(ePhase);
00078
00079 if(ePhase == TypeObject::SystemPost)
00080 {
00081 RenderAction::registerEnterDefault(
00082 DisplayFilterStage::getClassType(),
00083 reinterpret_cast<Action::Callback>(
00084 &DisplayFilterStage::renderEnter));
00085
00086 RenderAction::registerLeaveDefault(
00087 DisplayFilterStage::getClassType(),
00088 reinterpret_cast<Action::Callback>(
00089 &DisplayFilterStage::renderLeave));
00090 }
00091 }
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104 DisplayFilterStage::DisplayFilterStage(void) :
00105 Inherited()
00106 {
00107 }
00108
00109 DisplayFilterStage::DisplayFilterStage(const DisplayFilterStage &source) :
00110 Inherited(source)
00111 {
00112 }
00113
00114 DisplayFilterStage::~DisplayFilterStage(void)
00115 {
00116 }
00117
00118
00119
00120 void DisplayFilterStage::changed(ConstFieldMaskArg whichField,
00121 UInt32 origin,
00122 BitVector details)
00123 {
00124 Inherited::changed(whichField, origin, details);
00125 }
00126
00127 void DisplayFilterStage::dump( UInt32 ,
00128 const BitVector ) const
00129 {
00130 SLOG << "Dump DisplayFilterStage NI" << std::endl;
00131 }
00132
00133 DisplayFilterStageDataTransitPtr
00134 DisplayFilterStage::setupStageData(Int32 iPixelWidth,
00135 Int32 iPixelHeight)
00136 {
00137 DisplayFilterStageDataTransitPtr returnValue =
00138 DisplayFilterStageData::createLocal();
00139
00140 if(returnValue == NULL)
00141 return returnValue;
00142
00143
00144
00145 FrameBufferObjectUnrecPtr pFBO = FrameBufferObject::createLocal();
00146 RenderBufferUnrecPtr pDBuffer = RenderBuffer ::createLocal();
00147 TextureBufferUnrecPtr pTBuffer = TextureBuffer ::createLocal();
00148
00149 TextureObjChunkUnrecPtr pTex = TextureObjChunk ::createLocal();
00150 ImageUnrecPtr pImg = Image ::createLocal();
00151
00152 pImg->set(Image::OSG_RGB_PF,
00153 iPixelWidth,
00154 iPixelHeight,
00155 1,
00156 1,
00157 1,
00158 0.0,
00159 0,
00160 Image::OSG_UINT8_IMAGEDATA,
00161 false);
00162
00163 pTex ->setImage (pImg );
00164 pTex ->setMinFilter (GL_NEAREST );
00165 pTex ->setMagFilter (GL_NEAREST );
00166 pTex ->setWrapS (GL_CLAMP_TO_EDGE );
00167 pTex ->setWrapT (GL_CLAMP_TO_EDGE );
00168
00169 pTBuffer->setTexture(pTex);
00170
00171 pDBuffer->setInternalFormat(GL_DEPTH_COMPONENT24);
00172
00173
00174 pFBO->setSize(iPixelWidth, iPixelHeight);
00175
00176 pFBO->setColorAttachment(pTBuffer, 0);
00177 pFBO->setDepthAttachment(pDBuffer );
00178
00179 pFBO->editMFDrawBuffers()->push_back(GL_COLOR_ATTACHMENT0_EXT);
00180
00181 returnValue->setTarget(pFBO);
00182
00183
00184 ChunkMaterialUnrecPtr pCMat = ChunkMaterial::createLocal();
00185
00186 pCMat->addChunk(pTex);
00187
00188 returnValue->setBaseMaterial(pCMat);
00189
00190 returnValue->setWidth (iPixelWidth );
00191 returnValue->setHeight(iPixelHeight);
00192
00193 commitChanges();
00194
00195 return returnValue;
00196 }
00197
00198 void DisplayFilterStage::resizeStageData(DisplayFilterStageData *pData,
00199 Int32 iPixelWidth,
00200 Int32 iPixelHeight)
00201 {
00202 FrameBufferObject *pFBO = pData->getTarget();
00203
00204 if(pFBO == NULL)
00205 return;
00206
00207 TextureBuffer *pTexBuffer =
00208 dynamic_cast<TextureBuffer *>(pFBO->getColorAttachments(0));
00209
00210 if(pTexBuffer == NULL)
00211 return;
00212
00213 TextureObjChunk *pTex = pTexBuffer->getTexture();
00214
00215 if(pTex == NULL)
00216 return;
00217
00218 Image *pImg = pTex->getImage();
00219
00220 if(pImg == NULL)
00221 return;
00222
00223 pImg->set(Image::OSG_RGB_PF,
00224 iPixelWidth,
00225 iPixelHeight,
00226 1,
00227 1,
00228 1,
00229 0.0,
00230 0,
00231 Image::OSG_UINT8_IMAGEDATA,
00232 false);
00233
00234 pFBO->setSize(iPixelWidth, iPixelHeight);
00235
00236 pData->setWidth (iPixelWidth );
00237 pData->setHeight(iPixelHeight);
00238
00239 commitChanges();
00240 }
00241
00242 ActionBase::ResultE DisplayFilterStage::renderEnter(Action *action)
00243 {
00244 RenderAction *ract = dynamic_cast<RenderAction *>(action);
00245
00246 if(ract == NULL)
00247 return Action::Continue;
00248
00249 DisplayFilterStageDataUnrecPtr pData =
00250 ract->getData<DisplayFilterStageData *>(_iDataSlotId);
00251
00252 DrawEnv &oEnv = ract->getActivePartition()->getDrawEnv();
00253
00254 bool bFilterActive = false;
00255
00256 ResolutionDisplayFilter *pResFilter = NULL;
00257 DistortionDisplayFilter *pDistFilter = NULL;
00258 ColorDisplayFilter *pColFilter = NULL;
00259
00260 if(_mfFilterGroups.size() == 0)
00261 {
00262 pResFilter = this->getResolutionFilter();
00263
00264 pColFilter = this->getColorFilter();
00265
00266 if(pColFilter != NULL &&
00267 pColFilter->getEnabled() == true )
00268 {
00269 if(pData != NULL)
00270 pData->setColFilter(pColFilter);
00271
00272 bFilterActive = true;
00273 }
00274 else
00275 {
00276 if(pData != NULL)
00277 {
00278 pData->setColFilter(NULL);
00279
00280 ColorDisplayFilter::deactivate(pData);
00281 }
00282 }
00283
00284 pDistFilter = this->getDistortionFilter();
00285
00286 if(pDistFilter != NULL &&
00287 pDistFilter->getEnabled() == true )
00288 {
00289 if(pData != NULL)
00290 pData->setDistFilter(pDistFilter);
00291
00292 bFilterActive = true;
00293 }
00294 else
00295 {
00296 if(pData != NULL)
00297 pData->setDistFilter(NULL);
00298 }
00299 }
00300 else
00301 {
00302
00303
00304 MFFilterGroupsType::const_iterator gIt = _mfFilterGroups.begin();
00305 MFFilterGroupsType::const_iterator gEnd = _mfFilterGroups.end ();
00306
00307 for(; gIt != gEnd; ++gIt)
00308 {
00309 if((*gIt)->matches(ract->getDrawerId(),
00310 ract->getDrawableId()) == true)
00311 {
00312 pResFilter = (*gIt)->getResolutionFilter();
00313
00314 pColFilter = (*gIt)->getColorFilter();
00315
00316 if(pColFilter != NULL &&
00317 pColFilter->getEnabled() == true )
00318 {
00319 if(pData != NULL)
00320 pData->setColFilter(pColFilter);
00321
00322 bFilterActive = true;
00323 }
00324 else
00325 {
00326 if(pData != NULL)
00327 {
00328 pData->setColFilter(NULL);
00329
00330 ColorDisplayFilter::deactivate(pData);
00331 }
00332 }
00333
00334
00335 pDistFilter = (*gIt)->getDistortionFilter();
00336
00337 if(pDistFilter != NULL &&
00338 pDistFilter->getEnabled() == true )
00339 {
00340 if(pData != NULL)
00341 pData->setDistFilter(pDistFilter);
00342
00343 bFilterActive = true;
00344 }
00345 else
00346 {
00347 if(pData != NULL)
00348 pData->setDistFilter(NULL);
00349 }
00350
00351 break;
00352 }
00353 }
00354 }
00355
00356
00357
00358
00359 UInt32 uiTargetWidth = oEnv.getPixelWidth ();
00360 UInt32 uiTargetHeight = oEnv.getPixelHeight();
00361
00362 Int32 iLeft = oEnv.getPixelLeft ();
00363 Int32 iRight = oEnv.getPixelRight ();
00364 Int32 iBottom = oEnv.getPixelBottom();
00365 Int32 iTop = oEnv.getPixelTop ();
00366
00367 if(pResFilter != NULL &&
00368 pResFilter->getEnabled() == true )
00369 {
00370 bFilterActive = true;
00371
00372 uiTargetWidth = UInt32(uiTargetWidth * pResFilter->getDownScale());
00373 uiTargetHeight = UInt32(uiTargetHeight * pResFilter->getDownScale());
00374
00375 iLeft = Int32(iLeft * pResFilter->getDownScale());
00376 iRight = Int32(iRight * pResFilter->getDownScale());
00377 iBottom = Int32(iBottom * pResFilter->getDownScale());
00378 iTop = Int32(iTop * pResFilter->getDownScale());
00379
00380 }
00381
00382 if(pData == NULL)
00383 {
00384 pData = setupStageData(uiTargetWidth,
00385 uiTargetHeight);
00386
00387 if(pData == NULL)
00388 return Action::Continue;
00389
00390 this->setData(pData, _iDataSlotId, ract);
00391
00392 pData->setColFilter (pColFilter );
00393 pData->setDistFilter(pDistFilter);
00394 }
00395
00396
00397 if((pData->getWidth () != uiTargetWidth ) ||
00398 (pData->getHeight() != uiTargetHeight) )
00399 {
00400 resizeStageData(pData, uiTargetWidth, uiTargetHeight);
00401 }
00402
00403
00404
00405
00406 if(bFilterActive == false)
00407 return Action::Continue;
00408
00409 ract->disableDefaultPartition();
00410
00411 ract->beginPartitionGroup();
00412 {
00413 ract->pushPartition();
00414 {
00415 RenderPartition *pPart = ract ->getActivePartition();
00416 FrameBufferObject *pTarget = pData->getTarget();
00417 Viewport *pPort = ract ->getViewport();
00418 Camera *pCam = ract ->getCamera ();
00419 Background *pBack = ract ->getBackground();
00420
00421
00422 pPart->setRenderTarget(pTarget);
00423
00424 if(pPort != NULL)
00425 {
00426 pPart->setWindow(ract->getWindow());
00427
00428 if(pTarget != NULL)
00429 {
00430 pPart->calcViewportDimension(iLeft ,
00431 iBottom,
00432 iRight ,
00433 iTop ,
00434
00435 pTarget->getWidth (),
00436 pTarget->getHeight ());
00437 }
00438 else
00439 {
00440 pPart->calcViewportDimension(
00441 pPort->getLeft (),
00442 pPort->getBottom(),
00443 pPort->getRight (),
00444 pPort->getTop (),
00445
00446 ract->getWindow()->getWidth (),
00447 ract->getWindow()->getHeight());
00448 }
00449
00450 if(pCam != NULL)
00451 {
00452 Matrix m, t;
00453
00454
00455 pCam->getProjection (m,
00456 pPart->getViewportWidth (),
00457 pPart->getViewportHeight());
00458
00459 pCam->getProjectionTranslation(t,
00460 pPart->getViewportWidth (),
00461 pPart->getViewportHeight());
00462
00463 pPart->setupProjection(m, t);
00464
00465 pCam->getViewing(m,
00466 pPart->getViewportWidth (),
00467 pPart->getViewportHeight());
00468
00469
00470 pPart->setupViewing(m);
00471
00472 pPart->setNear (pCam->getNear());
00473 pPart->setFar (pCam->getFar ());
00474
00475 pPart->calcFrustum();
00476 }
00477
00478 pPart->setBackground(pBack);
00479 }
00480
00481 this->recurseFromThis(ract);
00482 }
00483 ract->popPartition();
00484
00485 ract->pushPartition((RenderPartition::CopyWindow |
00486 RenderPartition::CopyViewportSize),
00487 RenderPartition::SimpleCallback);
00488 {
00489 RenderPartition *pPart = ract->getActivePartition();
00490
00491 Matrix m, t;
00492
00493 m.setIdentity();
00494 t.setIdentity();
00495
00496 MatrixOrthogonal( m,
00497 0.f, 1.f,
00498 0.f, 1.f,
00499 -1.f, 1.f);
00500
00501 pPart->setupProjection(m, t);
00502
00503 RenderPartition::SimpleDrawCallback f;
00504
00505 f = boost::bind(&DisplayFilterStage::postProcess, this, _1);
00506
00507 pPart->dropFunctor(f);
00508 }
00509 ract->popPartition();
00510 }
00511 ract->endPartitionGroup();
00512
00513 return Action::Skip;
00514 }
00515
00516 ActionBase::ResultE DisplayFilterStage::renderLeave(Action *action)
00517 {
00518 return Action::Skip;
00519 }
00520
00521 void DisplayFilterStage::postProcess(DrawEnv *pEnv)
00522 {
00523 DisplayFilterStageData *pData =
00524 pEnv->getData<DisplayFilterStageData *>(_iDataSlotId);
00525
00526 if(pData == NULL)
00527 return;
00528
00529 ColorDisplayFilter *pColFilter = pData->getColFilter ();
00530 DistortionDisplayFilter *pDistFilter = pData->getDistFilter();
00531
00532
00533 ChunkMaterial *pSourceMat = pData->getBaseMaterial();
00534 State *pSourceState = pSourceMat->getState();
00535
00536 glColor3f(1.f, 0.f, 0.f);
00537
00538 glMatrixMode(GL_MODELVIEW);
00539 glPushMatrix();
00540
00541 glLoadIdentity();
00542
00543 if(pColFilter != NULL)
00544 {
00545 pColFilter->process(pData);
00546 }
00547
00548 pEnv->activateState(pSourceState, NULL);
00549
00550 if(pColFilter == NULL)
00551 {
00552 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
00553 }
00554
00555 if(pDistFilter != NULL)
00556 {
00557 pDistFilter->process(pData);
00558 }
00559 else
00560 {
00561 glBegin(GL_QUADS);
00562 {
00563 glTexCoord2f(0.00, 0.00);
00564 glVertex2f (0.00, 0.00);
00565
00566 glTexCoord2f(1.00, 0.00);
00567 glVertex2f (1.00, 0.00);
00568
00569 glTexCoord2f(1.00, 1.00);
00570 glVertex2f (1.00, 1.00);
00571
00572 glTexCoord2f(0.00, 1.00);
00573 glVertex2f (0.00, 1.00);
00574 }
00575 glEnd();
00576 }
00577
00578 if(pColFilter == NULL)
00579 {
00580 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
00581 }
00582
00583 pEnv->deactivateState();
00584
00585 glPopMatrix();
00586 }
00587
00588 OSG_END_NAMESPACE