Ignore:
Timestamp:
03/31/05 17:51:17 (19 years ago)
Author:
mattausch
Message:
 
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/VUT/OcclusionCullingSceneManager/src/OgreOcclusionCullingTerrainSceneTraverser.cpp

    r35 r36  
    1 #include "OgreOcclusionCullingSceneTraverser.h" 
    2 #include "OgreMath.h" 
    3 #include "OgreIteratorWrappers.h" 
    4 #include "OgreCamera.h" 
    5 #include "OgreHardwareOcclusionQuery.h" 
    6 //#include "OgreWireBoundingBox.h" 
    7 #include "OgreSolidHalfBoundingBox.h" 
    8  
    9  
    10 #include <windows.h> 
     1#include "OgreOcclusionCullingTerrainSceneTraverser.h" 
     2//#include <windows.h> 
    113 
    124namespace Ogre { 
    13          
    145        //----------------------------------------------------------------------- 
    15         OcclusionCullingSceneTraverser::OcclusionCullingSceneTraverser(SceneManager *sm, RenderSystem *rsys):  
    16         mFrameId(1), mDistanceQueue(NULL), mVisibilityThreshold(0), mCurrentTestIdx(0), 
    17         mQueryMode(MODE_RENDER), mNumSceneNodes(0), mCurrentAlgorithm(RENDER_COHERENT), 
    18         mNumTraversedNodes(0), mNumQueryCulledNodes(0), mNumFrustumCulledNodes(0),  
    19         mNumRenderedGeometry(0), mSceneManager(sm), mRenderSystem(rsys) 
    20         {                
    21                 mHalfBoundingBox[0] = mHalfBoundingBox[1] = 0; 
    22         } 
    23         //----------------------------------------------------------------------- 
    24         OcclusionCullingSceneTraverser::~OcclusionCullingSceneTraverser() 
    25         {                
    26                 if(mHalfBoundingBox[0]) delete mHalfBoundingBox[0]; 
    27                 if(mHalfBoundingBox[1]) delete mHalfBoundingBox[1]; 
    28  
    29                 deleteQueries(); 
    30                 //SceneManager::~SceneManager(); 
    31         } 
    32         //----------------------------------------------------------------------- 
    33         void OcclusionCullingSceneTraverser::renderScene( Camera *cam, SceneNode *root ) 
    34         { 
    35                 mNumTraversedNodes = 0; 
    36                 mNumQueryCulledNodes = 0; 
    37                 mNumFrustumCulledNodes = 0; 
    38                 mNumRenderedGeometry = 0; 
    39                  
    40                 mDistanceQueue = new PriorityQueue(myless<SceneNode *>(cam)); 
    41                 mDistanceQueue->push(root); 
    42                 mCurrentTestIdx = 0; 
    43  
    44                 mCurrentAlgorithm = RENDER_CULL_FRUSTUM; 
    45                 switch(mCurrentAlgorithm) 
    46                 { 
    47                         case RENDER_CULL_FRUSTUM: 
    48                                 renderCullFrustum(cam); 
    49                         break; 
    50                         case RENDER_STOP_AND_WAIT: 
    51                                 renderStopAndWait(cam); 
    52                                 break; 
    53                         case RENDER_COHERENT: 
    54                                 renderCoherentWithQueue(cam); 
    55                                 break; 
    56                         default: 
    57                                 renderCullFrustum(cam); 
    58                                 break; 
    59                 }        
    60                  
    61                 delete mDistanceQueue; 
    62  
    63                 mFrameId ++; 
    64         } 
    65         //----------------------------------------------------------------------- 
    66         void OcclusionCullingSceneTraverser::renderCoherentWithQueue(Camera *cam) 
    67         { 
    68                 QueryQueue queryQueue; 
    69  
    70                 //-- PART 1: process finished occlusion queries 
    71                 while(!mDistanceQueue->empty() || !queryQueue.empty()) 
    72                 { 
    73                         while(!queryQueue.empty() &&  
    74                                   ((queryQueue.front().second)->resultAvailable() || mDistanceQueue->empty())) 
    75                         { 
    76                                 SceneNode *node = queryQueue.front().first; 
    77                                 HardwareOcclusionQuery *query = queryQueue.front().second; 
    78  
    79                                 queryQueue.pop(); 
    80                          
    81                                 // wait until result available 
    82                                 unsigned int visiblePixels; 
    83                                 query->pullOcclusionQuery(&visiblePixels); 
    84  
    85                                 if(visiblePixels > mVisibilityThreshold) 
    86                                 { 
    87                                         pullUpVisibility(node); 
    88                                         traverseNode(cam, node); 
    89                                 } 
    90                                 else 
    91                                 { 
    92                                         mNumQueryCulledNodes ++; 
    93                                 } 
    94                         }        
    95  
    96                         //-- PART 2: hierarchical traversal 
    97                         if(!mDistanceQueue->empty()) 
    98                         { 
    99                                 SceneNode *node = mDistanceQueue->top(); 
    100                                 mDistanceQueue->pop(); 
    101          
    102                                 if(cam->isVisible(node->_getWorldAABB())) 
    103                                 { 
    104                                         // identify previously visible nodes 
    105                                         bool wasVisible = node->isNodeVisible() && (node->lastVisited() == mFrameId - 1); 
    106                                          
    107                                         // identify nodes that we cannot skip queries for 
    108                                         bool leafOrWasInvisible = !wasVisible || isLeaf(node); 
    109  
    110                                         // reset node's visibility classification  
    111                                         node->setNodeVisible(false); 
    112  
    113                                         // update node's visited flag 
    114                                         node->setLastVisited(mFrameId); 
    115                                  
    116                                         // skip testing previously visible interior nodes 
    117                                         if(leafOrWasInvisible) 
    118                                         { 
    119                                                 HardwareOcclusionQuery *query = issueOcclusionQuery(node, wasVisible); 
    120                                                 queryQueue.push(query_pair(node, query)); 
    121                                         } 
    122                                          
    123                                         // always traverse a node if it was visible 
    124                                         if(wasVisible) 
    125                                         { 
    126                                                 traverseNode(cam, node); 
    127                                         } 
    128                                 } 
    129                                 else 
    130                                 { 
    131                                         mNumFrustumCulledNodes ++; 
    132                                 } 
    133                         } 
    134                 } 
    135         } 
    136         //----------------------------------------------------------------------- 
    137         void OcclusionCullingSceneTraverser::renderCullFrustum(Camera *cam) 
    138         { 
    139                 while(!mDistanceQueue->empty()) 
    140                 { 
    141                         SceneNode *node = mDistanceQueue->top(); 
    142                         mDistanceQueue->pop(); 
    143          
    144                         // interesting for visualization purpose 
    145                         node->setNodeVisible(false); 
    146                                  
    147                         if(!cam->isVisible(node->_getWorldAABB())) 
    148                         { 
    149                                 // update node's visited flag  
    150                                 node->setLastVisited(mFrameId); 
    151                                 node->setNodeVisible(true); 
    152                                 traverseNode(cam, node); 
    153                         } 
    154                         //else 
    155                                 if(cam->isVisible(node->_getWorldAABB())) 
    156                                 { 
    157                                         mNumQueryCulledNodes ++; 
    158                                 }else 
    159                         {                        
    160                                 mNumFrustumCulledNodes ++; 
    161                         } 
    162                 } 
    163         }        
    164         //----------------------------------------------------------------------- 
    165         void OcclusionCullingSceneTraverser::renderStopAndWait(Camera *cam) 
    166         { 
    167                 while(!mDistanceQueue->empty()) 
    168                 { 
    169                         SceneNode *node = mDistanceQueue->top(); 
    170                         mDistanceQueue->pop(); 
    171                  
    172                         // interesting for the visualization 
    173                         node->setNodeVisible(false); 
    174                         node->setLastVisited(mFrameId); 
    175  
    176                         if(cam->isVisible(node->_getWorldAABB())) 
    177                         { 
    178                                 HardwareOcclusionQuery *query = issueOcclusionQuery(node, false); 
    179                                  
    180                                 unsigned int visiblePixels; 
    181                                 // wait if result not available 
    182                                 query->pullOcclusionQuery(&visiblePixels); 
    183                                  
    184                                 // node visible 
    185                                 if(visiblePixels > mVisibilityThreshold) 
    186                                 { 
    187                                         traverseNode(cam, node); 
    188                                 } 
    189                                 else 
    190                                 { 
    191                                         mNumQueryCulledNodes ++; 
    192                                 } 
    193                         } 
    194                         else 
    195                         { 
    196                                 mNumFrustumCulledNodes ++; 
    197                         } 
    198                 } 
    199         } 
    200         //----------------------------------------------------------------------- 
    201         HardwareOcclusionQuery *OcclusionCullingSceneTraverser::issueOcclusionQuery( SceneNode *node, bool wasVisible ) 
    202         { 
    203                 // change state so the bounding box gets not actually rendered on the screen 
    204                 setRenderingMode(MODE_QUERY); 
    205  
    206                 // get next available test id 
    207                 HardwareOcclusionQuery *query = mOcclusionQueries[mCurrentTestIdx++]; 
    208                  
    209                 query->beginOcclusionQuery(); 
    210                                  
    211                 renderBoundingBox(node); 
    212  
    213                 query->endOcclusionQuery(); 
    214  
    215                 return query; 
    216         } 
    217         //----------------------------------------------------------------------- 
    218         void OcclusionCullingSceneTraverser::setRenderingMode( int mode ) 
    219         {        
    220                 // avoid unnecessary state changes 
    221                 if(mode != mQueryMode) 
    222                 { 
    223                         bool enabled = (mode == MODE_RENDER); 
    224                          
    225                         mRenderSystem->_setColourBufferWriteEnabled(enabled,  
    226                                 enabled, enabled, enabled); 
    227                         mRenderSystem->_setDepthBufferWriteEnabled(enabled); 
    228                         mRenderSystem->setLightingEnabled(enabled); 
    229  
    230                         mQueryMode = mode; 
    231                 } 
    232         } 
    233         //----------------------------------------------------------------------- 
    234         void OcclusionCullingSceneTraverser::traverseNode( Camera *cam, SceneNode *node ) 
     6        void OcclusionCullingTerrainSceneTraverser::traverseNode( Camera *cam, SceneNode *node ) 
    2357        { 
    2368                mNumTraversedNodes ++; 
     
    25123        } 
    25224        //----------------------------------------------------------------------- 
    253         void OcclusionCullingSceneTraverser::renderSceneNode( Camera *cam, SceneNode *node ) 
     25        void OcclusionCullingTerrainSceneTraverser::renderSceneNode( Camera *cam, SceneNode *node ) 
    25426        { 
    25527                setRenderingMode(MODE_RENDER); 
     
    25830                mSceneManager->_renderSceneNode(cam, node); 
    25931                //MessageBox( NULL, "myplugin registered", "this is my plugin", MB_OK | MB_ICONERROR | MB_TASKMODAL); 
    260         } 
    261         //----------------------------------------------------------------------- 
    262         void OcclusionCullingSceneTraverser::preprocess( void ) 
    263         { 
    264                 //-- initialise occlusion queries. 
    265                 deleteQueries(); 
    266                  
    267                 for(unsigned int i=0; i < mNumSceneNodes; i++) 
    268                 { 
    269                         mOcclusionQueries.push_back(mRenderSystem->createHardwareOcclusionQuery()); 
    270                 }        
    271         } 
    272         //----------------------------------------------------------------------- 
    273         void OcclusionCullingSceneTraverser::setSceneManager( SceneManager *sm ) 
    274         { 
    275                 mSceneManager = sm; 
    276         } 
    277         //----------------------------------------------------------------------- 
    278         void OcclusionCullingSceneTraverser::setRenderSystem( RenderSystem *rsys ) 
    279         { 
    280                 mRenderSystem = rsys; 
    28132        } 
    28233        //----------------------------------------------------------------------- 
     
    29647        }*/ 
    29748        //----------------------------------------------------------------------- 
    298         bool OcclusionCullingSceneTraverser::isLeaf( SceneNode *node ) 
     49        bool OcclusionCullingTerrainSceneTraverser::isLeaf( SceneNode *node ) 
    29950        { 
    30051                return (node->numChildren() == 0); 
    30152        } 
    30253        //----------------------------------------------------------------------- 
    303         void OcclusionCullingSceneTraverser::pullUpVisibility( SceneNode *node ) 
     54        void OcclusionCullingTerrainSceneTraverser::pullUpVisibility( SceneNode *node ) 
    30455        { 
    30556                while(node && !node->isNodeVisible()) 
     
    31061        } 
    31162        //----------------------------------------------------------------------- 
    312         void OcclusionCullingSceneTraverser::deleteQueries( void ) 
    313         { 
    314                 for(unsigned int i=0; i < mNumSceneNodes; i++) 
    315                         delete mOcclusionQueries[i]; 
    316  
    317                 mOcclusionQueries.clear(); 
    318         } 
    319         //----------------------------------------------------------------------- 
    320         void OcclusionCullingSceneTraverser::renderBoundingBox( SceneNode *node ) 
     63        void OcclusionCullingTerrainSceneTraverser::renderBoundingBox( SceneNode *node ) 
    32164        { 
    32265                // Render two halfes of the bounding box (using triangle fans) 
     
    33780                } 
    33881        } 
    339         //----------------------------------------------------------------------- 
    340         SolidHalfBoundingBox *OcclusionCullingSceneTraverser::getSolidHalfBoundingBox( int half ) 
    341         { 
    342                 if(!mHalfBoundingBox[half]) 
    343                         mHalfBoundingBox[half] = new SolidHalfBoundingBox(half == 1); 
    344  
    345                 return mHalfBoundingBox[half];   
    346         } 
    347         //----------------------------------------------------------------------- 
    348         bool OcclusionCullingSceneTraverser::setOption( const String & key, const void * val ) 
    349         { 
    350                 if ( key == "Algorithm" ) 
    351                 { 
    352                         mCurrentAlgorithm = * static_cast < const int * > ( val ); 
    353                         return true; 
    354                 } 
    355                 if ( key == "Threshold" ) 
    356                 { 
    357                         mVisibilityThreshold = * static_cast < const int * > ( val ); 
    358                         return true; 
    359                 } 
    360  
    361                 return false; 
    362         } 
    363         //----------------------------------------------------------------------- 
    364         bool OcclusionCullingSceneTraverser::getOption( const String & key, void *val ) 
    365         { 
    366                 if ( key == "Algorithm" ) 
    367                 { 
    368                         * static_cast < int * > ( val ) = mCurrentAlgorithm; 
    369                         return true; 
    370                 } 
    371                 if ( key == "Threshold" ) 
    372                 { 
    373                         * static_cast < unsigned int * > ( val ) = mVisibilityThreshold; 
    374                         return true; 
    375                 } 
    376                 if ( key == "NumSceneNodes" ) 
    377                 { 
    378                         * static_cast < unsigned int * > ( val ) = mNumSceneNodes; 
    379                         return true; 
    380                 } 
    381                 if ( key == "NumTraversedNodes" ) 
    382                 { 
    383                         * static_cast < unsigned int * > ( val ) = mNumTraversedNodes; 
    384                         return true; 
    385                 } 
    386                 if ( key == "NumQueryCulledNodes" ) 
    387                 { 
    388                         * static_cast < unsigned int * > ( val ) = mNumQueryCulledNodes; 
    389                         return true; 
    390                 } 
    391                 if ( key == "NumFrustumCulledNodes" ) 
    392                 { 
    393                         * static_cast < unsigned int * > ( val ) = mNumFrustumCulledNodes; 
    394                         return true; 
    395                 } 
    396                 return false; 
    397         } 
    398         //----------------------------------------------------------------------- 
    399         bool OcclusionCullingSceneTraverser::getOptionKeys( StringVector & refKeys ) 
    400         { 
    401                 refKeys.push_back( "Algorithm" ); 
    402                 refKeys.push_back( "Threshold" ); 
    403                 refKeys.push_back( "NumSceneNodes" ); 
    404                 refKeys.push_back( "NumTraversedNodes" ); 
    405                 refKeys.push_back( "NumQueryCulledNodes" ); 
    406                 refKeys.push_back( "NumFrustumCulledNodes" ); 
    407                 //refKeys.push_back( "mNumRenderedGeometry" ); 
    408  
    409                 return true; 
    410         } 
    411         //----------------------------------------------------------------------- 
    412         void OcclusionCullingSceneTraverser::setNumSceneNodes(int num) 
    413         { 
    414                 mNumSceneNodes = num; 
    415         } 
    41682}        
Note: See TracChangeset for help on using the changeset viewer.