OSGDisplayFilterStage.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 "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 // Documentation for this class is emitted in the
00063 // OSGDisplayFilterStageBase.cpp file.
00064 // To modify it, please change the .fcd file (OSGDisplayFilterStage.fcd) and
00065 // regenerate the base file.
00066
00067 /***************************************************************************\
00068  *                           Class variables                               *
00069 \***************************************************************************/
00070
00071 /***************************************************************************\
00072  *                           Class methods                                 *
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  *                           Instance methods                              *
00096 \***************************************************************************/
00097
00098 /*-------------------------------------------------------------------------*\
00099  -  private                                                                 -
00100 \*-------------------------------------------------------------------------*/
00101
00102 /*----------------------- constructors & destructors ----------------------*/
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 /*----------------------------- class specific ----------------------------*/
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     // Scene Buffer
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         // Linear search, optimize of needed
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                     // set the projection
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