Changeset 36
- Timestamp:
- 03/31/05 17:51:17 (20 years ago)
- Location:
- trunk/VUT/OcclusionCullingSceneManager
- Files:
-
- 4 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/VUT/OcclusionCullingSceneManager/include/OgreOcclusionCullingSceneTraverser.h
r33 r36 100 100 //HACK 101 101 //unsigned int countSceneNodes(SceneNode *node); 102 v oid traverseNode( Camera *cam, SceneNode *node );102 virtual void traverseNode( Camera *cam, SceneNode *node ); 103 103 /** Renders current scene node 104 104 @param cam current camera -
trunk/VUT/OcclusionCullingSceneManager/include/OgreOcclusionCullingTerrainSceneTraverser.h
r35 r36 1 #ifndef _OcclusionCulling SceneTraverser_H__2 #define _OcclusionCulling SceneTraverser_H__1 #ifndef _OcclusionCullingTerrainSceneTraverser_H__ 2 #define _OcclusionCullingTerrainSceneTraverser_H__ 3 3 4 #include "OgreSceneNode.h" 5 #include "OgreSceneManager.h" 6 #include "OgrePrerequisites.h" 7 #include "OgreSolidHalfBoundingBox.h" 8 #include "OgreCamera.h" 9 #include "OgreRenderSystem.h" 10 #include <queue> 4 #include "OgreOcclusionCullingSceneTraverser.h" 11 5 12 6 using namespace std; 13 7 14 8 namespace Ogre { 15 /** 16 This class implements the compare operator for the priority queue. 17 a lower distance has a higher value in the queue 18 */ 19 template <typename T> class myless 9 10 class OcclusionCullingTerrainSceneTraverser: OcclusionCullingSceneTraverser 20 11 { 21 public:22 myless(Camera *cam) { mCamera = cam; }23 //bool operator() (HierarchyNode *v1, HierarchyNode *v2) const24 bool operator() (T v1, T v2) const25 {26 return v1->getSquaredViewDepth(mCamera) > v2->getSquaredViewDepth(mCamera);27 }28 private:29 Camera *mCamera;30 };31 32 typedef pair<SceneNode *, HardwareOcclusionQuery *> query_pair;33 typedef priority_queue<SceneNode *, vector<SceneNode *>, myless<vector<SceneNode *>::value_type> > PriorityQueue;34 typedef queue<query_pair> QueryQueue;35 /**36 Class which implements a scene mangager which uses occlusion queries for culling occluded objects37 */38 class OcclusionCullingSceneTraverser39 {40 public:41 /** Construction taking the current scene manager and the current rendersystem as argument42 @param sm current scene manager43 @param rsys current render system44 */45 OcclusionCullingSceneTraverser(SceneManager *sm, RenderSystem *rsys);46 ~OcclusionCullingSceneTraverser();47 48 enum {RENDER_CULL_FRUSTUM, RENDER_STOP_AND_WAIT, RENDER_COHERENT, NUM_RENDERMODES};49 50 /** Renders the scene with the specified algorithm51 @comment52 The algorithm type can be set with the parameter "Algorithm" and setOption.53 54 The algorithm is one of:55 RENDER_CULL_FRUSTUM: renders the scene with view frustum culling only56 RENDER_STOP_AND_WAIT: renders the scene with the hierarchical stop and wait algorithm57 RENDER_COHERENT: renders the scene with the coherent hierarchical algorithm58 59 @param cam current camera60 @param root root of hierarchy61 */62 void renderScene( Camera *cam, SceneNode *root );63 64 65 /** Sets the given option for the scene traverser.66 @remarks67 Options are:68 "Algorithm", int *;69 */70 bool setOption( const String &, const void * );71 /** Gets the given option for the scene traverser.72 @remarks73 See setOption74 */75 bool getOption( const String &, void * );76 bool getOptionKeys( StringVector &refKeys );77 78 /** Sets pointer to the current scene manager.79 @param the scene manager */80 void setSceneManager( SceneManager *sm );81 82 /** Sets pointer to the current render system83 @param the rendersystem */84 void setRenderSystem( RenderSystem *rsys );85 86 /** Doing some necessary preprocessing.87 @comment e.g., initialises occlusion queries */88 void preprocess( void );89 90 /** Sets the current number of scene nodes in the scene.91 @param num number of scene nodes92 */93 void setNumSceneNodes(int num );94 95 protected:96 /** query mode (= without color) or RENDER_MODE */97 enum {MODE_QUERY, MODE_RENDER};98 /** returns true if node is leaf of the hierarchy */99 bool isLeaf( SceneNode *node );100 //HACK101 //unsigned int countSceneNodes(SceneNode *node);102 12 void traverseNode( Camera *cam, SceneNode *node ); 103 /** Renders current scene node104 @param cam current camera105 @param node current scene node to be rendered106 */107 void renderSceneNode( Camera *cam, SceneNode *node);108 /** Sets rendering mode, e.g. query mode or render mode*/109 void setRenderingMode( int mode );110 /** Renders the scene with view frustum culling only. */111 void renderCullFrustum( Camera *cam );112 /** Renders the scene with the hierarchical stop and wait algorithm. */113 void renderStopAndWait( Camera *cam );114 /** Renders the scene with the coherent hierarchical algorithm and the query queye. */115 void renderCoherentWithQueue( Camera *cam );116 /** Issue a occlusion query for this node. */117 HardwareOcclusionQuery *issueOcclusionQuery( SceneNode *node, bool wasVisible );118 /** Pulls up the visibility from the child nodes. */119 void pullUpVisibility( SceneNode *node );120 /** delete all previously defined occlusion queries */121 void deleteQueries();122 /** Renders bounding box of specified node.123 @param the scene node contained in the bounding box to be rendered124 */125 void renderBoundingBox( SceneNode *node );126 /** Returns one half of the bounding box.127 @param the half of the bouding box128 */129 SolidHalfBoundingBox *getSolidHalfBoundingBox( int half );130 131 // we use a priority queue rather than a renderstack132 PriorityQueue *mDistanceQueue;133 134 std::vector<HardwareOcclusionQuery *> mOcclusionQueries;135 // two halfes of a aabb136 SolidHalfBoundingBox *mHalfBoundingBox[2];137 138 int mCurrentAlgorithm;139 140 unsigned int mFrameId;141 unsigned int mVisibilityThreshold;142 143 SceneManager *mSceneManager;144 RenderSystem *mRenderSystem;145 146 int mCurrentTestIdx;147 int mQueryMode;148 149 //--- statistics150 unsigned int mNumSceneNodes;151 unsigned int mNumTraversedNodes;152 unsigned int mNumQueryCulledNodes;153 unsigned int mNumFrustumCulledNodes;154 unsigned int mNumRenderedGeometry;155 13 }; 156 14 157 15 } 158 #endif // O CCLUSIONCULLINGSCENEMANAGER_H16 #endif // OcclusionCullingTerrainSceneTraverser_H -
trunk/VUT/OcclusionCullingSceneManager/scripts/Plugin_OcclusionCullingSceneManager.sln
r16 r36 6 6 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestCulling", "..\TestCulling\TestCulling.vcproj", "{248F19A6-2FE0-4F5D-8928-E0EA10609887}" 7 7 ProjectSection(ProjectDependencies) = postProject 8 {80DECC17-BDDD-4412-8CF8-F7C1C17A7436} = {80DECC17-BDDD-4412-8CF8-F7C1C17A7436} 8 EndProjectSection 9 EndProject 10 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestCullingDotScene", "..\TestCullingDotScene\TestCullingDotScene.vcproj", "{BE13944C-D05E-467F-B0AC-8A65A3B5FE60}" 11 ProjectSection(ProjectDependencies) = postProject 9 12 EndProjectSection 10 13 EndProject … … 23 26 {248F19A6-2FE0-4F5D-8928-E0EA10609887}.Release.ActiveCfg = Release|Win32 24 27 {248F19A6-2FE0-4F5D-8928-E0EA10609887}.Release.Build.0 = Release|Win32 28 {BE13944C-D05E-467F-B0AC-8A65A3B5FE60}.Debug.ActiveCfg = Debug|Win32 29 {BE13944C-D05E-467F-B0AC-8A65A3B5FE60}.Debug.Build.0 = Debug|Win32 30 {BE13944C-D05E-467F-B0AC-8A65A3B5FE60}.Release.ActiveCfg = Release|Win32 31 {BE13944C-D05E-467F-B0AC-8A65A3B5FE60}.Release.Build.0 = Release|Win32 25 32 EndGlobalSection 26 33 GlobalSection(ExtensibilityGlobals) = postSolution -
trunk/VUT/OcclusionCullingSceneManager/scripts/Plugin_OcclusionCullingSceneManager.vcproj
r33 r36 163 163 </File> 164 164 <File 165 RelativePath="..\src\OgreOcclusionCullingTerrainSceneTraverser.cpp"> 166 </File> 167 <File 165 168 RelativePath="..\src\OgreSolidHalfBoundingBox.cpp"> 166 169 </File> … … 183 186 <File 184 187 RelativePath="..\include\OgreOcclusionCullingTerrainSceneManager.h"> 188 </File> 189 <File 190 RelativePath="..\include\OgreOcclusionCullingTerrainSceneTraverser.h"> 185 191 </File> 186 192 <File -
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.