// // Copyright (C) 2007 Skew Matrix Software LLC (http://www.skew-matrix.com) // // This library is open source and may be redistributed and/or modified under // the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or // (at your option) any later version. The full license is in LICENSE file // included with this distribution, and on the openscenegraph.org website. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // OpenSceneGraph Public License for more details. // #ifndef OSG_OCCLUSION_QUERY_NODE #define OSG_OCCLUSION_QUERY_NODE 1 #include #include #include namespace osg { // This Node performs occlusion query testing on its children. // You can use it directly to occlusion query test a portion // of your scene graph, or you can use it implicitly with an // OcclusionQueryRoot, which places OcclusionQueryNodes where // needed and acts as a master control. class OSG_EXPORT OcclusionQueryNode : public osg::Group { public: OcclusionQueryNode(); // Copy constructor using CopyOp to manage deep vs shallow copy. OcclusionQueryNode( const OcclusionQueryNode& oqn, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY ); META_Node( osg, OcclusionQueryNode ); virtual osg::BoundingSphere computeBound() const; virtual void releaseGLObjects( osg::State* state = 0 ) const; // When disabled, OQN doesn't perform occlusion queries, and simply // renders its children. void setQueriesEnabled( bool enable=true ); bool getQueriesEnabled() const { return _enabled; } // Sets/gets the visibility threshold. If the test indicates that // the number of visible pixels is less than the specified // threshold, don't draw the actual geometry. void setVisibilityThreshold( unsigned int pixels ) { _visThreshold = pixels; } unsigned int getVisibilityThreshold() const { return _visThreshold; } // Specifies how many frames to wait before issuing another query. void setQueryFrameCount( int frames ) { _queryFrameCount = frames; } int getQueryFrameCount() const { return _queryFrameCount; } // Indicate whether or not the bounding box used in the occlusion query test // should be rendered. Handy for debugging and development. // Should only be called outside of cull/draw. No thread issues. void setDebugDisplay( bool enable ); bool getDebugDisplay() const; // Set and get the StateSet used by the OcclusionQueryNode // when rendering the query geometry. OQN creates its own by // default, but if you use many OQNs you might want to use // this method to set all OQNs to use the same StateSet // for more efficient processing. void setQueryStateSet( osg::StateSet* ss ); osg::StateSet* getQueryStateSet(); const osg::StateSet* getQueryStateSet() const; // Set and get the StateSet used by the OcclusionQueryNode // when rendering the debug query geometry (see setDebugDisplay). void setDebugStateSet( osg::StateSet* ss ); osg::StateSet* getDebugStateSet(); const osg::StateSet* getDebugStateSet() const; // For statistics gathering, e.g., by a NodeVisitor. bool getPassed() const; // These methods are public so that osgUtil::CullVisitor can access them. // Not intended for application use. bool getPassed( const osg::Camera* camera, osg::NodeVisitor& nv ); void traverseQuery( const osg::Camera* camera, osg::NodeVisitor& nv ); void traverseDebug( osg::NodeVisitor& nv ); // Delete unused query IDs for this contextID. static void flushDeletedQueryObjects( unsigned int contextID, double currentTime, double& availableTime ); // discard all the cached query objects which need to be deleted // in the OpenGL context related to contextID. // Note, unlike flush no OpenGL calls are made, instead the handles are all removed. // this call is useful for when an OpenGL context has been destroyed. static void discardDeletedQueryObjects( unsigned int contextID ); protected: virtual ~OcclusionQueryNode(); void createSupportNodes(); osg::ref_ptr< osg::Geode > _queryGeode; osg::ref_ptr< osg::Geode > _debugGeode; bool _enabled; // Tracks the last frame number that we performed a query. // User can set how many times (See setQueryFrameCount). typedef std::map< const osg::Camera*, int > FrameCountMap; FrameCountMap _frameCountMap; mutable OpenThreads::Mutex _frameCountMutex; // For statistics gathering bool _passed; // User-settable variables unsigned int _visThreshold; int _queryFrameCount; bool _debugBB; // Required to ensure that computeBound() is thread-safe. mutable OpenThreads::Mutex _computeBoundMutex; }; } #endif