Changeset 36 for trunk/VUT/OcclusionCullingSceneManager/src
- Timestamp:
- 03/31/05 17:51:17 (19 years ago)
- 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> 11 3 12 4 namespace Ogre { 13 14 5 //----------------------------------------------------------------------- 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 ) 235 7 { 236 8 mNumTraversedNodes ++; … … 251 23 } 252 24 //----------------------------------------------------------------------- 253 void OcclusionCulling SceneTraverser::renderSceneNode( Camera *cam, SceneNode *node )25 void OcclusionCullingTerrainSceneTraverser::renderSceneNode( Camera *cam, SceneNode *node ) 254 26 { 255 27 setRenderingMode(MODE_RENDER); … … 258 30 mSceneManager->_renderSceneNode(cam, node); 259 31 //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;281 32 } 282 33 //----------------------------------------------------------------------- … … 296 47 }*/ 297 48 //----------------------------------------------------------------------- 298 bool OcclusionCulling SceneTraverser::isLeaf( SceneNode *node )49 bool OcclusionCullingTerrainSceneTraverser::isLeaf( SceneNode *node ) 299 50 { 300 51 return (node->numChildren() == 0); 301 52 } 302 53 //----------------------------------------------------------------------- 303 void OcclusionCulling SceneTraverser::pullUpVisibility( SceneNode *node )54 void OcclusionCullingTerrainSceneTraverser::pullUpVisibility( SceneNode *node ) 304 55 { 305 56 while(node && !node->isNodeVisible()) … … 310 61 } 311 62 //----------------------------------------------------------------------- 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 ) 321 64 { 322 65 // Render two halfes of the bounding box (using triangle fans) … … 337 80 } 338 81 } 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 }416 82 }
Note: See TracChangeset
for help on using the changeset viewer.