Additions for the support for ConvexPlaneOccluder. Work still underway.

This commit is contained in:
Robert Osfield
2002-06-03 15:39:41 +00:00
parent 518dd5710a
commit 3f84849210
19 changed files with 328 additions and 246 deletions

View File

@@ -149,6 +149,10 @@ SOURCE=..\..\src\osg\CullFace.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osg\CullingSet.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osg\Depth.cpp
# End Source File
# Begin Source File
@@ -397,10 +401,6 @@ SOURCE=..\..\Include\Osg\ClipNode
# End Source File
# Begin Source File
SOURCE=..\..\Include\Osg\ClippingVolume
# End Source File
# Begin Source File
SOURCE=..\..\Include\Osg\ClipPlane
# End Source File
# Begin Source File
@@ -429,6 +429,10 @@ SOURCE=..\..\Include\Osg\CullFace
# End Source File
# Begin Source File
SOURCE=..\..\Include\Osg\CullingSet
# End Source File
# Begin Source File
SOURCE=..\..\Include\Osg\Depth
# End Source File
# Begin Source File
@@ -589,6 +593,10 @@ SOURCE=..\..\Include\Osg\PolygonOffset
# End Source File
# Begin Source File
SOURCE=..\..\Include\Osg\Polytope
# End Source File
# Begin Source File
SOURCE=..\..\Include\Osg\PositionAttitudeTransform
# End Source File
# Begin Source File

View File

@@ -10,7 +10,6 @@
#include <osg/Referenced>
#include <osg/Matrix>
#include <osg/Quat>
#include <osg/ClippingVolume>
#include <osg/Viewport>
#include <osg/DisplaySettings>

View File

@@ -12,7 +12,7 @@ namespace osg {
class OccluderVolume;
/** A ClippingVolume class for representing convex clipping volumes made up.
/** A class for representing convex clipping volumes made up.
* When adding planes, their normals should point inwards (into the volume) */
class SG_EXPORT ConvexPlanerOccluder : public Referenced
{

View File

@@ -14,7 +14,7 @@ namespace osg {
class BoundingBox;
class BoundingSphere;
/** A ClippingVolume class for representing convex clipping volumes made up.
/** A class for representing convex clipping volumes made up.
* When adding planes, their normals should point inwards (into the volume) */
class SG_EXPORT ConvexPlanerPolygon
{

View File

@@ -126,13 +126,17 @@ class SG_EXPORT Node : public Object
* to the cull traversal.*/
void setCullingActive(const bool active);
/** Get the view frustum/small feature _cullingActive flag. Used a guide
/** Get the view frustum/small feature _cullingActive flag for this node. Used a guide
* to the cull traversal.*/
inline const bool getCullingActive() const { return _cullingActive; }
/** Get the number of Children of this node which have culling disabled.*/
inline const int getNumChildrenWithCullingDisabled() const { return _numChildrenWithCullingDisabled; }
/** Return true if this node can be culled by view frustum, occlusion or small feature culling during the cull traversal.
* note, return true only if no children have culling disabled, and the local _cullingActive flag is true.*/
inline const bool isCullingActive() const { return _numChildrenWithCullingDisabled==0 && _cullingActive && _bsphere.isValid(); }
/**
* Set user data, data must be subclased from Referenced to allow

View File

@@ -2,48 +2,48 @@
//Distributed under the terms of the GNU Library General Public License (LGPL)
//as published by the Free Software Foundation.
#ifndef OSG_CLIPPINGVOLUME
#define OSG_CLIPPINGVOLUME 1
#ifndef OSG_POLYTOPE
#define OSG_POLYTOPE 1
#include <osg/Plane>
#include <vector>
#include <osg/fast_back_stack>
namespace osg {
/** A ClippingVolume class for representing convex clipping volumes made up.
/** A Polytope class for representing convex clipping volumes made up.
* When adding planes, their normals should point inwards (into the volume) */
class SG_EXPORT ClippingVolume
class SG_EXPORT Polytope
{
public:
typedef unsigned int ClippingMask;
typedef std::vector<osg::Plane> PlaneList;
inline ClippingVolume() {setupMask();}
inline Polytope() {setupMask();}
inline ClippingVolume(const ClippingVolume& cs, const unsigned int mask)
{
set(cs,mask);
}
inline ClippingVolume(const ClippingVolume& cv) : _localMask(cv._localMask), _planeList(cv._planeList) {}
inline Polytope(const Polytope& cv) :
_maskStack(cv._maskStack),
_resultsMask(cv._resultsMask),
_planeList(cv._planeList) {}
inline ClippingVolume(const PlaneList& pl) : _planeList(pl) {setupMask();}
inline Polytope(const PlaneList& pl) : _planeList(pl) {setupMask();}
inline ~ClippingVolume() {}
inline ~Polytope() {}
inline void clear() { _planeList.clear(); setupMask(); }
inline ClippingVolume& operator = (const ClippingVolume& cv)
inline Polytope& operator = (const Polytope& cv)
{
if (&cv==this) return *this;
_localMask = cv._localMask;
_planeList = cv._planeList;
return *this;
_maskStack = cv._maskStack;
_resultsMask = cv._resultsMask;
_planeList = cv._planeList;
return *this;
}
/** Create a ClippingVolume with is cube, centered at 0,0,0, with sides of 2 units.*/
/** Create a Polytope with is cube, centered at 0,0,0, with sides of 2 units.*/
void setToUnitFrustum()
{
_planeList.erase(_planeList.begin(),_planeList.end());
@@ -66,22 +66,6 @@ class SG_EXPORT ClippingVolume
setupMask();
}
inline void set(const ClippingVolume& cs, const unsigned int mask)
{
_planeList.erase(_planeList.begin(),_planeList.end());
unsigned int selector_mask = 0x1;
for(PlaneList::const_iterator itr=cs._planeList.begin();
itr!=cs._planeList.end();
++itr)
{
if (mask&selector_mask) _planeList.push_back(*itr);
selector_mask <<= 1;
}
setupMask();
}
inline void set(const ClippingVolume& cs) { _planeList = cs._planeList; setupMask(); }
inline void set(const PlaneList& pl) { _planeList = pl; setupMask(); }
inline void add(const osg::Plane& pl) { _planeList.push_back(pl); setupMask(); }
@@ -92,37 +76,44 @@ class SG_EXPORT ClippingVolume
inline void setupMask()
{
_localMask = 0;
_resultsMask = 0;
for(unsigned int i=0;i<_planeList.size();++i)
{
_localMask = (_localMask<<1) | 1;
_resultsMask = (_resultsMask<<1) | 1;
}
_maskStack.back() = _resultsMask;
}
unsigned int getLocalMask() const { return _localMask; }
inline ClippingMask& getCurrentMask() { return _maskStack.back(); }
inline ClippingMask getCurrentMask() const { return _maskStack.back(); }
inline ClippingMask getResultsMask() const
{
return _resultsMask;
}
inline void pushCurrentMask()
{
_maskStack.push_back(_resultsMask);
}
inline void popCurrentMask()
{
_maskStack.pop_back();
}
/** Check whether a vertex is contained with clipping set.*/
inline const bool contains(const osg::Vec3& v) const
{
for(PlaneList::const_iterator itr=_planeList.begin();
itr!=_planeList.end();
++itr)
{
if (itr->distance(v)<0.0f) return false;
}
return true;
}
inline const bool contains(const osg::Vec3& v,const unsigned int mask) const
{
if (!(mask & _localMask)) return true;
if (!_maskStack.back()) return true;
unsigned int selector_mask = 0x1;
for(PlaneList::const_iterator itr=_planeList.begin();
itr!=_planeList.end();
++itr)
{
if (mask&selector_mask && (itr->distance(v)<0.0f)) return false;
if ((_maskStack.back()&selector_mask) && (itr->distance(v)<0.0f)) return false;
selector_mask <<= 1;
}
return true;
@@ -133,95 +124,97 @@ class SG_EXPORT ClippingVolume
modifying the mask to turn off planes which wouldn't contribute to clipping
of any internal objects. This feature is used in osgUtil::CullVisitor
to prevent redundant plane checking.*/
inline const bool contains(const osg::BoundingSphere& bs,unsigned int& mask) const
inline const bool contains(const osg::BoundingSphere& bs)
{
if (!(mask & _localMask)) return true;
if (!_maskStack.back()) return true;
_resultsMask = _maskStack.back();
ClippingMask selector_mask = 0x1;
unsigned int selector_mask = 0x1;
for(PlaneList::const_iterator itr=_planeList.begin();
itr!=_planeList.end();
++itr)
{
if (mask&selector_mask)
if (_resultsMask&selector_mask)
{
int res=itr->intersect(bs);
if (res<0) return false; // outside clipping set.
else if (res>0) mask ^= selector_mask; // subsequent checks against this plane not required.
else if (res>0) _resultsMask ^= selector_mask; // subsequent checks against this plane not required.
}
selector_mask <<= 1;
}
return true;
}
/** Check whether any part of a bounding sphere is contained within clipping set.*/
inline const bool contains(const osg::BoundingSphere& bs) const
{
for(PlaneList::const_iterator itr=_planeList.begin();
itr!=_planeList.end();
++itr)
{
if (itr->intersect(bs)<0) return false; // outside clipping set.
}
return true;
}
/** Check whether any part of a bounding box is contained within clipping set.
Using a mask to determine which planes should be used for the check, and
modifying the mask to turn off planes which wouldn't contribute to clipping
of any internal objects. This feature is used in osgUtil::CullVisitor
to prevent redundant plane checking.*/
inline const bool contains(const osg::BoundingBox& bb,unsigned int& mask) const
inline const bool contains(const osg::BoundingBox& bb)
{
if (!(mask & _localMask)) return true;
if (!_maskStack.back()) return true;
_resultsMask = _maskStack.back();
ClippingMask selector_mask = 0x1;
unsigned int selector_mask = 0x1;
for(PlaneList::const_iterator itr=_planeList.begin();
itr!=_planeList.end();
++itr)
{
if (mask&selector_mask)
if (_resultsMask&selector_mask)
{
int res=itr->intersect(bb);
if (res<0) return false; // outside clipping set.
else if (res>0) mask ^= selector_mask; // subsequent checks against this plane not required.
else if (res>0) _resultsMask ^= selector_mask; // subsequent checks against this plane not required.
}
selector_mask <<= 1;
}
return true;
}
/** Check whether any part of a bounding box is contained within clipping set.*/
inline const bool contains(const osg::BoundingBox& bb) const
{
for(PlaneList::const_iterator itr=_planeList.begin();
itr!=_planeList.end();
++itr)
{
if (itr->intersect(bb)<0) return false; // outside clipping set.
}
return true;
}
/** Check whether the entire bounding sphere is contained within clipping set.*/
inline const bool containsAllOf(const osg::BoundingSphere& bs) const
inline const bool containsAllOf(const osg::BoundingSphere& bs)
{
if (!_maskStack.back()) return false;
_resultsMask = _maskStack.back();
ClippingMask selector_mask = 0x1;
for(PlaneList::const_iterator itr=_planeList.begin();
itr!=_planeList.end();
++itr)
{
if (itr->intersect(bs)<1) return false; // intersects, or is below plane.
if (_resultsMask&selector_mask)
{
int res=itr->intersect(bs);
if (res<1) return false; // intersects, or is below plane.
_resultsMask ^= selector_mask; // subsequent checks against this plane not required.
}
selector_mask <<= 1;
}
return true;
}
/** Check whether the entire bounding box is contained within clipping set.*/
inline const bool containsAllOf(const osg::BoundingBox& bb) const
inline const bool containsAllOf(const osg::BoundingBox& bb)
{
if (!_maskStack.back()) return false;
_resultsMask = _maskStack.back();
ClippingMask selector_mask = 0x1;
for(PlaneList::const_iterator itr=_planeList.begin();
itr!=_planeList.end();
++itr)
{
if (itr->intersect(bb)<1) return false; // intersects, or is below plane.
if (_resultsMask&selector_mask)
{
int res=itr->intersect(bb);
if (res<1) return false; // intersects, or is below plane.
_resultsMask ^= selector_mask; // subsequent checks against this plane not required.
}
selector_mask <<= 1;
}
return true;
}
@@ -244,19 +237,28 @@ class SG_EXPORT ClippingVolume
* see transform for details. */
inline void transformProvidingInverse(const osg::Matrix& matrix)
{
if (!_maskStack.back()) return;
_resultsMask = _maskStack.back();
ClippingMask selector_mask = 0x1;
for(PlaneList::iterator itr=_planeList.begin();
itr!=_planeList.end();
++itr)
{
itr->transformProvidingInverse(matrix);
if (_resultsMask&selector_mask)
{
itr->transformProvidingInverse(matrix);
selector_mask <<= 1;
}
}
}
protected:
unsigned int _localMask;
PlaneList _planeList;
fast_back_stack<ClippingMask> _maskStack;
ClippingMask _resultsMask;
PlaneList _planeList;
};

View File

@@ -6,24 +6,27 @@
#define OSG_SHADOWOCCLUDERVOLUME 1
#include <osg/ref_ptr>
#include <osg/ClippingVolume>
#include <osg/Polytope>
#include <osg/ConvexPlanerOccluder>
namespace osg {
/** ShadowOccluderVolume is a helper class for implementating shadow occlusion culling. */
class SG_EXPORT ShadowOccluderVolume : public Referenced
class SG_EXPORT ShadowOccluderVolume
{
public:
typedef std::vector<Polytope> HoleList;
ShadowOccluderVolume(const ShadowOccluderVolume& soc,Matrix& MVP);
ShadowOccluderVolume(const ConvexPlanerOccluder& occluder,Matrix& MVP);
typedef std::vector<ClippingVolume> ClippingHoleList;
inline void pushCurrentMask();
inline void popCurrentMask();
/** Convert shadow occluder into local coords by multiplying the
* clip space occluder by the ModelViewProjectionMatrix.*/
void set(const ShadowOccluderVolume& soc,Matrix& MVP);
@@ -34,23 +37,46 @@ class SG_EXPORT ShadowOccluderVolume : public Referenced
/** return true if the specified bounding sphere is contaned entirely
* within this shadow occluder volume.*/
bool contains(const BoundingSphere& bs);
bool contains(const BoundingSphere& bound);
/** return true if the specified bounding box is contained entirely
* within this shadow occluder volume.*/
bool contains(const BoundingBox& bs);
bool contains(const BoundingBox& bound);
protected:
// the original shadow occluder computed in clip space
ref_ptr<ShadowOccluderVolume> _clipSpaceOccluder;
ClippingVolume _occluderVolume;
ClippingHoleList _clippingHoleList;
Polytope _occluderVolume;
HoleList _holeList;
};
inline void ShadowOccluderVolume::pushCurrentMask()
{
_occluderVolume.pushCurrentMask();
if (!_holeList.empty())
{
for(HoleList::iterator itr=_holeList.begin();
itr!=_holeList.end();
++itr)
{
itr->pushCurrentMask();
}
}
}
inline void ShadowOccluderVolume::popCurrentMask()
{
_occluderVolume.popCurrentMask();
if (!_holeList.empty())
{
for(HoleList::iterator itr=_holeList.begin();
itr!=_holeList.end();
++itr)
{
itr->popCurrentMask();
}
}
}
} // end of namespace
#endif

View File

@@ -11,7 +11,7 @@
#include <osg/FrameStamp>
#include <osg/DisplaySettings>
#include <osg/ClippingVolume>
#include <osg/Polytope>
#include <vector>
#include <map>
@@ -100,8 +100,7 @@ class SG_EXPORT State : public Referenced
}
ClippingVolume getClippingVolume() const;
Polytope getViewFrustum() const;
/** Apply stateset.*/

View File

@@ -82,7 +82,6 @@ class SG_EXPORT Texture : public StateAttribute
StateAttribute(text,copyop),
_handleList(),
_modifiedTag(),
_textureObjectSize(text._textureObjectSize),
_image(copyop(text._image.get())),
_target(text._target),
_textureUnit(text._textureUnit),
@@ -232,11 +231,6 @@ class SG_EXPORT Texture : public StateAttribute
/** return the OpenGL texture object for specified context.*/
inline const uint getTextureObject(const uint contextID) const { if (contextID<_handleList.size()) return _handleList[contextID]; else return 0;}
/** return the memory size of texture object.
* Texture object size can be used for estimating the cost of
* uploading the texture to graphics hardware, which in turn can
* be used for setting texture residence priorities. */
inline const uint getTextureObjectSize() const { return _textureObjectSize; }
enum SubloadMode {
OFF,
@@ -339,9 +333,6 @@ class SG_EXPORT Texture : public StateAttribute
typedef std::vector<uint> ImageModifiedTag;
mutable ImageModifiedTag _modifiedTag;
// size of the created OpenGL texture object, may be estimated.
mutable uint _textureObjectSize;
// not ideal that _image is mutable, but its required since
// Image::ensureDimensionsArePowerOfTwo() can only be called

View File

@@ -5,6 +5,8 @@
#ifndef OSG_FAST_BACK_STACK
#define OSG_FAST_BACK_STACK 1
#include <vector>
namespace osg {
/** Simple stack implementation that keeps the back() cached locally for fast access
@@ -22,8 +24,17 @@ class fast_back_stack
inline fast_back_stack():_value(),_stack(),_size(0) {}
inline fast_back_stack(const fast_back_stack& fbs):_value(fbs._value),_stack(fbs._stack),_size(fbs._size) {}
inline fast_back_stack(const T& value):_value(value),_stack(),_size(1) {}
fast_back_stack& operator = (const fast_back_stack& fbs)
{
_value = fbs._value;
_stack = fbs._stack;
_size = fbs._size;
}
inline void clear() { _stack.clear(); _size = 0; }
inline bool empty() const { return _size==0; }
@@ -34,6 +45,15 @@ class fast_back_stack
inline const T& back() const { return _value; }
inline void push_back()
{
if (_size>0)
{
_stack.push_back(_value);
}
++_size;
}
inline void push_back(const T& value)
{
if (_size>0)

View File

@@ -15,7 +15,9 @@
#include <osg/Impostor>
#include <osg/EarthSky>
#include <osg/Notify>
#include <osg/Notify>
#include <osg/CullingSet>
#include <osg/fast_back_stack>
#include <osgUtil/RenderGraph>
@@ -240,31 +242,50 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor
v.y()*mvpw(1,3)+
v.z()*mvpw(2,3)+
mvpw(3,3);
return fabs(radius*_windowToModelFactor/W);
}
osg::ClippingVolume& getCurrentClippingVolume() { return _modelviewClippingVolumeStack.back(); }
inline bool isCulled(const osg::BoundingSphere& sp,CullingMode& mode)
inline float pixelSize2(const osg::Vec3& v, float const radius)
{
if (!sp.isValid()) return true;
const float R2 = osg::square(_viewportStack.back()->width()/osg::DegreesToRadians(38.0f))*1.15f;
if (!(_modelviewClippingVolumeStack.back().contains(sp,mode))) return true;
//float p1 = fabs(radius*_windowToModelFactor/W);
return R2*radius*radius/(v-getEyeLocal()).length2();
if (mode&SMALL_FEATURE_CULLING)
}
inline bool isCulled(const osg::Node& node)
{
if (node.isCullingActive())
{
if (pixelSize(sp.center(),sp.radius())<_smallFeatureCullingPixelSize) return true;
const osg::BoundingSphere& sp = node.getBound();
if (!(_modelviewPolytopeStack.back().contains(sp))) return true;
// if (pixelSize(sp.center(),sp.radius())<_smallFeatureCullingPixelSize) return true;
if (pixelSize2(sp.center(),sp.radius())<osg::square(_smallFeatureCullingPixelSize)) return true;
}
return false;
}
inline const bool isCulled(const osg::BoundingBox& bb,CullingMode mode)
inline const bool isCulled(const osg::BoundingBox& bb)
{
if (!bb.isValid()) return true;
return !_modelviewClippingVolumeStack.back().contains(bb,mode);
//return !_modelviewPolytopeStack.back().contains(bb,mode);
return !_modelviewPolytopeStack.back().contains(bb);
//return false;
}
inline void pushCurrentMask()
{
_modelviewPolytopeStack.back().pushCurrentMask();
}
inline void popCurrentMask()
{
_modelviewPolytopeStack.back().popCurrentMask();
}
const CullingMode getCurrentCullingMode() const { return _cullingModeStack.back(); }
@@ -327,23 +348,23 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor
void pushClippingVolume();
void popClippingVolume();
void pushPolytope();
void popPolytope();
// typedef std::vector<osg::ClippingVolume> ClippingVolumeStack;
// typedef std::vector<osg::Polytope> PolytopeStack;
// typedef std::vector<osg::ref_ptr<osg::Matrix> > MatrixStack;
typedef osg::fast_back_stack<osg::ClippingVolume> ClippingVolumeStack;
typedef osg::fast_back_stack<osg::Polytope> PolytopeStack;
typedef osg::fast_back_stack< osg::ref_ptr<osg::Matrix> > MatrixStack;
MatrixStack _projectionStack;
MatrixStack _PW_Stack;
ClippingVolumeStack _projectionClippingVolumeStack;
PolytopeStack _projectionPolytopeStack;
MatrixStack _modelviewStack;
MatrixStack _MVPW_Stack;
ClippingVolumeStack _modelviewClippingVolumeStack;
PolytopeStack _modelviewPolytopeStack;
bool _windowToModelFactorDirty;
float _windowToModelFactor;
@@ -358,6 +379,10 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor
typedef osg::fast_back_stack<CullingMode> CullingModeStack;
CullingModeStack _cullingModeStack;
typedef osg::fast_back_stack<osg::ref_ptr<osg::CullingSet> > ClippingStack;
ClippingStack _clippingSet;
unsigned int _bbCornerNear;
unsigned int _bbCornerFar;

View File

@@ -20,7 +20,7 @@ Camera::Camera(DisplaySettings* ds)
}
setPerspective(fovy,1.0,1.0,1000.0);
// look at details.
_lookAtType =USE_HOME_POSITON;

11
src/osg/CullingSet.cpp Normal file
View File

@@ -0,0 +1,11 @@
#include <osg/CullingSet>
using namespace osg;
CullingSet::CullingSet()
{
}
CullingSet::~CullingSet()
{
}

View File

@@ -16,6 +16,7 @@ CXXFILES =\
ConvexPlanerOccluder.cpp\
CopyOp.cpp\
CullFace.cpp\
CullingSet.cpp\
Depth.cpp\
DisplaySettings.cpp\
Drawable.cpp\

View File

@@ -1,3 +1,54 @@
#include <osg/ShadowOccluderVolume>
using namespace osg;
ShadowOccluderVolume::ShadowOccluderVolume(const ShadowOccluderVolume& soc,Matrix& MVP)
{
set(soc,MVP);
}
ShadowOccluderVolume::ShadowOccluderVolume(const ConvexPlanerOccluder& occluder,Matrix& MVP)
{
set(occluder,MVP);
}
void ShadowOccluderVolume::set(const ShadowOccluderVolume& soc,Matrix& MVP)
{
}
void ShadowOccluderVolume::set(const ConvexPlanerOccluder& occluder,Matrix& MVP)
{
}
bool ShadowOccluderVolume::contains(const BoundingSphere& bound)
{
if (_occluderVolume.containsAllOf(bound))
{
for(HoleList::iterator itr=_holeList.begin();
itr!=_holeList.end();
++itr)
{
if (itr->contains(bound)) return false;
}
return true;
}
return false;
}
bool ShadowOccluderVolume::contains(const BoundingBox& bound)
{
if (_occluderVolume.containsAllOf(bound))
{
for(HoleList::iterator itr=_holeList.begin();
itr!=_holeList.end();
++itr)
{
if (itr->contains(bound)) return false;
}
return true;
}
return false;
}

View File

@@ -599,9 +599,9 @@ const StateAttribute* State::getLastAppliedAttribute(const StateAttribute::Type
}
ClippingVolume State::getClippingVolume() const
Polytope State::getViewFrustum() const
{
ClippingVolume cv;
Polytope cv;
cv.setToUnitFrustum();
cv.transformProvidingInverse((*_modelView)*(*_projection));
return cv;

View File

@@ -40,8 +40,6 @@ Texture::Texture()
_textureWidth = _textureHeight = 0;
_textureObjectSize = 0;
_subloadMode = OFF;
_subloadOffsX = _subloadOffsY = 0;
_subloadWidth = _subloadHeight = 0;
@@ -445,9 +443,6 @@ void Texture::applyTexImage(GLenum target, Image* image, State& state) const
(GLenum)image->getDataType(),
image->data() );
// just estimate estimate it right now..
// note, ignores texture compression..
_textureObjectSize = image->s()*image->t()*4;
}
else if(glCompressedTexImage2D_ptr)
{
@@ -458,7 +453,6 @@ void Texture::applyTexImage(GLenum target, Image* image, State& state) const
size,
image->data());
_textureObjectSize = size;
}
}
@@ -470,14 +464,10 @@ void Texture::applyTexImage(GLenum target, Image* image, State& state) const
image->s(),image->t(),
(GLenum)image->getPixelFormat(), (GLenum)image->getDataType(),
image->data() );
// just estimate size it right now..
// crude x2 multiplier to account for minmap storage.
// note, ignores texture compression..
_textureObjectSize = image->s()*image->t()*4;
}
else
{
_textureObjectSize = 0;
size_t no_mipmaps = image->getNumMipmaps();
int width = image->s();
int height = image->t();
@@ -498,7 +488,6 @@ void Texture::applyTexImage(GLenum target, Image* image, State& state) const
(GLenum)image->getDataType(),
image->getMipmapData(k));
_textureObjectSize += width*height*4;
width >>= 1;
height >>= 1;
}
@@ -518,7 +507,6 @@ void Texture::applyTexImage(GLenum target, Image* image, State& state) const
glCompressedTexImage2D_ptr(target, k, internalFormat,
width, height, 0, size, image->getMipmapData(k));
_textureObjectSize += size;
width >>= 1;
height >>= 1;
}

View File

@@ -125,10 +125,10 @@ void CullVisitor::reset()
// first unref all referenced objects and then empty the containers.
//
_projectionStack.clear();
_projectionClippingVolumeStack.clear();
_projectionPolytopeStack.clear();
_modelviewStack.clear();
_modelviewClippingVolumeStack.clear();
_modelviewPolytopeStack.clear();
_viewportStack.clear();
@@ -139,7 +139,6 @@ void CullVisitor::reset()
_cullingModeStack.clear();
// reset the calculated near far planes.
_computeNearFar = COMPUTE_NEAR_FAR_USING_BOUNDING_VOLUMES;
_computed_znear = FLT_MAX;
_computed_zfar = -FLT_MAX;
@@ -167,13 +166,11 @@ void CullVisitor::reset()
_windowToModelFactor = 1.0f;
}
void CullVisitor::pushClippingVolume()
void CullVisitor::pushPolytope()
{
_modelviewClippingVolumeStack.push_back(osg::ClippingVolume());
osg::ClippingVolume& cv = _modelviewClippingVolumeStack.back();
//cv.set(_projectionClippingVolumeStack.back());
cv.set(_projectionClippingVolumeStack.back(),_cullingModeStack.back());
_cullingModeStack.push_back(cv.getLocalMask() | (_cullingModeStack.back()&SMALL_FEATURE_CULLING));
_modelviewPolytopeStack.push_back();
osg::Polytope& cv = _modelviewPolytopeStack.back();
cv = _projectionPolytopeStack.back();
if (!_modelviewStack.empty()) cv.transformProvidingInverse(*_modelviewStack.back());
@@ -182,11 +179,10 @@ void CullVisitor::pushClippingVolume()
_windowToModelFactorDirty = true;
}
void CullVisitor::popClippingVolume()
void CullVisitor::popPolytope()
{
_modelviewClippingVolumeStack.pop_back();
_modelviewPolytopeStack.pop_back();
_MVPW_Stack.pop_back();
_cullingModeStack.pop_back();
_windowToModelFactorDirty = true;
}
@@ -207,11 +203,11 @@ void CullVisitor::pushProjectionMatrix(Matrix* matrix)
{
_projectionStack.push_back(matrix);
_projectionClippingVolumeStack.push_back(ClippingVolume());
_projectionClippingVolumeStack.back().setToUnitFrustumWithoutNearFar();
_projectionClippingVolumeStack.back().transformProvidingInverse(*matrix);
_projectionPolytopeStack.push_back();
_projectionPolytopeStack.back().setToUnitFrustumWithoutNearFar();
_projectionPolytopeStack.back().transformProvidingInverse(*matrix);
pushClippingVolume();
pushPolytope();
}
void CullVisitor::popProjectionMatrix()
@@ -243,16 +239,16 @@ void CullVisitor::popProjectionMatrix()
}
_projectionStack.pop_back();
_projectionClippingVolumeStack.pop_back();
_projectionPolytopeStack.pop_back();
popClippingVolume();
popPolytope();
}
void CullVisitor::pushModelViewMatrix(Matrix* matrix)
{
_modelviewStack.push_back(matrix);
pushClippingVolume();
pushPolytope();
// fast method for computing the eye point in local coords which doesn't require the inverse matrix.
const float x_0 = (*matrix)(0,0);
@@ -289,7 +285,7 @@ void CullVisitor::popModelViewMatrix()
{
_modelviewStack.pop_back();
_eyePointStack.pop_back();
popClippingVolume();
popPolytope();
osg::Vec3 lookVector(0.0f,0.0f,-1.0f);
@@ -364,14 +360,10 @@ CullVisitor::CullingMode CullVisitor::getCullingMode() const
void CullVisitor::apply(Node& node)
{
CullingMode mode = _cullingModeStack.back();
if (!node.getCullingActive()) mode = 0;
else if (node.getNumChildrenWithCullingDisabled()==0 &&
isCulled(node.getBound(),mode)) return;
if (isCulled(node)) return;
// push the culling mode.
_cullingModeStack.push_back(mode);
pushCurrentMask();
// push the node's state.
StateSet* node_state = node.getStateSet();
@@ -383,19 +375,13 @@ void CullVisitor::apply(Node& node)
if (node_state) popStateSet();
// pop the culling mode.
_cullingModeStack.pop_back();
popCurrentMask();
}
void CullVisitor::apply(Geode& node)
{
// return if object's bounding sphere is culled.
CullingMode mode = _cullingModeStack.back();
if (!node.getCullingActive()) mode = 0;
else if (node.getNumChildrenWithCullingDisabled()==0 &&
isCulled(node.getBound(),mode)) return;
if (isCulled(node)) return;
// push the node's state.
StateSet* node_state = node.getStateSet();
@@ -414,7 +400,7 @@ void CullVisitor::apply(Geode& node)
}
else
{
if (isCulled(bb,mode)) continue;
if (isCulled(bb)) continue;
}
@@ -490,12 +476,7 @@ void CullVisitor::apply(Geode& node)
void CullVisitor::apply(Billboard& node)
{
// return if object's bounding sphere is culled.
CullingMode mode = _cullingModeStack.back();
if (!node.getCullingActive()) mode = 0;
else if (node.getNumChildrenWithCullingDisabled()==0 &&
isCulled(node.getBound(),mode)) return;
if (isCulled(node)) return;
// push the node's state.
StateSet* node_state = node.getStateSet();
@@ -602,15 +583,10 @@ void CullVisitor::apply(ClipNode& node)
void CullVisitor::apply(Group& node)
{
// return if object's bounding sphere is culled.
CullingMode mode = _cullingModeStack.back();
if (!node.getCullingActive()) mode = 0;
else if (node.getNumChildrenWithCullingDisabled()==0 &&
isCulled(node.getBound(),mode)) return;
if (isCulled(node)) return;
// push the culling mode.
_cullingModeStack.push_back(mode);
pushCurrentMask();
// push the node's state.
StateSet* node_state = node.getStateSet();
@@ -622,20 +598,15 @@ void CullVisitor::apply(Group& node)
if (node_state) popStateSet();
// pop the culling mode.
_cullingModeStack.pop_back();
popCurrentMask();
}
void CullVisitor::apply(Transform& node)
{
// return if object's bounding sphere is culled.
CullingMode mode = _cullingModeStack.back();
if (!node.getCullingActive()) mode = 0;
else if (node.getNumChildrenWithCullingDisabled()==0 &&
isCulled(node.getBound(),mode)) return;
if (isCulled(node)) return;
// push the culling mode.
_cullingModeStack.push_back(mode);
pushCurrentMask();
// push the node's state.
StateSet* node_state = node.getStateSet();
@@ -653,20 +624,15 @@ void CullVisitor::apply(Transform& node)
if (node_state) popStateSet();
// pop the culling mode.
_cullingModeStack.pop_back();
popCurrentMask();
}
void CullVisitor::apply(Projection& node)
{
// return if object's bounding sphere is culled.
CullingMode mode = _cullingModeStack.back();
if (!node.getCullingActive()) mode = 0;
else if (node.getNumChildrenWithCullingDisabled()==0 &&
isCulled(node.getBound(),mode)) return;
if (isCulled(node)) return;
// push the culling mode.
_cullingModeStack.push_back(mode);
pushCurrentMask();
// push the node's state.
StateSet* node_state = node.getStateSet();
@@ -695,7 +661,7 @@ void CullVisitor::apply(Projection& node)
if (node_state) popStateSet();
// pop the culling mode.
_cullingModeStack.pop_back();
popCurrentMask();
}
void CullVisitor::apply(Switch& node)
@@ -706,18 +672,13 @@ void CullVisitor::apply(Switch& node)
void CullVisitor::apply(LOD& node)
{
// return if object's bounding sphere is culled.
CullingMode mode = _cullingModeStack.back();
if (!node.getCullingActive()) mode = 0;
else if (node.getNumChildrenWithCullingDisabled()==0 &&
isCulled(node.getBound(),mode)) return;
if (isCulled(node)) return;
int eval = node.evaluate(getEyeLocal(),_LODBias);
if (eval<0) return;
// push the culling mode.
_cullingModeStack.push_back(mode);
pushCurrentMask();
// push the node's state.
StateSet* node_state = node.getStateSet();
@@ -730,7 +691,7 @@ void CullVisitor::apply(LOD& node)
if (node_state) popStateSet();
// pop the culling mode.
_cullingModeStack.pop_back();
popCurrentMask();
}
void CullVisitor::apply(osg::EarthSky& node)
@@ -752,29 +713,22 @@ void CullVisitor::apply(osg::EarthSky& node)
void CullVisitor::apply(Impostor& node)
{
const BoundingSphere& bs = node.getBound();
// return if object's bounding sphere is culled.
CullingMode mode = _cullingModeStack.back();
if (!node.getCullingActive()) mode = 0;
else if (node.getNumChildrenWithCullingDisabled()==0 &&
isCulled(node.getBound(),mode)) return;
if (isCulled(node)) return;
osg::Vec3 eyeLocal = getEyeLocal();
int eval = node.evaluate(eyeLocal,_LODBias);
if (eval<0){
return;
}
if (eval<0) return;
// push the culling mode.
_cullingModeStack.push_back(mode);
pushCurrentMask();
// push the node's state.
StateSet* node_state = node.getStateSet();
if (node_state) pushStateSet(node_state);
const BoundingSphere& bs = node.getBound();
float distance2 = (eyeLocal-bs.center()).length2();
if (!_impostorActive ||
@@ -875,7 +829,7 @@ void CullVisitor::apply(Impostor& node)
if (node_state) popStateSet();
// pop the culling mode.
_cullingModeStack.pop_back();
popCurrentMask();
}
ImpostorSprite* CullVisitor::createImpostorSprite(Impostor& node)
@@ -1030,7 +984,7 @@ ImpostorSprite* CullVisitor::createImpostorSprite(Impostor& node)
}
// restore the culling mode.
_cullingModeStack.pop_back();
popCurrentMask();
popStateSet();

View File

@@ -194,6 +194,9 @@ void SceneView::cull()
if (!projection) projection = osgNew osg::Matrix(_camera->getProjectionMatrix());
if (!modelview) modelview = osgNew osg::Matrix(_camera->getModelViewMatrix());
//cout <<"fovx="<<_camera->calc_fovx()<<endl;
}
if (!projection) projection = osgNew osg::Matrix();