#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: /** Construction taking the current scene manager and the current rendersystem as argument @param sm current scene manager @param rsys current render system */ OcclusionCullingSceneTraverser(SceneManager *sm, RenderSystem *rsys); ~OcclusionCullingSceneTraverser(); enum {RENDER_CULL_FRUSTUM, RENDER_STOP_AND_WAIT, RENDER_COHERENT, NUM_RENDERMODES}; /** Renders the scene with the specified algorithm @comment The algorithm type can be set with the parameter "Algorithm" and setOption. 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 @param cam current camera @param root root of hierarchy */ void renderScene( Camera *cam, SceneNode *root ); /** Sets the given option for the scene traverser. @remarks Options are: "Algorithm", int *; */ bool setOption( const String &, const void * ); /** Gets the given option for the scene traverser. @remarks See setOption */ bool getOption( const String &, void * ); bool getOptionKeys( StringVector &refKeys ); /** Sets pointer to the current scene manager. @param the scene manager */ void setSceneManager( SceneManager *sm ); /** Sets pointer to the current render system @param the rendersystem */ void setRenderSystem( RenderSystem *rsys ); /** Doing some necessary preprocessing. @comment e.g., initialises occlusion queries */ void preprocess( void ); /** Sets the current number of scene nodes in the scene. @param num number of scene nodes */ void setNumSceneNodes(int num ); protected: /** query mode (= without color) or RENDER_MODE */ 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