Further work on Occlusion Culling. Most of work is complete, just debugging
required now.
This commit is contained in:
parent
8dcb26967c
commit
0ebe473eb5
@ -235,14 +235,15 @@ ifeq ($(OS),Darwin)
|
||||
LIB_EXT = dylib
|
||||
QUICKTIME_LIB = -framework QuickTime
|
||||
TIFF_LIB = -ltiff
|
||||
SRC_DIRS = osg osgGA osgUtil osgDB osgGLUT osgParticle \
|
||||
SRC_DIRS = osg osgUtil osgDB osgGA osgGLUT osgParticle \
|
||||
osgPlugins Demos
|
||||
PLUGIN_DIRS = osg rgb lib3ds flt obj lwo txp bmp pic tga \
|
||||
osgtgz tgz zip
|
||||
DEMOS_DIRS = hangglide osgbillboard osgcluster osgconv osgcopy \
|
||||
osgcube osgimpostor osgreflect osgscribe \
|
||||
osgstereoimage osgtexture osgviews osgversion \
|
||||
sgv osgparticle
|
||||
osgcube osgcallback osgclip osgimpostor osgoccluder \
|
||||
osgreflect osgscribe osgstereoimage osgtexture \
|
||||
osgviews osgversion sgv osgparticle
|
||||
|
||||
endif
|
||||
|
||||
#### Cygwin/Mingw specific definitions
|
||||
|
@ -30,10 +30,9 @@ class SG_EXPORT CollectOccludersVisitor : public osg::NodeVisitor, public osg::C
|
||||
virtual void apply(osg::LOD& node);
|
||||
virtual void apply(osg::OccluderNode& node);
|
||||
|
||||
typedef std::vector<ShadowVolumeOccluder> OccluderList;
|
||||
|
||||
OccluderList& getOccluderList() { return _occluderList; }
|
||||
const OccluderList& getOccluderList() const { return _occluderList; }
|
||||
void setCollectedOcculderList(const ShadowVolumeOccluderList& svol) { _occluderList = svol; }
|
||||
ShadowVolumeOccluderList& getCollectedOccluderList() { return _occluderList; }
|
||||
const ShadowVolumeOccluderList& getCollectedOccluderList() const { return _occluderList; }
|
||||
|
||||
|
||||
protected:
|
||||
@ -44,7 +43,7 @@ class SG_EXPORT CollectOccludersVisitor : public osg::NodeVisitor, public osg::C
|
||||
/** prevent unwanted copy operator.*/
|
||||
CollectOccludersVisitor& operator = (const CollectOccludersVisitor&) { return *this; }
|
||||
|
||||
OccluderList _occluderList;
|
||||
ShadowVolumeOccluderList _collectedOccluderList;
|
||||
|
||||
};
|
||||
|
||||
|
@ -44,6 +44,10 @@ class SG_EXPORT CullStack
|
||||
CullingMode getCullingMode() const { return _cullingMode; }
|
||||
|
||||
void reset();
|
||||
|
||||
void setOccluderList(const ShadowVolumeOccluderList& svol) { _occluderList = svol; }
|
||||
ShadowVolumeOccluderList& getOccluderList() { return _occluderList; }
|
||||
const ShadowVolumeOccluderList& getOccluderList() const { return _occluderList; }
|
||||
|
||||
void pushViewport(osg::Viewport* viewport);
|
||||
void popViewport();
|
||||
@ -110,6 +114,17 @@ class SG_EXPORT CullStack
|
||||
}
|
||||
|
||||
|
||||
typedef fast_back_stack<ref_ptr<CullingSet> > CullingStack;
|
||||
|
||||
CullingStack& getClipSpaceCullingStack() { return _clipspaceCullingStack; }
|
||||
|
||||
CullingStack& getProjectionCullingStack() { return _projectionCullingStack; }
|
||||
|
||||
CullingStack& getModelViewCullingStack() { return _modelviewCullingStack; }
|
||||
|
||||
CullingSet& getCurrentCullingSet() { return *_modelviewCullingStack.back(); }
|
||||
|
||||
|
||||
inline osg::Viewport* getViewport();
|
||||
inline osg::Matrix& getModelViewMatrix();
|
||||
inline osg::Matrix& getProjectionMatrix();
|
||||
@ -139,6 +154,9 @@ class SG_EXPORT CullStack
|
||||
float _LODBias;
|
||||
float _smallFeatureCullingPixelSize;
|
||||
|
||||
// base set of shadow volume occluder to use in culling.
|
||||
ShadowVolumeOccluderList _occluderList;
|
||||
|
||||
typedef fast_back_stack< ref_ptr<Matrix> > MatrixStack;
|
||||
|
||||
MatrixStack _projectionStack;
|
||||
@ -152,7 +170,6 @@ class SG_EXPORT CullStack
|
||||
typedef fast_back_stack<Vec3> EyePointStack;
|
||||
EyePointStack _eyePointStack;
|
||||
|
||||
typedef fast_back_stack<ref_ptr<CullingSet> > CullingStack;
|
||||
CullingStack _clipspaceCullingStack;
|
||||
CullingStack _projectionCullingStack;
|
||||
CullingStack _modelviewCullingStack;
|
||||
|
@ -77,22 +77,7 @@ class SG_EXPORT CullingSet : public Referenced
|
||||
/** Compute the pixel of an bounding sphere.*/
|
||||
float pixelSize(const BoundingSphere& bs) const { return bs.radius()/(bs.center()*_pixelSizeVector); }
|
||||
|
||||
inline void disableOccluder(NodePath& nodePath)
|
||||
{
|
||||
for(OccluderList::iterator itr=_occluderList.begin();
|
||||
itr!=_occluderList.end();
|
||||
++itr)
|
||||
{
|
||||
if (itr->getNodePath()==nodePath)
|
||||
{
|
||||
// we have trapped for the case an occlude potentially occluding itself,
|
||||
// to prevent this we disable the results mask so that no subsequnt
|
||||
// when the next pushCurrentMask calls happens this occluder is switched off.
|
||||
itr->disableResultMasks();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void disableOccluder(NodePath& nodePath);
|
||||
|
||||
inline bool isCulled(const std::vector<Vec3>& vertices)
|
||||
{
|
||||
|
@ -50,6 +50,13 @@ class SG_EXPORT Plane
|
||||
_fv.set(norm[0],norm[1],norm[2],-(v1*norm));
|
||||
calculateUpperLowerBBCorners();
|
||||
}
|
||||
|
||||
/** flip/reverse the orientation of the plane.*/
|
||||
inline void flip()
|
||||
{
|
||||
_fv = -_fv;
|
||||
calculateUpperLowerBBCorners();
|
||||
}
|
||||
|
||||
|
||||
inline void makeUnitLength()
|
||||
|
@ -70,6 +70,18 @@ class SG_EXPORT Polytope
|
||||
|
||||
inline void add(const osg::Plane& pl) { _planeList.push_back(pl); setupMask(); }
|
||||
|
||||
/** flip/reverse the orientation of all the planes.*/
|
||||
inline void flip()
|
||||
{
|
||||
for(PlaneList::iterator itr=_planeList.begin();
|
||||
itr!=_planeList.end();
|
||||
++itr)
|
||||
{
|
||||
itr->flip();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline PlaneList& getPlaneList() { return _planeList; }
|
||||
|
||||
inline const PlaneList& getPlaneList() const { return _planeList; }
|
||||
|
@ -12,6 +12,8 @@
|
||||
|
||||
namespace osg {
|
||||
|
||||
class CullStack;
|
||||
|
||||
/** ShadowVolumeOccluder is a helper class for implementating shadow occlusion culling. */
|
||||
class SG_EXPORT ShadowVolumeOccluder
|
||||
{
|
||||
@ -21,25 +23,35 @@ class SG_EXPORT ShadowVolumeOccluder
|
||||
|
||||
typedef std::vector<Polytope> HoleList;
|
||||
|
||||
ShadowVolumeOccluder(const ShadowVolumeOccluder& soc):
|
||||
_quality(soc._quality),
|
||||
_nodePath(soc._nodePath),
|
||||
_occluderVolume(soc._occluderVolume),
|
||||
_holeList(soc._holeList) {}
|
||||
ShadowVolumeOccluder(const ShadowVolumeOccluder& svo):
|
||||
_volume(svo._volume),
|
||||
_nodePath(svo._nodePath),
|
||||
_projectionMatrix(svo._projectionMatrix),
|
||||
_occluderVolume(svo._occluderVolume),
|
||||
_holeList(svo._holeList) {}
|
||||
|
||||
ShadowVolumeOccluder():
|
||||
_volume(0.0f) {}
|
||||
|
||||
ShadowVolumeOccluder(const NodePath& nodePath,const ConvexPlanerOccluder& occluder,const Matrix& MV,const Matrix& P)
|
||||
{
|
||||
computeOccluder(nodePath,occluder,MV,P);
|
||||
}
|
||||
|
||||
/** compute the shadow volume occluder. */
|
||||
void computeOccluder(const NodePath& nodePath,const ConvexPlanerOccluder& occluder,const Matrix& MV,const Matrix& P);
|
||||
bool computeOccluder(const NodePath& nodePath,const ConvexPlanerOccluder& occluder,CullStack& cullStack);
|
||||
|
||||
|
||||
inline void disableResultMasks();
|
||||
|
||||
inline void pushCurrentMask();
|
||||
inline void popCurrentMask();
|
||||
|
||||
|
||||
/** return true if the matrix passed in matches the projection matrix that this ShaowVolumeOccluder is
|
||||
* associated with.*/
|
||||
bool matchProjectionMatrix(const osg::Matrix& matrix) const
|
||||
{
|
||||
if (_projectionMatrix.valid()) return matrix==*_projectionMatrix;
|
||||
else return false;
|
||||
}
|
||||
|
||||
|
||||
/** Set the NodePath which describes the which node in the scene graph
|
||||
* that this occluder was attached to.*/
|
||||
@ -47,7 +59,9 @@ class SG_EXPORT ShadowVolumeOccluder
|
||||
inline NodePath& getNodePath() { return _nodePath; }
|
||||
inline const NodePath& getNodePath() const { return _nodePath; }
|
||||
|
||||
float quality() { return _quality; }
|
||||
float volume() { return _volume; }
|
||||
|
||||
|
||||
|
||||
/** return true if the specified vertex list is contaned entirely
|
||||
* within this shadow occluder volume.*/
|
||||
@ -75,12 +89,18 @@ class SG_EXPORT ShadowVolumeOccluder
|
||||
|
||||
protected:
|
||||
|
||||
float _quality;
|
||||
NodePath _nodePath;
|
||||
Polytope _occluderVolume;
|
||||
HoleList _holeList;
|
||||
float _volume;
|
||||
NodePath _nodePath;
|
||||
ref_ptr<const Matrix> _projectionMatrix;
|
||||
Polytope _occluderVolume;
|
||||
HoleList _holeList;
|
||||
};
|
||||
|
||||
|
||||
/** A list of ShadowVolumeOccluder, used by CollectOccluderVisitor and CullVistor's.*/
|
||||
typedef std::vector<ShadowVolumeOccluder> ShadowVolumeOccluderList;
|
||||
|
||||
|
||||
inline void ShadowVolumeOccluder::disableResultMasks()
|
||||
{
|
||||
_occluderVolume.setResultMask(0);
|
||||
|
@ -103,18 +103,26 @@ void CollectOccludersVisitor::apply(osg::OccluderNode& node)
|
||||
|
||||
if (isCulled(node)) return;
|
||||
|
||||
std::cout<<"CollectOccludersVisitor:: We have found an Occlusion node in frustum"<<&node<<std::endl;
|
||||
// std::cout<<"CollectOccludersVisitor:: We have found an Occlusion node in frustum"<<&node<<std::endl;
|
||||
|
||||
// push the culling mode.
|
||||
pushCurrentMask();
|
||||
|
||||
|
||||
if (node.getOccluder()&& !isCulled(node.getOccluder()->getOccluder().getVertexList()))
|
||||
if (node.getOccluder())
|
||||
{
|
||||
|
||||
// need to test occluder against view frustum.
|
||||
std::cout << " adding in Occluder"<<std::endl;
|
||||
_occluderList.push_back(ShadowVolumeOccluder(_nodePath, *node.getOccluder(), getModelViewMatrix(),getProjectionMatrix()));
|
||||
// computeOccluder will check if the occluder is the view frustum,
|
||||
// if it ins't then the it will return false, when in it will
|
||||
// clip the occluder's polygons in clip space, then create occluder
|
||||
// planes, all with their normals facing inward towards the volume,
|
||||
// and then transform them back into projection space.
|
||||
ShadowVolumeOccluder svo;
|
||||
if (svo.computeOccluder(_nodePath, *node.getOccluder(), *this))
|
||||
{
|
||||
// need to test occluder against view frustum.
|
||||
// std::cout << " adding in Occluder"<<std::endl;
|
||||
_occluderList.push_back(svo);
|
||||
}
|
||||
}
|
||||
|
||||
traverse(node);
|
||||
|
@ -109,13 +109,28 @@ void CullStack::pushProjectionMatrix(Matrix* matrix)
|
||||
_projectionStack.push_back(matrix);
|
||||
|
||||
osg::CullingSet* cullingSet = osgNew osg::CullingSet();
|
||||
// set up view frustum.
|
||||
cullingSet->getFrustum().setToUnitFrustumWithoutNearFar();
|
||||
cullingSet->getFrustum().transformProvidingInverse(*matrix);
|
||||
|
||||
// set the small feature culling.
|
||||
cullingSet->setSmallFeatureCullingPixelSize(_smallFeatureCullingPixelSize);
|
||||
|
||||
_projectionCullingStack.push_back(cullingSet);
|
||||
// set up the relevant occluders which a related to this projection.
|
||||
for(ShadowVolumeOccluderList::iterator itr=_occluderList.begin();
|
||||
itr!=_occluderList.end();
|
||||
++itr)
|
||||
{
|
||||
//std::cout << " ** testing occluder"<<std::endl;
|
||||
if (itr->matchProjectionMatrix(*matrix))
|
||||
{
|
||||
//std::cout << " ** activating occluder"<<std::endl;
|
||||
cullingSet->addOccluder(*itr);
|
||||
}
|
||||
}
|
||||
|
||||
//_projectionCullingStack.push_back(osgNew osg::CullingSet(*_clipspaceCullingStack.back(),*matrix));
|
||||
|
||||
_projectionCullingStack.push_back(cullingSet);
|
||||
|
||||
|
||||
pushCullingSet();
|
||||
|
@ -12,3 +12,21 @@ CullingSet::CullingSet()
|
||||
CullingSet::~CullingSet()
|
||||
{
|
||||
}
|
||||
|
||||
void CullingSet::disableOccluder(NodePath& nodePath)
|
||||
{
|
||||
//std::cout<<" trying to disable occluder"<<std::endl;
|
||||
for(OccluderList::iterator itr=_occluderList.begin();
|
||||
itr!=_occluderList.end();
|
||||
++itr)
|
||||
{
|
||||
if (itr->getNodePath()==nodePath)
|
||||
{
|
||||
//std::cout<<" ++ disabling occluder"<<std::endl;
|
||||
// we have trapped for the case an occlude potentially occluding itself,
|
||||
// to prevent this we disable the results mask so that no subsequnt
|
||||
// when the next pushCurrentMask calls happens this occluder is switched off.
|
||||
itr->disableResultMasks();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,161 @@
|
||||
#include <osg/ShadowVolumeOccluder>
|
||||
#include <osg/CullStack>
|
||||
|
||||
using namespace osg;
|
||||
|
||||
|
||||
void ShadowVolumeOccluder::computeOccluder(const NodePath& nodePath,const ConvexPlanerOccluder& occluder,const Matrix& MV,const Matrix& P)
|
||||
|
||||
typedef std::pair<bool,Vec3> Point; // bool=true signifies a newly created point, false indicates original point.
|
||||
typedef std::vector<Point> PointList;
|
||||
typedef std::vector<Vec3> VertexList;
|
||||
|
||||
|
||||
// convert a vector for Vec3 into a vector of Point's.
|
||||
void convert(const VertexList& in,PointList& out)
|
||||
{
|
||||
std::cout<<" Computing Occluder"<<std::endl;
|
||||
out.reserve(in.size());
|
||||
for(VertexList::const_iterator itr=in.begin();
|
||||
itr!=in.end();
|
||||
++itr)
|
||||
{
|
||||
out.push_back(Point(false,*itr));
|
||||
}
|
||||
}
|
||||
|
||||
// clip the convex hull 'in' to plane to generate a clipped convex hull 'out'
|
||||
// return true if points remain after clipping.
|
||||
unsigned int clip(const Plane& plane,const PointList& in, PointList& out)
|
||||
{
|
||||
std::vector<float> distance;
|
||||
distance.reserve(in.size());
|
||||
for(PointList::const_iterator itr=in.begin();
|
||||
itr!=in.end();
|
||||
++itr)
|
||||
{
|
||||
distance.push_back(plane.distance(itr->second));
|
||||
}
|
||||
|
||||
out.clear();
|
||||
|
||||
for(unsigned int i=0;i<in.size();++i)
|
||||
{
|
||||
unsigned int i_1 = (i+1)%in.size(); // do the mod to wrap the index round back to the start.
|
||||
|
||||
if (distance[i]>=0.0f)
|
||||
{
|
||||
out.push_back(in[i]);
|
||||
|
||||
if (distance[i_1]<0.0f)
|
||||
{
|
||||
float r = distance[i_1]/(distance[i_1]-distance[i]);
|
||||
out.push_back(Point(true,in[i].second*r+in[i_1].second*(1.0f-r)));
|
||||
}
|
||||
|
||||
}
|
||||
else if (distance[i_1]>0.0f)
|
||||
{
|
||||
float r = distance[i_1]/(distance[i_1]-distance[i]);
|
||||
out.push_back(Point(true,in[i].second*r+in[i_1].second*(1.0f-r)));
|
||||
}
|
||||
}
|
||||
|
||||
return out.size();
|
||||
}
|
||||
|
||||
// clip the convex hull 'in' to planeList to generate a clipped convex hull 'out'
|
||||
// return true if points remain after clipping.
|
||||
unsigned int clip(const Polytope::PlaneList& planeList,const VertexList& vin,PointList& out)
|
||||
{
|
||||
PointList in;
|
||||
convert(vin,in);
|
||||
|
||||
for(Polytope::PlaneList::const_iterator itr=planeList.begin();
|
||||
itr!=planeList.end();
|
||||
++itr)
|
||||
{
|
||||
if (!clip(*itr,in,out)) return false;
|
||||
in.swap(out);
|
||||
}
|
||||
|
||||
in.swap(out);
|
||||
|
||||
return out.size();
|
||||
}
|
||||
|
||||
void transform(PointList& points,const osg::Matrix& matrix)
|
||||
{
|
||||
for(PointList::iterator itr=points.begin();
|
||||
itr!=points.end();
|
||||
++itr)
|
||||
{
|
||||
itr->second = itr->second*matrix;
|
||||
}
|
||||
}
|
||||
|
||||
void transform(const PointList& in,PointList& out,const osg::Matrix& matrix)
|
||||
{
|
||||
for(PointList::const_iterator itr=in.begin();
|
||||
itr!=in.end();
|
||||
++itr)
|
||||
{
|
||||
out.push_back(Point(itr->first,itr->second * matrix));
|
||||
}
|
||||
}
|
||||
|
||||
void pushToFarPlane(PointList& points)
|
||||
{
|
||||
for(PointList::iterator itr=points.begin();
|
||||
itr!=points.end();
|
||||
++itr)
|
||||
{
|
||||
itr->second.z()=-1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void computePlanes(const PointList& front, const PointList& back, Polytope::PlaneList& planeList)
|
||||
{
|
||||
for(unsigned int i=0;i<front.size();++i)
|
||||
{
|
||||
unsigned int i_1 = (i+1)%front.size(); // do the mod to wrap the index round back to the start.
|
||||
if (!front[i].first || !front[i_1].first)
|
||||
{
|
||||
planeList.push_back(Plane(front[i].second,front[i_1].second,back[i].second));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Plane computeFrontPlane(const PointList& front)
|
||||
{
|
||||
return Plane(front[2].second,front[1].second,front[0].second);
|
||||
}
|
||||
|
||||
bool ShadowVolumeOccluder::computeOccluder(const NodePath& nodePath,const ConvexPlanerOccluder& occluder,CullStack& cullStack)
|
||||
{
|
||||
|
||||
|
||||
// std::cout<<" Computing Occluder"<<std::endl;
|
||||
|
||||
CullingSet& cullingset = cullStack.getCurrentCullingSet();
|
||||
|
||||
const Matrix& MV = cullStack.getModelViewMatrix();
|
||||
const Matrix& P = cullStack.getProjectionMatrix();
|
||||
|
||||
// take a reference to the NodePath to this occluder.
|
||||
_nodePath = nodePath;
|
||||
|
||||
|
||||
// take a reference to the projection matrix.
|
||||
_projectionMatrix = &P;
|
||||
|
||||
|
||||
|
||||
// compute the inverse of the projection matrix.
|
||||
Matrix invP;
|
||||
invP.invert(P);
|
||||
|
||||
// compute the transformation matrix which takes form local coords into clip space.
|
||||
Matrix MVP(MV);
|
||||
MVP *= P;
|
||||
|
||||
// for the occluder polygon and each of the holes do
|
||||
// first transform occluder polygon into clipspace by multiple it by c[i] = v[i]*(MV*P)
|
||||
@ -15,7 +165,52 @@ void ShadowVolumeOccluder::computeOccluder(const NodePath& nodePath,const Convex
|
||||
// compute volume (quality) betwen front polygon in projection space and back polygon in projection space.
|
||||
|
||||
|
||||
const VertexList& vertices_in = occluder.getOccluder().getVertexList();
|
||||
|
||||
PointList points;
|
||||
|
||||
if (clip(cullingset.getFrustum().getPlaneList(),vertices_in,points)>=3)
|
||||
{
|
||||
// compute the points on the far plane.
|
||||
PointList farPoints;
|
||||
farPoints.reserve(points.size());
|
||||
transform(points,farPoints,MVP);
|
||||
pushToFarPlane(farPoints);
|
||||
transform(farPoints,invP);
|
||||
|
||||
// move the occlude points into projection space.
|
||||
transform(points,MV);
|
||||
|
||||
// create the sides of the occluder
|
||||
computePlanes(points,farPoints,_occluderVolume.getPlaneList());
|
||||
|
||||
// create the front face of the occluder
|
||||
Plane occludePlane = computeFrontPlane(points);
|
||||
_occluderVolume.add(occludePlane);
|
||||
|
||||
// if the front face is pointing away from the eye point flip the whole polytope.
|
||||
if (occludePlane[3]>0.0f)
|
||||
{
|
||||
// std::cout << " flipping polytope"<<std::endl;
|
||||
_occluderVolume.flip();
|
||||
}
|
||||
|
||||
|
||||
for(Polytope::PlaneList::const_iterator itr=_occluderVolume.getPlaneList().begin();
|
||||
itr!=_occluderVolume.getPlaneList().end();
|
||||
++itr)
|
||||
{
|
||||
// std::cout << " compute plane "<<*itr<<std::endl;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// std::cout << " occluder clipped out of frustum."<<points.size()<<std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool ShadowVolumeOccluder::contains(const std::vector<Vec3>& vertices)
|
||||
|
@ -546,7 +546,7 @@ void CullVisitor::apply(osg::OccluderNode& node)
|
||||
// list, if so disable the appropriate ShadowOccluderVolume
|
||||
disableOccluder(_nodePath);
|
||||
|
||||
std::cout<<"CullVisitor:: We are in an Occlusion node"<<&node<<std::endl;
|
||||
// std::cout<<"CullVisitor:: We are in an Occlusion node"<<&node<<std::endl;
|
||||
|
||||
|
||||
if (isCulled(node)) return;
|
||||
|
@ -310,7 +310,8 @@ void SceneView::cullStage(osg::Matrix* projection,osg::Matrix* modelview,osgUtil
|
||||
// collect any occluder in the view frustum.
|
||||
if (_sceneData->containsOccluderNodes())
|
||||
{
|
||||
std::cout << "Scene graph contains occluder nodes, searching for them"<<std::endl;
|
||||
//std::cout << "Scene graph contains occluder nodes, searching for them"<<std::endl;
|
||||
|
||||
osg::CollectOccludersVisitor cov;
|
||||
|
||||
cov.setFrameStamp(_frameStamp.get());
|
||||
@ -331,8 +332,10 @@ void SceneView::cullStage(osg::Matrix* projection,osg::Matrix* modelview,osgUtil
|
||||
cov.popModelViewMatrix();
|
||||
cov.popProjectionMatrix();
|
||||
cov.popViewport();
|
||||
|
||||
std::cout << "finished searching for occluder"<<std::endl;
|
||||
|
||||
// std::cout << "finished searching for occluder"<<std::endl;
|
||||
|
||||
cullVisitor->setOccluderList(cov.getCollectedOccluderList());
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user