#ifndef _OcclusionCullingSceneManager_H__ #define _OcclusionCullingSceneManager_H__ #include "OgreSceneNode.h" #include "OgreSceneManager.h" #include "OgrePrerequisites.h" #include "OgreSolidHalfBoundingBox.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 OcclusionCullingSceneManager : public SceneManager { public: OcclusionCullingSceneManager(); ~OcclusionCullingSceneManager(); 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 */ void _renderVisibleObjects(void); void _findVisibleObjects(Camera* cam, bool onlyShadowCasters); void _updateSceneGraph(Camera* cam); protected: enum {MODE_QUERY, MODE_RENDER}; int isLeaf(SceneNode *node); int countSceneNodes(SceneNode *node); void renderZPass(); void traverseNode(SceneNode *node); /** Renders current node */ void render(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(); /** Renders the scene with the hierarchical stop and wait algorithm. */ void renderStopAndWait(); /** Renders the scene with the coherent hierarchical algorithm and the query queye. */ void renderCoherentWithQueue(); /** 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 node which bounding box is 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); /** sets the type of the algorithm @param algorithm type */ void setAlgorithmType(int type); int getAlgorithmType(); // we use a priority queue rather than a renderstack PriorityQueue *mDistanceQueue; unsigned int mFrameId; unsigned int mVisibilityThreshold; unsigned int mNumSceneNodes; int mCurrentTestIdx; int mQueryMode; std::vector mOcclusionQueries; // two halfes of a aabb SolidHalfBoundingBox *mHalfBoundingBox[2]; int mAlgorithmType; }; } #endif // OCCLUSIONCULLINGSCENEMANAGER_H