OpenSceneGraph/include/osg/OcclusionQueryNode
Robert Osfield d50eacd07e From Paul Martz, "The changes are very similar to Magne's, except they now take the near plane into account. The changes are:
* Change OcclusionQueryNode::getPassed to take a NodeVisitor rather than the distance from BS center to the eye point. Change where CullVisitor calls this method to use the new parameters.
 * getPassed now exits early and returns true to avoid blinking / blink-in of geometry for the first frame or for out-of-range LOD children coming back into view.
 * getPassed now considers the distance from the near plane to the bounding sphere (rather than eye point to bounding sphere) when determining if the viewer is "inside" the bounding sphere or not."
2010-02-26 10:13:28 +00:00

138 lines
4.9 KiB
Plaintext

//
// 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>
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