OcclusionQueryNode
Go to the documentation of this file.
//
// 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 <osg/Export>
#include <osg/CopyOp>
#include <osg/Group>
#include <osg/Geometry>
namespace osg {
// Create and return a StateSet appropriate for performing an occlusion
// query test (disable lighting, texture mapping, etc). Probably some
// room for improvement here. Could disable shaders, for example.
osg::StateSet* initOQState();
// Create and return a StateSet for rendering a debug representation of query geometry.
osg::StateSet* initOQDebugState();
// TestResult -- stores (per context) results of an occlusion query
// test performed by QueryGeometry. An OcclusionQueryNode has a
// Geode owning a single QueryGeometry that
// draws the occlusion query geometry. QueryGeometry keeps a
// TestResult per context to store the result/status of each query.
// Accessed during the cull and draw traversals.
class TestResult : public osg::Referenced
{
public:
TestResult() : _init( false ), _id( 0 ), _contextID( 0 ), _active( false ), _numPixels( 0 ) {setThreadSafeRefUnref(true);}
~TestResult() {}
bool _init;
// Query ID for this context.
GLuint _id;
// Context ID owning this query ID.
unsigned int _contextID;
// Set to true when a query gets issued and set to
// false when the result is retrieved.
mutable bool _active;
// Result of last query.
GLint _numPixels;
};
// QueryGeometry -- A Drawable that performs an occlusion query,
// using its geometric data as the query geometry.
class OSG_EXPORT QueryGeometry : public osg::Geometry
{
public:
QueryGeometry( const std::string& oqnName=std::string("") );
~QueryGeometry();
void reset();
// TBD implement copy constructor
virtual void drawImplementation( osg::RenderInfo& renderInfo ) const;
struct QueryResult
{
QueryResult() : valid(false), numPixels(0) {}
QueryResult(bool v, unsigned int p) : valid(v), numPixels(p) {}
bool valid;
unsigned int numPixels;
};
QueryResult getQueryResult( const osg::Camera* cam ) const;
unsigned int getNumPixels( const osg::Camera* cam ) const;
virtual void releaseGLObjects( osg::State* state = 0 ) const;
static void deleteQueryObject( unsigned int contextID, GLuint handle );
static void flushDeletedQueryObjects( unsigned int contextID, double currentTime, double& availableTime );
static void discardDeletedQueryObjects( unsigned int contextID );
protected:
typedef std::map< const osg::Camera*, osg::ref_ptr<osg::TestResult> > ResultMap;
mutable ResultMap _results;
mutable OpenThreads::Mutex _mapMutex;
// Needed for debug only
std::string _oqnName;
};
// 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( unsigned int frames ) { _queryFrameCount = frames; }
unsigned int getQueryFrameCount() const { return _queryFrameCount; }
// Resets the queries. The next frame will issue a new query.
// This is useful for big view changes, if it shouldn't be waited for
// '_queryFrameCount' till the frame contents change.
void resetQueries();
// 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 QueryGeometry object used for the occlusion query.
// By default an axis aligned box is used as the query geometry.
// Resetting to the default query geometry is done by setting it to 0.
// Returns 0 if no QueryGeometry is created.
void setQueryGeometry( osg::QueryGeometry* geom );
const osg::QueryGeometry* getQueryGeometry() 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.
virtual 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:
enum QueryGeometryState {
INVALID,
VALID,
USER_DEFINED
};
virtual ~OcclusionQueryNode();
virtual void createSupportNodes();
bool isQueryGeometryValid() const { return _queryGeometryState != INVALID; }
void setQueryGeometryInternal( osg::QueryGeometry* queryGeom,
osg::Geometry* debugQueryGeom,
QueryGeometryState state );
void updateDefaultQueryGeometry();
osg::ref_ptr< osg::Geode > _queryGeode;
osg::ref_ptr< osg::Geode > _debugGeode;
bool _enabled;
mutable QueryGeometryState _queryGeometryState;
// Tracks the last frame number that we performed a query.
// User can set how many times (See setQueryFrameCount).
typedef std::map< const osg::Camera*, unsigned int > FrameCountMap;
FrameCountMap _frameCountMap;
mutable OpenThreads::Mutex _frameCountMutex;
// For statistics gathering
bool _passed;
// User-settable variables
unsigned int _visThreshold;
unsigned int _queryFrameCount;
bool _debugBB;
// Required to ensure that computeBound() is thread-safe.
mutable OpenThreads::Mutex _computeBoundMutex;
};
}
#endif
CopyOp
Geometry
Group
OpenThreads::Mutex
This class provides an object-oriented thread mutex interface.
Definition Mutex:31
osg::Camera
Definition Camera:45
osg::CopyOp
Definition CopyOp:41
osg::CopyOp::SHALLOW_COPY
@ SHALLOW_COPY
Definition CopyOp:47
osg::Geometry
Definition Geometry:31
osg::Group
Definition Group:29
osg::NodeVisitor
Definition NodeVisitor:82
osg::OcclusionQueryNode::QueryGeometryState
QueryGeometryState
Definition OcclusionQueryNode:195
osg::OcclusionQueryNode::INVALID
@ INVALID
Definition OcclusionQueryNode:196
osg::OcclusionQueryNode::USER_DEFINED
@ USER_DEFINED
Definition OcclusionQueryNode:198
osg::OcclusionQueryNode::VALID
@ VALID
Definition OcclusionQueryNode:197
osg::OcclusionQueryNode::discardDeletedQueryObjects
static void discardDeletedQueryObjects(unsigned int contextID)
osg::OcclusionQueryNode::traverseQuery
void traverseQuery(const osg::Camera *camera, osg::NodeVisitor &nv)
osg::OcclusionQueryNode::getDebugDisplay
bool getDebugDisplay() const
osg::OcclusionQueryNode::setQueryGeometry
void setQueryGeometry(osg::QueryGeometry *geom)
osg::OcclusionQueryNode::_queryGeode
osg::ref_ptr< osg::Geode > _queryGeode
Definition OcclusionQueryNode:213
osg::OcclusionQueryNode::setDebugStateSet
void setDebugStateSet(osg::StateSet *ss)
osg::OcclusionQueryNode::_debugBB
bool _debugBB
Definition OcclusionQueryNode:232
osg::OcclusionQueryNode::getQueryStateSet
const osg::StateSet * getQueryStateSet() const
osg::OcclusionQueryNode::setQueriesEnabled
void setQueriesEnabled(bool enable=true)
osg::OcclusionQueryNode::getDebugStateSet
osg::StateSet * getDebugStateSet()
osg::OcclusionQueryNode::getPassed
virtual bool getPassed(const osg::Camera *camera, osg::NodeVisitor &nv)
osg::OcclusionQueryNode::_computeBoundMutex
OpenThreads::Mutex _computeBoundMutex
Definition OcclusionQueryNode:236
osg::OcclusionQueryNode::_visThreshold
unsigned int _visThreshold
Definition OcclusionQueryNode:230
osg::OcclusionQueryNode::setQueryStateSet
void setQueryStateSet(osg::StateSet *ss)
osg::OcclusionQueryNode::getDebugStateSet
const osg::StateSet * getDebugStateSet() const
osg::OcclusionQueryNode::_passed
bool _passed
Definition OcclusionQueryNode:227
osg::OcclusionQueryNode::_debugGeode
osg::ref_ptr< osg::Geode > _debugGeode
Definition OcclusionQueryNode:214
osg::OcclusionQueryNode::getQueryStateSet
osg::StateSet * getQueryStateSet()
osg::OcclusionQueryNode::getQueriesEnabled
bool getQueriesEnabled() const
Definition OcclusionQueryNode:127
osg::OcclusionQueryNode::_enabled
bool _enabled
Definition OcclusionQueryNode:216
osg::OcclusionQueryNode::_queryGeometryState
QueryGeometryState _queryGeometryState
Definition OcclusionQueryNode:218
osg::OcclusionQueryNode::_frameCountMap
FrameCountMap _frameCountMap
Definition OcclusionQueryNode:223
osg::OcclusionQueryNode::META_Node
META_Node(osg, OcclusionQueryNode)
osg::OcclusionQueryNode::setDebugDisplay
void setDebugDisplay(bool enable)
osg::OcclusionQueryNode::resetQueries
void resetQueries()
osg::OcclusionQueryNode::OcclusionQueryNode
OcclusionQueryNode(const OcclusionQueryNode &oqn, const osg::CopyOp &copyop=osg::CopyOp::SHALLOW_COPY)
osg::OcclusionQueryNode::getPassed
bool getPassed() const
osg::OcclusionQueryNode::setQueryGeometryInternal
void setQueryGeometryInternal(osg::QueryGeometry *queryGeom, osg::Geometry *debugQueryGeom, QueryGeometryState state)
osg::OcclusionQueryNode::flushDeletedQueryObjects
static void flushDeletedQueryObjects(unsigned int contextID, double currentTime, double &availableTime)
osg::OcclusionQueryNode::_queryFrameCount
unsigned int _queryFrameCount
Definition OcclusionQueryNode:231
osg::OcclusionQueryNode::OcclusionQueryNode
OcclusionQueryNode()
osg::OcclusionQueryNode::computeBound
virtual osg::BoundingSphere computeBound() const
osg::OcclusionQueryNode::traverseDebug
void traverseDebug(osg::NodeVisitor &nv)
osg::OcclusionQueryNode::isQueryGeometryValid
bool isQueryGeometryValid() const
Definition OcclusionQueryNode:205
osg::OcclusionQueryNode::setVisibilityThreshold
void setVisibilityThreshold(unsigned int pixels)
Definition OcclusionQueryNode:133
osg::OcclusionQueryNode::releaseGLObjects
virtual void releaseGLObjects(osg::State *state=0) const
osg::OcclusionQueryNode::setQueryFrameCount
void setQueryFrameCount(unsigned int frames)
Definition OcclusionQueryNode:137
osg::OcclusionQueryNode::createSupportNodes
virtual void createSupportNodes()
osg::OcclusionQueryNode::~OcclusionQueryNode
virtual ~OcclusionQueryNode()
osg::OcclusionQueryNode::getVisibilityThreshold
unsigned int getVisibilityThreshold() const
Definition OcclusionQueryNode:134
osg::OcclusionQueryNode::FrameCountMap
std::map< const osg::Camera *, unsigned int > FrameCountMap
Definition OcclusionQueryNode:222
osg::OcclusionQueryNode::getQueryGeometry
const osg::QueryGeometry * getQueryGeometry() const
osg::OcclusionQueryNode::_frameCountMutex
OpenThreads::Mutex _frameCountMutex
Definition OcclusionQueryNode:224
osg::OcclusionQueryNode::getQueryFrameCount
unsigned int getQueryFrameCount() const
Definition OcclusionQueryNode:138
osg::OcclusionQueryNode::updateDefaultQueryGeometry
void updateDefaultQueryGeometry()
osg::QueryGeometry
Definition OcclusionQueryNode:64
osg::QueryGeometry::~QueryGeometry
~QueryGeometry()
osg::QueryGeometry::QueryGeometry
QueryGeometry(const std::string &oqnName=std::string(""))
osg::QueryGeometry::_results
ResultMap _results
Definition OcclusionQueryNode:97
osg::QueryGeometry::ResultMap
std::map< const osg::Camera *, osg::ref_ptr< osg::TestResult > > ResultMap
Definition OcclusionQueryNode:96
osg::QueryGeometry::_mapMutex
OpenThreads::Mutex _mapMutex
Definition OcclusionQueryNode:98
osg::QueryGeometry::releaseGLObjects
virtual void releaseGLObjects(osg::State *state=0) const
osg::QueryGeometry::reset
void reset()
osg::QueryGeometry::flushDeletedQueryObjects
static void flushDeletedQueryObjects(unsigned int contextID, double currentTime, double &availableTime)
osg::QueryGeometry::getNumPixels
unsigned int getNumPixels(const osg::Camera *cam) const
osg::QueryGeometry::getQueryResult
QueryResult getQueryResult(const osg::Camera *cam) const
osg::QueryGeometry::_oqnName
std::string _oqnName
Definition OcclusionQueryNode:101
osg::QueryGeometry::discardDeletedQueryObjects
static void discardDeletedQueryObjects(unsigned int contextID)
osg::QueryGeometry::deleteQueryObject
static void deleteQueryObject(unsigned int contextID, GLuint handle)
osg::QueryGeometry::drawImplementation
virtual void drawImplementation(osg::RenderInfo &renderInfo) const
osg::Referenced
Definition Referenced:44
osg::Referenced::setThreadSafeRefUnref
virtual void setThreadSafeRefUnref(bool)
Definition Referenced:59
osg::RenderInfo
Definition RenderInfo:28
osg::StateSet
Definition StateSet:46
osg::State
Definition State:80
osg::TestResult::_init
bool _init
Definition OcclusionQueryNode:46
osg::TestResult::TestResult
TestResult()
Definition OcclusionQueryNode:43
osg::TestResult::~TestResult
~TestResult()
Definition OcclusionQueryNode:44
osg::TestResult::_active
bool _active
Definition OcclusionQueryNode:55
osg::TestResult::_contextID
unsigned int _contextID
Definition OcclusionQueryNode:51
osg::TestResult::_id
GLuint _id
Definition OcclusionQueryNode:49
osg::TestResult::_numPixels
GLint _numPixels
Definition OcclusionQueryNode:58
osg::ref_ptr< osg::Geode >
osg
Definition AlphaFunc:19
osg::initOQDebugState
osg::StateSet * initOQDebugState()
osg::BoundingSphere
BoundingSphered BoundingSphere
Definition BoundingSphere:314
osg::initOQState
osg::StateSet * initOQState()
Export
OSG_EXPORT
#define OSG_EXPORT
Definition osg/Export:39
osg::QueryGeometry::QueryResult
Definition OcclusionQueryNode:76
osg::QueryGeometry::QueryResult::numPixels
unsigned int numPixels
Definition OcclusionQueryNode:81
osg::QueryGeometry::QueryResult::QueryResult
QueryResult()
Definition OcclusionQueryNode:77
osg::QueryGeometry::QueryResult::valid
bool valid
Definition OcclusionQueryNode:80
osg::QueryGeometry::QueryResult::QueryResult
QueryResult(bool v, unsigned int p)
Definition OcclusionQueryNode:78