#ifndef _OcclusionCullingSceneTraverser_H__ #define _OcclusionCullingSceneTraverser_H__ #include "OgreSceneNode.h" #include "OgreSceneManager.h" #include "OgrePrerequisites.h" #include "OgreSolidHalfBoundingBox.h" #include "OgreCamera.h" #include "OgreRenderSystem.h" #include using namespace std; namespace Ogre { /** This class implements the compare operator for the priority queue. a lower distance has a higher value in the queue */ template class myless { public: myless(Camera *cam) { mCamera = cam; } //bool operator() (HierarchyNode *v1, HierarchyNode *v2) const bool operator() (T v1, T v2) const { return v1->getSquaredViewDepth(mCamera) > v2->getSquaredViewDepth(mCamera); } private: Camera *mCamera; }; typedef pair query_pair; typedef priority_queue, myless::value_type> > PriorityQueue; typedef queue QueryQueue; /** Class which implements a scene mangager which uses occlusion queries for culling occluded objects */ class OcclusionCullingSceneTraverser { public: OcclusionCullingSceneTraverser(); ~OcclusionCullingSceneTraverser(); enum {RENDER_CULL_FRUSTUM, RENDER_STOP_AND_WAIT, RENDER_COHERENT, NUM_RENDERMODES}; /** Overriden from SceneManager. Renders the scene with the specified algorithm /** The algorithm is one of RENDER_CULL_FRUSTUM: renders the scene with view frustum culling only RENDER_STOP_AND_WAIT: renders the scene with the hierarchical stop and wait algorithm RENDER_COHERENT: renders the scene with the coherent hierarchical algorithm */ /** Sets the given option for the SceneTraverser @remarks Options are: "Algorithm", int *; */ bool setOption( const String &, const void * ); /** Gets the given option for the SceneTraverser. @remarks See setOption */ bool getOption( const String &, void * ); /** Renders current scene @param cam current camera @param root root of hierarchy */ void renderScene( Camera *cam, SceneNode *root ); /** Sets the scene manager */ void setSceneManager( SceneManager *sm ); /** Sets the render system */ void setRenderSystem( RenderSystem *rsys ); void preprocess( void ); protected: enum {MODE_QUERY, MODE_RENDER}; /** returns true if node is leaf of the hierarchy */ bool isLeaf( SceneNode *node ); //HACK //unsigned int countSceneNodes(SceneNode *node); void traverseNode( Camera *cam, SceneNode *node ); /** Renders current scene node @param cam current camera @param node current scene node to be rendered */ void renderSceneNode( Camera *cam, SceneNode *node); /** Sets rendering mode, e.g. query mode or render mode*/ void setRenderingMode( int mode ); /** Renders the scene with view frustum culling only. */ void renderCullFrustum( Camera *cam ); /** Renders the scene with the hierarchical stop and wait algorithm. */ void renderStopAndWait( Camera *cam ); /** Renders the scene with the coherent hierarchical algorithm and the query queye. */ void renderCoherentWithQueue( Camera *cam ); /** Issue a occlusion query for this node. */ HardwareOcclusionQuery *issueOcclusionQuery( SceneNode *node, bool wasVisible ); /** Pulls up the visibility from the child nodes. */ void pullUpVisibility( SceneNode *node ); /** delete all previously defined occlusion queries */ void deleteQueries(); /** Renders bounding box of specified node. @param the scene node contained in the bounding box to be rendered */ void renderBoundingBox( SceneNode *node ); /** Returns one half of the bounding box. @param the half of the bouding box */ SolidHalfBoundingBox *getSolidHalfBoundingBox( int half ); // we use a priority queue rather than a renderstack PriorityQueue *mDistanceQueue; std::vector mOcclusionQueries; // two halfes of a aabb SolidHalfBoundingBox *mHalfBoundingBox[2]; int mCurrentAlgorithm; unsigned int mFrameId; unsigned int mVisibilityThreshold; SceneManager *mSceneManager; RenderSystem *mRenderSystem; int mCurrentTestIdx; int mQueryMode; //--- statistics unsigned int mNumSceneNodes; unsigned int mNumTraversedNodes; unsigned int mNumQueryCulledNodes; unsigned int mNumFrustumCulledNodes; unsigned int mNumRenderedGeometry; }; } #endif // OCCLUSIONCULLINGSCENEMANAGER_H