Further work on removing Camera references from NewCullVisitor and releted

classes, this work paves the way for making osg::Camera an optional
extra rather than a requirement for rendering.
This commit is contained in:
Robert Osfield 2002-04-09 16:09:19 +00:00
parent 57248a4bf9
commit 6f65e86057
12 changed files with 510 additions and 493 deletions

View File

@ -102,9 +102,9 @@ class SG_EXPORT ImpostorSprite : public Drawable
inline const Vec3* getControlCoords() const { return _controlcoords; }
/** calculate the pixel error value for current camera position and object position.*/
const float calcPixelError(const Camera& camera,const Viewport& viewport,const osg::Matrix* matrix) const;
/** calculate the pixel error value for passing in the ModelViewProjectionWindow transform,
* which transform local coords into screen space.*/
const float ImpostorSprite::calcPixelError(const Matrix& MVPW) const;
void setTexture(Texture* tex,int s,int t);

View File

@ -88,9 +88,35 @@ class SG_EXPORT Matrix : public Object
void makeRotate( float angle, float x, float y, float z );
void makeRotate( const Quat& );
void makeRotate( float, float, float ); //Euler angles
/** Set to a orthographic projection. See glOrtho for further details.*/
void makeOrtho(const double left, const double right,
const double bottom, const double top,
const double zNear, const double zFar);
/** Set to a 2D orthographic projection. See glOrtho2D for further details.*/
inline void makeOrtho2D(const double left, const double right,
const double bottom, const double top)
{
makeOrtho(left,right,bottom,top,-1.0,1.0);
}
/** Set to a perspective projection. See glFrustum for further details.*/
void makeFrustum(const double left, const double right,
const double bottom, const double top,
const double zNear, const double zFar);
/** Set to a symmetrical perspective projection, See gluPerspective for further details.
* Aspect ratio is defined as width/height.*/
void makePerspective(const double fovy,const double aspectRatio,
const double zNear, const double zFar);
/** Set to the position and orientation as per a camera, using the same convention as gluLookAt. */
void makeLookAt(const Vec3& eye,const Vec3& center,const Vec3& up);
bool invert( const Matrix& );
bool invertAffine( const Matrix& );
//basic utility functions to create new matrices
inline static Matrix identity( void );
@ -101,7 +127,30 @@ class SG_EXPORT Matrix : public Object
inline static Matrix rotate( const Vec3&, const Vec3& );
inline static Matrix rotate( float, float, float, float );
inline static Matrix rotate( float angle, const Vec3& axis);
inline static Matrix rotate( const Quat& );
inline static Matrix rotate( const Quat&);
/** Create a orthographic projection. See glOrtho for further details.*/
inline static Matrix ortho(const double left, const double right,
const double bottom, const double top,
const double zNear, const double zFar);
/** Create a 2D orthographic projection. See glOrtho for further details.*/
inline static Matrix ortho2D(const double left, const double right,
const double bottom, const double top);
/** Create a perspective projection. See glFrustum for further details.*/
inline static Matrix frustum(const double left, const double right,
const double bottom, const double top,
const double zNear, const double zFar);
/** Create a symmetrical perspective projection, See gluPerspective for further details.
* Aspect ratio is defined as width/height.*/
inline static Matrix perspective(const double fovy,const double aspectRatio,
const double zNear, const double zFar);
/** Create the position and orientation as per a camera, using the same convention as gluLookAt. */
inline static Matrix lookAt(const Vec3& eye,const Vec3& center,const Vec3& up);
inline Vec3 preMult( const Vec3& v ) const;
inline Vec3 postMult( const Vec3& v ) const;
@ -227,6 +276,48 @@ inline Matrix Matrix::rotate(const Vec3& from, const Vec3& to )
return m;
}
inline Matrix Matrix::ortho(const double left, const double right,
const double bottom, const double top,
const double zNear, const double zFar)
{
Matrix m;
m.makeOrtho(left,right,bottom,top,zNear,zFar);
return m;
}
inline Matrix Matrix::ortho2D(const double left, const double right,
const double bottom, const double top)
{
Matrix m;
m.makeOrtho2D(left,right,bottom,top);
return m;
}
inline Matrix Matrix::frustum(const double left, const double right,
const double bottom, const double top,
const double zNear, const double zFar)
{
Matrix m;
m.makeFrustum(left,right,bottom,top,zNear,zFar);
return m;
}
inline Matrix Matrix::perspective(const double fovy,const double aspectRatio,
const double zNear, const double zFar)
{
Matrix m;
m.makePerspective(fovy,aspectRatio,zNear,zFar);
return m;
}
inline Matrix Matrix::lookAt(const Vec3& eye,const Vec3& center,const Vec3& up)
{
Matrix m;
m.makeLookAt(eye,center,up);
return m;
}
inline Vec3 Matrix::postMult( const Vec3& v ) const
{
float d = 1.0f/(_mat[3][0]*v.x()+_mat[3][1]*v.y()+_mat[3][2]*v.z()+_mat[3][3]) ;

View File

@ -12,7 +12,6 @@
#include <osg/Drawable>
#include <osg/StateSet>
#include <osg/State>
#include <osg/Camera>
#include <osg/Impostor>
#include <osg/EarthSky>
#include <osg/Notify>
@ -60,12 +59,6 @@ class OSGUTIL_EXPORT NewCullVisitor : public osg::NodeVisitor
virtual void apply(osg::EarthSky& node);
virtual void apply(osg::Impostor& node);
void setCamera(const osg::Camera& camera);
const osg::Camera* getCamera() const { return _camera.get(); }
void setEarthSky(const osg::EarthSky* earthSky) { _earthSky = earthSky; }
const osg::EarthSky* getEarthSky() const { return _earthSky.get(); }
@ -118,24 +111,14 @@ class OSGUTIL_EXPORT NewCullVisitor : public osg::NodeVisitor
CullViewState::CullingMode getCullingMode() const;
/** Set the viewport.
* Used to enable the NewCullVisitor can make decision
* such as based on viewport dimensions.*/
void setViewport(osg::Viewport* viewport) { _viewport = viewport; }
void pushViewport(osg::Viewport* viewport);
void popViewport();
/** Get the const viewport. */
const osg::Viewport* getViewport() const { return _viewport.get(); }
void pushProjectionMatrix(osg::Matrix* matrix);
void popProjectionMatrix();
/** Get the viewport. */
osg::Viewport* getViewport() { return _viewport.get(); }
inline void pushCullViewState() { pushCullViewState_ModelView(NULL,NULL); }
void pushCullViewState_Projection(osg::Matrix* matrix);
void pushCullViewState_ModelView(osg::Matrix* matrix);
void pushCullViewState_ModelView(osg::Matrix* matrix,osg::Matrix* inverse);
void popCullViewState();
void pushModelViewMatrix(osg::Matrix* matrix);
void popModelViewMatrix();
/** Push state set on the current state group.
* If the state exists in a child state group of the current
@ -202,55 +185,56 @@ class OSGUTIL_EXPORT NewCullVisitor : public osg::NodeVisitor
inline osg::Matrix* getCurrentMatrix()
{
return _cvs->_matrix.get();
}
inline osg::Matrix* getInverseCurrentMatrix()
{
return _cvs->_inverse.get();
return _modelviewStack.back().get();
}
inline const osg::Vec3& getEyeLocal() const
{
return _cvs->_eyePoint;
return _eyePointStack.back();
}
inline const osg::Vec3 NewCullVisitor::getUpLocal() const
{
const osg::Matrix& matrix = *_modelviewStack.back();
return osg::Vec3(matrix(0,1),matrix(1,1),matrix(2,1));
}
inline const osg::Vec3& getUpLocal() const
inline const osg::Vec3 NewCullVisitor::getLookVectorLocal() const
{
return _cvs->_upVector;
}
inline const osg::Vec3& getCenterLocal() const
{
return _cvs->_centerPoint;
}
inline const osg::Vec3& getLookVectorLocal() const
{
return _cvs->_lookVector;
const osg::Matrix& matrix = *_modelviewStack.back();
return osg::Vec3(-matrix(0,2),-matrix(1,2),-matrix(2,2));
}
inline bool isCulled(const osg::BoundingSphere& sp,CullViewState::CullingMode& mode) const
{
return _cvs->isCulled(sp,mode);
if (!sp.isValid()) return true;
if (!(_modelviewClippingVolumeStack.back().contains(sp,mode))) return true;
if (mode&CullViewState::SMALL_FEATURE_CULLING)
{
const float _ratio2 = 0.002f*0.002f;
osg::Vec3 delta(sp._center-getEyeLocal());
if (sp.radius2()<delta.length2()*_ratio2)
{
return true;
}
}
return false;
}
inline const bool isCulled(const osg::BoundingBox& bb,const CullViewState::CullingMode mode) const
inline const bool isCulled(const osg::BoundingBox& bb,CullViewState::CullingMode mode) const
{
return _cvs->isCulled(bb,mode);
if (!bb.isValid()) return true;
return !_modelviewClippingVolumeStack.back().contains(bb,mode);
}
void updateCalculatedNearFar(const osg::BoundingBox& bb);
void updateCalculatedNearFar(const osg::Vec3& pos);
/**calculates near for "global" vertex in scene*/
double calculateZNear(const osg::Vec3& position, const osg::Vec3& eye, const osg::Vec3& look);
/** Add a drawable to current render graph.*/
inline void addDrawable(osg::Drawable* drawable,osg::Matrix* matrix)
{
@ -262,7 +246,7 @@ class OSGUTIL_EXPORT NewCullVisitor : public osg::NodeVisitor
_currentRenderBin->addRenderGraph(_currentRenderGraph);
}
//_currentRenderGraph->addLeaf(new RenderLeaf(drawable,matrix));
_currentRenderGraph->addLeaf(createOrReuseRenderLeaf(drawable,_cvs->_projection.get(),matrix));
_currentRenderGraph->addLeaf(createOrReuseRenderLeaf(drawable,_projectionStack.back().get(),matrix));
}
/** Add a drawable and depth to current render graph.*/
@ -276,7 +260,7 @@ class OSGUTIL_EXPORT NewCullVisitor : public osg::NodeVisitor
_currentRenderBin->addRenderGraph(_currentRenderGraph);
}
//_currentRenderGraph->addLeaf(new RenderLeaf(drawable,matrix,depth));
_currentRenderGraph->addLeaf(createOrReuseRenderLeaf(drawable,_cvs->_projection.get(),matrix,depth));
_currentRenderGraph->addLeaf(createOrReuseRenderLeaf(drawable,_projectionStack.back().get(),matrix,depth));
}
/** Add a light to current render graph.*/
@ -289,33 +273,125 @@ class OSGUTIL_EXPORT NewCullVisitor : public osg::NodeVisitor
* to generate the impostor texture. */
osg::ImpostorSprite* createImpostorSprite(osg::Impostor& node);
typedef std::vector< osg::ref_ptr<CullViewState> > CullViewStateStack;
CullViewStateStack _viewStateStack;
osg::ref_ptr<CullViewState> _tvs;
osg::ref_ptr<CullViewState> _cvs;
osg::Viewport* getViewport()
{
if (!_viewportStack.empty())
{
return _viewportStack.back().get();
}
else
{
return 0L;
}
}
osg::Matrix& getModelViewMatrix()
{
if (!_modelviewStack.empty())
{
return *_modelviewStack.back();
}
else
{
// default construction to identity.
static osg::Matrix identity;
return identity;
}
}
osg::Matrix& getProjectionMatrix()
{
if (!_projectionStack.empty())
{
return *_projectionStack.back();
}
else
{
// default construction to identity.
static osg::Matrix identity;
return identity;
}
}
const osg::Matrix getWindowMatrix()
{
if (!_viewportStack.empty())
{
osg::Viewport* viewport = _viewportStack.back().get();
return osg::Matrix::scale(0.5f*viewport->width(),viewport->height(),0.5f)*osg::Matrix::translate(0.5f,0.5f,0.5f);
}
else
{
// default construction to identity.
static osg::Matrix identity;
return identity;
}
}
const osg::Matrix& getMVPW()
{
if (!_MVPW_Stack.empty())
{
if (!_MVPW_Stack.back())
{
_MVPW_Stack.back() = new osg::Matrix(getModelViewMatrix()*getProjectionMatrix()*getWindowMatrix());
}
return *_MVPW_Stack.back();
}
else
{
// default construction to identity.
static osg::Matrix identity;
return identity;
}
}
void pushClippingVolume();
void popClippingVolume();
typedef std::vector<osg::ClippingVolume> ClippingVolumeStack;
typedef std::vector<osg::ref_ptr<osg::Matrix> > MatrixStack;
MatrixStack _projectionStack;
MatrixStack _PW_Stack;
ClippingVolumeStack _projectionClippingVolumeStack;
MatrixStack _modelviewStack;
MatrixStack _MVPW_Stack;
ClippingVolumeStack _modelviewClippingVolumeStack;
typedef std::vector<osg::ref_ptr<osg::Viewport> > ViewportStack;
ViewportStack _viewportStack;
typedef std::vector<osg::Vec3> EyePointStack;
EyePointStack _eyePointStack;
typedef std::vector<CullViewState::CullingMode> CullingModeStack;
CullingModeStack _cullingModeStack;
unsigned int _bbCornerNear;
unsigned int _bbCornerFar;
osg::ref_ptr<RenderGraph> _rootRenderGraph;
RenderGraph* _currentRenderGraph;
osg::ref_ptr<RenderStage> _rootRenderStage;
RenderBin* _currentRenderBin;
std::vector<CullViewState::CullingMode> _cullingModeStack;
float _LODBias;
float _calculated_znear;
float _calculated_zfar;
osg::ref_ptr<const osg::Camera> _camera;
osg::ref_ptr<const osg::EarthSky> _earthSky;
TransparencySortMode _tsm;
// viewport x,y,width,height respectively.
osg::ref_ptr<osg::Viewport> _viewport;
bool _impostorActive;
bool _depthSortImpostorSprites;
float _impostorPixelErrorThreshold;

View File

@ -5,7 +5,6 @@
#ifndef OSGUTIL_RENDERSTAGE
#define OSGUTIL_RENDERSTAGE 1
#include <osg/Camera>
#include <osg/ColorMask>
#include <osgUtil/RenderBin>
@ -92,12 +91,6 @@ class OSGUTIL_EXPORT RenderStage : public RenderBin
/** Get the clear color.*/
const int getClearStencil() const { return _clearStencil; }
void setCamera(osg::Camera* camera) { _camera = camera; }
osg::Camera* getCamera() { return _camera.get(); }
const osg::Camera* getCamera() const { return _camera.get(); }
void setRenderStageLighting(RenderStageLighting* rsl) { _renderStageLighting = rsl; }
RenderStageLighting* getRenderStageLighting() const
@ -125,8 +118,6 @@ class OSGUTIL_EXPORT RenderStage : public RenderBin
bool _stageDrawnThisFrame;
DependencyList _dependencyList;
osg::ref_ptr<osg::Camera> _camera;
// viewport x,y,width,height.
osg::ref_ptr<osg::Viewport> _viewport;

View File

@ -40,31 +40,16 @@ ImpostorSprite::~ImpostorSprite()
}
}
const float ImpostorSprite::calcPixelError(const Camera& camera,const Viewport& viewport,const osg::Matrix* matrix) const
const float ImpostorSprite::calcPixelError(const Matrix& MVPW) const
{
// find the maximum screen space pixel error between the control coords and the quad coners.
float max_error_sqrd = 0.0f;
for(int i=0;i<4;++i)
{
Vec3 projected_coord;
Vec3 projected_control;
if (matrix)
{
// project the coords of the quad into screen space.
camera.project(_coords[i]*(*matrix),viewport,projected_coord);
// project the controls coords into screen space.
camera.project(_controlcoords[i]*(*matrix),viewport,projected_control);
}
else
{
// project the coords of the quad into screen space.
camera.project(_coords[i],viewport,projected_coord);
// project the controls coords into screen space.
camera.project(_controlcoords[i],viewport,projected_control);
}
Vec3 projected_coord = _coords[i]*MVPW;
Vec3 projected_control = _controlcoords[i]*MVPW;
float dx = (projected_coord.x()-projected_control.x());
float dy = (projected_coord.y()-projected_control.y());
@ -77,7 +62,6 @@ const float ImpostorSprite::calcPixelError(const Camera& camera,const Viewport&
return sqrtf(max_error_sqrd);
}
void ImpostorSprite::drawImmediateMode(State&)
{
// when the tex env is set to REPLACE, and the

View File

@ -227,7 +227,6 @@ void Matrix::postMult( const Matrix& other )
}
}
#undef SET_ROW
#undef INNER_PRODUCT
@ -310,24 +309,51 @@ bool Matrix::invert( const Matrix& mat )
return true;
}
bool Matrix::invertAffine( const Matrix& mat)
void Matrix::makeOrtho(const double left, const double right,
const double bottom, const double top,
const double zNear, const double zFar)
{
// | R p |' | R' -R'p |'
// | | -> | |
// | 0 0 0 1 | | 0 0 0 1 |
for (unsigned int i=0; i<3; i++)
{
operator()(i,3) = 0;
operator()(3,i) = -(mat(i,0)*mat(3,0) +
mat(i,1)*mat(3,1) +
mat(i,2)*mat(3,2));
for (unsigned int j=0; j<3; j++)
{
operator()(i,j) = mat(j,i);
}
}
operator()(3,3) = 1;
return true;
// note transpose of Matrix wr.t OpenGL documentation, since the OSG use post multiplication rather than pre.
double tx = -(right+left)/(right-left);
double ty = -(top+bottom)/(top-bottom);
double tz = -(zFar+zNear)/(zFar-zNear);
SET_ROW(0, 2.0f/(right-left), 0.0f, 0.0f, 0.0f )
SET_ROW(1, 0.0f, 2.0f/(top-bottom), 0.0f, 0.0f )
SET_ROW(2, 0.0f, 0.0f, -2.0f/(zFar-zNear), 0.0f )
SET_ROW(3, tx, ty, tz, 1.0f )
}
void Matrix::makeFrustum(const double left, const double right,
const double bottom, const double top,
const double zNear, const double zFar)
{
// note transpose of Matrix wr.t OpenGL documentation, since the OSG use post multiplication rather than pre.
double A = (right+left)/(right-left);
double B = (top+bottom)/(top-bottom);
double C = -(zFar+zNear)/(zFar-zNear);
double D = -2.0*zFar*zNear/(zFar-zNear);
SET_ROW(0, 2.0f*zNear/(right-left), 0.0f, 0.0f, 0.0f )
SET_ROW(1, 0.0f, 2.0f*zNear/(top-bottom), 0.0f, 0.0f )
SET_ROW(2, A, B, C, -1.0f )
SET_ROW(3, 0.0f, 0.0f, D, 0.0f )
}
void Matrix::makePerspective(const double fovy,const double aspectRatio,
const double zNear, const double zFar)
{
// calculate the appropriate left, right etc.
double tan_fovy = tan(DegreesToRadians(fovy*0.5));
double right = tan_fovy * aspectRatio * zNear;
double left = -right;
double top = tan_fovy * zNear;
double bottom = -top;
makeFrustum(left,right,bottom,top,zNear,zFar);
}
void Matrix::makeLookAt(const Vec3& eye,const Vec3& center,const Vec3& up)
{
}
#undef SET_ROW

View File

@ -1280,8 +1280,11 @@ void CullVisitor::apply(Impostor& node)
if (impostorSprite)
{
// impostor found, now check to see if it is good enough to use
float error = impostorSprite->calcPixelError(*_camera,*_viewport,matrix);
// RO, commenting this out since the calcPixelError's calling convention
// has changed, this version of CullVisitor is soon to be removed
// so this shouldn't be a problem.
//float error = impostorSprite->calcPixelError(*_camera,*_viewport,matrix);
float error = 0.0f;
if (error>_impostorPixelErrorThreshold)
{
// chosen impostor sprite pixel error is too great to use
@ -1403,9 +1406,10 @@ ImpostorSprite* CullVisitor::createImpostorSprite(Impostor& node)
// set up to charge the same RenderStageLighting is the parent previous stage.
rtts->setRenderStageLighting(previous_stage->getRenderStageLighting());
osg::Camera* camera = osgNew osg::Camera(*_camera);
rtts->setCamera(camera);
// temporarily commeted out to keep things compiling.
osg::Camera* camera = osgNew osg::Camera(*_camera);
// rtts->setCamera(camera);
std::cout<<"Warning:: in createImpostorSprite() rtts->setCamera(camera) call has been removed, this will cause problems."<<std::endl;
// record the render bin, to be restored after creation
// of the render to text

View File

@ -12,7 +12,7 @@ using namespace osgUtil;
InsertImpostorsVisitor::InsertImpostorsVisitor()
{
setTraversalMode(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN);
_impostorThresholdRatio = 10.0f;
_impostorThresholdRatio = 30.0f;
_maximumNumNestedImpostors = 3;
_numNestedImpostors = 0;
}

View File

@ -20,6 +20,8 @@
#include <float.h>
#include <algorithm>
#include <osg/Timer>
using namespace osg;
using namespace osgUtil;
@ -86,23 +88,14 @@ NewCullVisitor::NewCullVisitor()
// unless there is bug somewhere...
_cullingModeStack.push_back(CullViewState::ENABLE_ALL_CULLING);
_tvs = osgNew CullViewState;
_tvs->_eyePoint.set(0.0f,0.0f,1.0f);
_tvs->_centerPoint.set(0.0f,0.0f,0.0f);
_tvs->_lookVector.set(0.0f,0.0f,-1.0f);
_tvs->_upVector.set(0.0f,1.0f,0.0f);
_cvs = _tvs;
_tsm = LOOK_VECTOR_DISTANCE;
//_tsm = LOOK_VECTOR_DISTANCE;
_tsm = OBJECT_EYE_POINT_DISTANCE;
_calculated_znear = FLT_MAX;
_calculated_zfar = -FLT_MAX;
_viewport = NULL;
_impostorActive = true;
_depthSortImpostorSprites = false;
_impostorPixelErrorThreshold = 4.0f;
@ -124,20 +117,32 @@ void NewCullVisitor::reset()
//
// first unref all referenced objects and then empty the containers.
//
_viewStateStack.clear();
_projectionStack.clear();
_projectionClippingVolumeStack.clear();
_modelviewStack.clear();
_modelviewClippingVolumeStack.clear();
_viewportStack.clear();
_eyePointStack.clear();
// remove all accept the first element of the stack.
_cullingModeStack.erase(_cullingModeStack.begin()+1,_cullingModeStack.end());
if (_cvs!=_tvs)
{
_cvs = _tvs;
}
// reset the calculated near far planes.
_calculated_znear = FLT_MAX;
_calculated_zfar = -FLT_MAX;
// remove all accept the first element of the stack.
_cullingModeStack.erase(_cullingModeStack.begin()+1,_cullingModeStack.end());
osg::Vec3 lookVector(0.0,0.0,-1.0);
_bbCornerFar = (lookVector.x()>=0?1:0) |
(lookVector.y()>=0?2:0) |
(lookVector.z()>=0?4:0);
_bbCornerNear = (~_bbCornerFar)&7;
// reset the resuse lists.
_currentReuseMatrixIndex = 0;
@ -152,188 +157,105 @@ void NewCullVisitor::reset()
}
void NewCullVisitor::setCamera(const Camera& camera)
void NewCullVisitor::pushClippingVolume()
{
_camera = &camera;
_tvs->_clippingVolume.setToUnitFrustumWithoutNearFar();
_tvs->_clippingVolume.transformProvidingInverse(_camera->getModelViewMatrix()*_camera->getProjectionMatrix());
//_tvs->_clippingVolume = camera.getClippingVolume();
_tvs->_eyePoint = camera.getEyePoint_Model();
_tvs->_centerPoint = camera.getCenterPoint_Model();
_tvs->_lookVector = _tvs->_centerPoint-_tvs->_eyePoint;
_tvs->_lookVector.normalize();
_tvs->_upVector = camera.getUpVector_Model();
_tvs->_bbCornerFar = (_tvs->_lookVector.x()>=0?1:0) |
(_tvs->_lookVector.y()>=0?2:0) |
(_tvs->_lookVector.z()>=0?4:0);
_tvs->_bbCornerNear = (~_tvs->_bbCornerFar)&7;
_modelviewClippingVolumeStack.push_back(_projectionClippingVolumeStack.back());
if (!_modelviewStack.empty()) _modelviewClippingVolumeStack.back().transformProvidingInverse(*_modelviewStack.back());
_MVPW_Stack.push_back(0L);
}
void NewCullVisitor::pushCullViewState_Projection(Matrix* matrix)
void NewCullVisitor::popClippingVolume()
{
std::cout<<"NewCullVisitor::pushCullViewState_Projection(Matrix* matrix) not properly implemented yet..."<<std::endl;
pushCullViewState_ModelView(NULL,NULL);
_modelviewClippingVolumeStack.pop_back();
_MVPW_Stack.pop_back();
}
void NewCullVisitor::pushCullViewState_ModelView(Matrix* matrix)
void NewCullVisitor::pushViewport(osg::Viewport* viewport)
{
if (matrix)
{
osg::Matrix* inverse = osgNew osg::Matrix;
inverse->invert(*matrix);
pushCullViewState_ModelView(matrix,inverse);
}
else
pushCullViewState_ModelView(NULL,NULL);
_viewportStack.push_back(viewport);
_MVPW_Stack.push_back(0L);
}
void NewCullVisitor::pushCullViewState_ModelView(Matrix* matrix,osg::Matrix* inverse)
void NewCullVisitor::popViewport()
{
_viewportStack.pop_back();
_MVPW_Stack.pop_back();
}
osg::ref_ptr<CullViewState> nvs = osgNew CullViewState;
Matrix* inverse_world = NULL;
if (matrix)
{
if (_cvs.valid() && _cvs->_matrix.valid())
{
matrix->postMult(*(_cvs->_matrix));
}
nvs->_matrix = matrix;
}
else
{
if (_cvs.valid())
{
nvs->_matrix = _cvs->_matrix;
}
else
{
nvs->_matrix = NULL;
}
}
if (inverse)
{
if (_cvs.valid() && _cvs->_inverse.valid())
{
inverse->preMult(*(_cvs->_inverse));
}
nvs->_inverse = inverse;
}
else
{
if (_cvs.valid())
{
nvs->_inverse = _cvs->_inverse;
}
else
{
nvs->_inverse = NULL;
}
}
inverse_world = nvs->_inverse.get();
void NewCullVisitor::pushProjectionMatrix(Matrix* matrix)
{
_projectionStack.push_back(matrix);
if (inverse_world)
{
nvs->_eyePoint = _tvs->_eyePoint*(*inverse_world);
//nvs->_eyePoint = inverse_world->getTrans();
nvs->_centerPoint = _tvs->_centerPoint*(*inverse_world);
nvs->_lookVector = nvs->_centerPoint - nvs->_eyePoint;
nvs->_lookVector.normalize();
Vec3 zero_transformed = Vec3(0.0f,0.0f,0.0f)*(*inverse_world);
nvs->_upVector = (_tvs->_upVector)*(*inverse_world) - zero_transformed;
nvs->_upVector.normalize();
nvs->_clippingVolume = _tvs->_clippingVolume;
nvs->_clippingVolume.transformProvidingInverse(*(nvs->_matrix));
// osg::ClippingVolume cv;
// cv.setToUnitFrustum();
// cv.transformProvidingInverse((*(nvs->_matrix))*_camera->getProjectionMatrix());
//
// std::cout << "cv "<<std::endl;
// for(ClippingVolume::PlaneList::iterator itr = cv.getPlaneList().begin();
// itr!=cv.getPlaneList().end();
// ++itr)
// {
// std::cout << " Plane "<<*itr<<std::endl;
// }
//
// std::cout << "nvs->_clippingVolume "<<std::endl;
// for(ClippingVolume::PlaneList::iterator itr = nvs->_clippingVolume.getPlaneList().begin();
// itr!=nvs->_clippingVolume.getPlaneList().end();
// ++itr)
// {
// std::cout << " Plane "<<*itr<<std::endl;
// }
// std::cout << std::endl;
}
else
{
nvs->_eyePoint = _tvs->_eyePoint;
nvs->_lookVector = _tvs->_lookVector;
nvs->_centerPoint = _tvs->_centerPoint;
nvs->_upVector = _tvs->_upVector;
nvs->_clippingVolume = _tvs->_clippingVolume;
}
nvs->_bbCornerFar = (nvs->_lookVector.x()>=0?1:0) |
(nvs->_lookVector.y()>=0?2:0) |
(nvs->_lookVector.z()>=0?4:0);
nvs->_bbCornerNear = (~nvs->_bbCornerFar)&7;
_cvs = nvs;
_viewStateStack.push_back(nvs);
_projectionClippingVolumeStack.push_back(ClippingVolume());
_projectionClippingVolumeStack.back().setToUnitFrustumWithoutNearFar();
_projectionClippingVolumeStack.back().transformProvidingInverse(*matrix);
pushClippingVolume();
}
void NewCullVisitor::popCullViewState()
void NewCullVisitor::popProjectionMatrix()
{
// pop the top of the view stack and unref it.
_viewStateStack.pop_back();
// to new cvs and ref it.
if (_viewStateStack.empty())
{
_cvs = _tvs;
}
else
{
_cvs = _viewStateStack.back().get();
}
_projectionStack.pop_back();
_projectionClippingVolumeStack.pop_back();
popClippingVolume();
}
double NewCullVisitor::calculateZNear(const osg::Vec3& position, const osg::Vec3& eye, const osg::Vec3& look)
void NewCullVisitor::pushModelViewMatrix(Matrix* matrix)
{
//note: the candidate points are always in "global" coordinates
return (position - eye)*look;
_modelviewStack.push_back(matrix);
pushClippingVolume();
// fast method for computing the eye point in local coords which doesn't require the inverse matrix.
const float x_0 = (*matrix)(0,0);
const float x_1 = (*matrix)(1,0);
const float x_2 = (*matrix)(2,0);
const float x_scale = (*matrix)(3,0) / -(x_0*x_0+x_1*x_1+x_2*x_2);
const float y_0 = (*matrix)(0,1);
const float y_1 = (*matrix)(1,1);
const float y_2 = (*matrix)(2,1);
const float y_scale = (*matrix)(3,1) / -(y_0*y_0+y_1*y_1+y_2*y_2);
const float z_0 = (*matrix)(0,2);
const float z_1 = (*matrix)(1,2);
const float z_2 = (*matrix)(2,2);
const float z_scale = (*matrix)(3,2) / -(z_0*z_0+z_1*z_1+z_2*z_2);
_eyePointStack.push_back(osg::Vec3(x_0*x_scale + y_0*y_scale + z_0*z_scale,
x_1*x_scale + y_1*y_scale + z_1*z_scale,
x_2*x_scale + y_2*y_scale + z_2*z_scale));
osg::Vec3 lookVector = getLookVectorLocal();
_bbCornerFar = (lookVector.x()>=0?1:0) |
(lookVector.y()>=0?2:0) |
(lookVector.z()>=0?4:0);
_bbCornerNear = (~_bbCornerFar)&7;
}
void NewCullVisitor::popModelViewMatrix()
{
_modelviewStack.pop_back();
_eyePointStack.pop_back();
popClippingVolume();
osg::Vec3 lookVector(0.0f,0.0f,-1.0f);
if (!_modelviewStack.empty())
{
lookVector = getLookVectorLocal();
}
_bbCornerFar = (lookVector.x()>=0?1:0) |
(lookVector.y()>=0?2:0) |
(lookVector.z()>=0?4:0);
_bbCornerNear = (~_bbCornerFar)&7;
}
inline float distance(const osg::Vec3& coord,const osg::Matrix& matrix)
@ -352,18 +274,18 @@ void NewCullVisitor::updateCalculatedNearFar(const osg::BoundingBox& bb)
}
float d_near,d_far;
if (_cvs->_matrix.valid())
if (!_modelviewStack.empty())
{
const osg::Matrix& matrix = *(_cvs->_matrix);
d_near = distance(bb.corner(_cvs->_bbCornerNear),matrix);
d_far = distance(bb.corner(_cvs->_bbCornerFar),matrix);
const osg::Matrix& matrix = *(_modelviewStack.back());
d_near = distance(bb.corner(_bbCornerNear),matrix);
d_far = distance(bb.corner(_bbCornerFar),matrix);
}
else
{
d_near = -(bb.corner(_cvs->_bbCornerNear)).z();
d_far = -(bb.corner(_cvs->_bbCornerFar)).z();
d_near = -(bb.corner(_bbCornerNear)).z();
d_far = -(bb.corner(_bbCornerFar)).z();
}
if (d_near<=d_far)
@ -388,9 +310,9 @@ void NewCullVisitor::updateCalculatedNearFar(const osg::BoundingBox& bb)
void NewCullVisitor::updateCalculatedNearFar(const osg::Vec3& pos)
{
float d;
if (_cvs->_matrix.valid())
if (!_modelviewStack.empty())
{
const osg::Matrix& matrix = *(_cvs->_matrix);
const osg::Matrix& matrix = *(_modelviewStack.back());
d = distance(pos,matrix);
}
else
@ -487,14 +409,13 @@ void NewCullVisitor::apply(Geode& node)
{
center = drawable->getBound().center();
}
Vec3 delta_center = center-_tvs->_eyePoint;
float depth;
switch(_tsm)
{
case(LOOK_VECTOR_DISTANCE):depth = _tvs->_lookVector*delta_center;break;
case(LOOK_VECTOR_DISTANCE):depth = -center.z();break;
case(OBJECT_EYE_POINT_DISTANCE):
default: depth = delta_center.length2();break;
default: depth = center.length2();break;
}
if (stateset) pushStateSet(stateset);
@ -567,14 +488,13 @@ void NewCullVisitor::apply(Billboard& node)
{
center = pos;
}
Vec3 delta_center = center-_tvs->_eyePoint;
float depth;
switch(_tsm)
{
case(LOOK_VECTOR_DISTANCE):depth = _tvs->_lookVector*delta_center;break;
case(LOOK_VECTOR_DISTANCE):depth = -center.z();break;
case(OBJECT_EYE_POINT_DISTANCE):
default: depth = delta_center.length2();break;
default: depth = center.length2();break;
}
if (stateset) pushStateSet(stateset);
@ -657,14 +577,13 @@ void NewCullVisitor::apply(Transform& node)
if (node_state) pushStateSet(node_state);
ref_ptr<osg::Matrix> matrix = createOrReuseMatrix();
ref_ptr<osg::Matrix> inverse = createOrReuseMatrix();
node.getLocalToWorldMatrix(*matrix,this);
node.getWorldToLocalMatrix(*inverse,this);
pushCullViewState_ModelView(matrix.get(),inverse.get());
matrix->postMult(*getCurrentMatrix());
pushModelViewMatrix(matrix.get());
traverse(node);
popCullViewState();
popModelViewMatrix();
// pop the node's state off the render graph stack.
if (node_state) popStateSet();
@ -691,11 +610,11 @@ void NewCullVisitor::apply(Projection& node)
ref_ptr<osg::Matrix> matrix = createOrReuseMatrix();
*matrix = node.getMatrix();
pushCullViewState_Projection(matrix.get());
pushProjectionMatrix(matrix.get());
traverse(node);
popCullViewState();
popProjectionMatrix();
// pop the node's state off the render graph stack.
if (node_state) popStateSet();
@ -791,7 +710,7 @@ void NewCullVisitor::apply(Impostor& node)
// traverse the appropriate child of the LOD.
node.getChild(eval)->accept(*this);
}
else if (!_viewport.valid())
else if (_viewportStack.empty())
{
// need to use impostor but no valid viewport is defined to simply
// default to using the LOD child as above.
@ -799,6 +718,7 @@ void NewCullVisitor::apply(Impostor& node)
}
else
{
// within the impostor distance threshold therefore attempt
// to use impostor instead.
@ -810,8 +730,8 @@ void NewCullVisitor::apply(Impostor& node)
if (impostorSprite)
{
// impostor found, now check to see if it is good enough to use
float error = impostorSprite->calcPixelError(*_camera,*_viewport,matrix);
float error = impostorSprite->calcPixelError(getMVPW());
if (error>_impostorPixelErrorThreshold)
{
// chosen impostor sprite pixel error is too great to use
@ -853,14 +773,13 @@ void NewCullVisitor::apply(Impostor& node)
{
center = node.getCenter();
}
Vec3 delta_center = center-_tvs->_eyePoint;
float depth;
switch(_tsm)
{
case(LOOK_VECTOR_DISTANCE):depth = _tvs->_lookVector*delta_center;break;
case(LOOK_VECTOR_DISTANCE):depth = -center.z();break;
case(OBJECT_EYE_POINT_DISTANCE):
default: depth = delta_center.length2();break;
default: depth = center.length2();break;
}
addDrawableAndDepth(impostorSprite,matrix,depth);
@ -878,8 +797,8 @@ void NewCullVisitor::apply(Impostor& node)
}
else
{
// no impostor has been selected or created so default to
// traversing the usual LOD selected child.
// no impostor has been selected or created so default to
// traversing the usual LOD selected child.
node.getChild(eval)->accept(*this);
}
@ -894,10 +813,10 @@ void NewCullVisitor::apply(Impostor& node)
ImpostorSprite* NewCullVisitor::createImpostorSprite(Impostor& node)
{
if (!_camera.valid()) return NULL;
bool isPerspectiveCamera = _camera->getProjectionType()==Camera::FRUSTUM ||
_camera->getProjectionType()==Camera::PERSPECTIVE;
// default to true right now, will dertermine if perspective from the
// projection matrix...
bool isPerspectiveProjection = true;
Matrix* matrix = getCurrentMatrix();
const BoundingSphere& bs = node.getBound();
@ -906,11 +825,12 @@ ImpostorSprite* NewCullVisitor::createImpostorSprite(Impostor& node)
if (!bs.isValid())
{
cout << "bb invalid"<<&node<<endl;
return NULL;
}
Vec3 eye_world = _tvs->_eyePoint;
Vec3 eye_world(0.0,0.0,0.0);
Vec3 center_world = bs.center()*(*matrix);
// no appropriate sprite has been found therefore need to create
@ -929,13 +849,10 @@ ImpostorSprite* NewCullVisitor::createImpostorSprite(Impostor& node)
clear_color[3] = 0.0f; // set the alpha to zero.
rtts->setClearColor(clear_color);
rtts->setClearMask(previous_stage->getClearMask());
// set up to charge the same RenderStageLighting is the parent previous stage.
rtts->setRenderStageLighting(previous_stage->getRenderStageLighting());
osg::Camera* camera = osgNew osg::Camera(*_camera);
rtts->setCamera(camera);
// record the render bin, to be restored after creation
// of the render to text
@ -944,86 +861,10 @@ ImpostorSprite* NewCullVisitor::createImpostorSprite(Impostor& node)
// set the current renderbin to be the newly created stage.
_currentRenderBin = rtts.get();
// store the previous camera setting
Vec3 rotate_from = bs.center()-eye_local;
Vec3 rotate_to = getLookVectorLocal();
osg::Matrix* rotate_matrix = osgNew osg::Matrix(
osg::Matrix::translate(-eye_local)*
osg::Matrix::rotate(rotate_from,rotate_to)*
osg::Matrix::translate(eye_local));
// pushing the cull view state will update it so it takes
// into account the new camera orientation.
pushCullViewState_ModelView(rotate_matrix);
// what shall we do about the near far?
// we could need to save the near and far, or switch it off.
// simplicist to save near and far. will do this for now.
float previous_znear = _calculated_znear;
float previous_zfar = _calculated_zfar;
_calculated_znear = FLT_MAX;
_calculated_zfar = -FLT_MAX;
ref_ptr<StateSet> dummyState = osgNew StateSet;
// dummyState->setMode(GL_BLEND,osg::StateAttribute::OVERRIDE_OFF);
pushStateSet(dummyState.get());
// switch off the view frustum culling, since we will have
// the whole subgraph in view.
_cullingModeStack.push_back((_cullingModeStack.back() & ~CullViewState::VIEW_FRUSTUM_CULLING));
{
// traversing the usual LOD selected child.
node.getChild(eval)->accept(*this);
}
popStateSet();
// restore the culling mode.
_cullingModeStack.pop_back();
float local_znear = _calculated_znear;
float local_zfar = _calculated_zfar;
// restore the previous near and far.
_calculated_znear = previous_znear;
_calculated_zfar = previous_zfar;
// restor the previous renderbin.
_currentRenderBin = previousRenderBin;
// restore the previous _tvs and _cvs;
popCullViewState();
if (rtts->_renderGraphList.size()==0 && rtts->_bins.size()==0)
{
// getting to this point means that all the subgraph has been
// culled by small feature culling or is beyond LOD ranges.
return NULL;
}
if (local_znear>local_zfar)
{
notify(WARN) << "Warning : problem with osg::NewCullVisitor::creatImpostorSprite() local_znear ("<<local_znear<<") "<<" > ("<<local_zfar<<") local_zfar"<< std::endl;
return NULL;
}
// create texture quad coords (in local coords)
// create quad coords (in local coords)
Vec3 center_local = bs.center();
Vec3 camera_up_local = _cvs->_upVector;
Vec3 camera_up_local = getUpLocal();
Vec3 lv_local = center_local-eye_local;
float distance_local = lv_local.length();
@ -1037,7 +878,7 @@ ImpostorSprite* NewCullVisitor::createImpostorSprite(Impostor& node)
float width = bs.radius();
if (isPerspectiveCamera)
if (isPerspectiveProjection)
{
// expand the width to account for projection onto sprite.
width *= (distance_local/sqrtf(distance_local*distance_local-bs.radius2()));
@ -1055,55 +896,33 @@ ImpostorSprite* NewCullVisitor::createImpostorSprite(Impostor& node)
// adjust camera left,right,up,down to fit (in world coords)
#define USE_SPHERE_NEAR_FAR
#ifdef USE_SPHERE_NEAR_FAR
Vec3 near_local ( center_local-lv_local*width );
Vec3 far_local ( center_local+lv_local*width );
#endif
Vec3 top_local ( center_local+up_local);
Vec3 right_local ( center_local+sv_local);
#ifdef USE_SPHERE_NEAR_FAR
Vec3 near_world;
Vec3 far_world;
#endif
Vec3 top_world;
Vec3 right_world;
if (matrix)
{
#ifdef USE_SPHERE_NEAR_FAR
near_world = near_local * (*matrix);
far_world = far_local * (*matrix);
#endif
top_world = top_local * (*matrix);
right_world = right_local * (*matrix);
}
else
{
#ifdef USE_SPHERE_NEAR_FAR
near_world = near_local;
far_world = far_local;
#endif
top_world = top_local;
right_world = right_local;
}
#ifdef USE_SPHERE_NEAR_FAR
float znear = (near_world-eye_world).length();
float zfar = (far_world-eye_world).length();
#else
float znear = local_znear;
float zfar = local_zfar;
#endif
if (local_zfar>=local_znear)
{
znear = local_znear;
zfar = local_zfar;
}
float top = (top_world-center_world).length();
float right = (right_world-center_world).length();
@ -1111,62 +930,89 @@ ImpostorSprite* NewCullVisitor::createImpostorSprite(Impostor& node)
znear *= 0.9f;
zfar *= 1.1f;
if (isPerspectiveCamera)
// set up projection.
osg::Matrix* projection = osgNew osg::Matrix;
if (isPerspectiveProjection)
{
// deal with projection issue move the top and right points
// onto the near plane.
float ratio = znear/(center_world-eye_world).length();
float ratio = znear/(center_world-eye_world).length();
top *= ratio;
right *= ratio;
camera->setFrustum(-right,right,-top,top,znear,zfar);
projection->makeFrustum(-right,right,-top,top,znear,zfar);
}
else
{
// othographic projection.
camera->setOrtho(-right,right,-top,top,znear,zfar);
projection->makeOrtho(-right,right,-top,top,znear,zfar);
}
if (local_znear<znear)
pushProjectionMatrix(projection);
Vec3 rotate_from = bs.center()-eye_local;
Vec3 rotate_to = getLookVectorLocal();
osg::Matrix* rotate_matrix = osgNew osg::Matrix(
osg::Matrix::translate(-eye_local)*
osg::Matrix::rotate(rotate_from,rotate_to)*
osg::Matrix::translate(eye_local)*
getModelViewMatrix());
// pushing the cull view state will update it so it takes
// into account the new camera orientation.
pushModelViewMatrix(rotate_matrix);
ref_ptr<StateSet> dummyState = osgNew StateSet;
pushStateSet(dummyState.get());
// switch off the view frustum culling, since we will have
// the whole subgraph in view.
_cullingModeStack.push_back((_cullingModeStack.back() & ~CullViewState::VIEW_FRUSTUM_CULLING));
{
znear = local_znear;
// traversing the usual LOD selected child.
node.getChild(eval)->accept(*this);
}
if (local_zfar>zfar)
// restore the culling mode.
_cullingModeStack.pop_back();
popStateSet();
// restore the previous model view matrix.
popModelViewMatrix();
// restore the previous model view matrix.
popProjectionMatrix();
// restore the previous renderbin.
_currentRenderBin = previousRenderBin;
if (rtts->_renderGraphList.size()==0 && rtts->_bins.size()==0)
{
zfar = local_zfar;
// getting to this point means that all the subgraph has been
// culled by small feature culling or is beyond LOD ranges.
return NULL;
}
// restore the previous near and far.
local_znear = previous_znear;
local_zfar = previous_zfar;
// calc texture size for eye, bs.
Vec3 c00_world;
Vec3 c11_world;
if (matrix)
{
c00_world = c00 * (*matrix);
c11_world = c11 * (*matrix);
}
else
{
c00_world = c00;
c11_world = c11;
}
const osg::Viewport& viewport = *getViewport();
// calc texture size for eye, bs.
// convert the corners of the sprite (in world coords) into their
// equivilant window coordinates by using the camera's project method.
Vec3 c00_win;
Vec3 c11_win;
_camera->project(c00_world,*_viewport,c00_win);
_camera->project(c11_world,*_viewport,c11_win);
const osg::Matrix& MVPW = getMVPW();
Vec3 c00_win = c00 * MVPW;
Vec3 c11_win = c11 * MVPW;
// adjust texture size to be nearest power of 2.
@ -1193,21 +1039,21 @@ ImpostorSprite* NewCullVisitor::createImpostorSprite(Impostor& node)
int new_t = (int)(powf(2.0f,rounded_tp2));
// if dimension is bigger than window divide it down.
while (new_s>_viewport->width()) new_s /= 2;
while (new_s>viewport.width()) new_s /= 2;
// if dimension is bigger than window divide it down.
while (new_t>_viewport->height()) new_t /= 2;
while (new_t>viewport.height()) new_t /= 2;
// offset the impostor viewport from the center of the main window
// viewport as often the edges of the viewport might be obscured by
// other windows, which can cause image/reading writing problems.
int center_x = _viewport->x()+_viewport->width()/2;
int center_y = _viewport->y()+_viewport->height()/2;
int center_x = viewport.x()+viewport.width()/2;
int center_y = viewport.y()+viewport.height()/2;
Viewport* viewport = osgNew Viewport;
viewport->setViewport(center_x-new_s/2,center_y-new_t/2,new_s,new_t);
rtts->setViewport(viewport);
Viewport* new_viewport = osgNew Viewport;
new_viewport->setViewport(center_x-new_s/2,center_y-new_t/2,new_s,new_t);
rtts->setViewport(new_viewport);
// create the impostor sprite.
@ -1252,7 +1098,7 @@ ImpostorSprite* NewCullVisitor::createImpostorSprite(Impostor& node)
Vec3* controlcoords = impostorSprite->getControlCoords();
if (isPerspectiveCamera)
if (isPerspectiveProjection)
{
// deal with projection issue by moving the coorners of the quad
// towards the eye point.

View File

@ -30,7 +30,7 @@ void RenderLeaf::render(State& state,RenderLeaf* previous)
}
//state.applyProjectionMatrix(_projection.get());
state.applyProjectionMatrix(_projection.get());
state.applyModelViewMatrix(_modelview.get());
_drawable->draw(state);
@ -42,7 +42,7 @@ void RenderLeaf::render(State& state,RenderLeaf* previous)
// send state changes and matrix changes to OpenGL.
state.apply(_parent->_stateset.get());
//state.applyProjectionMatrix(_projection.get());
state.applyProjectionMatrix(_projection.get());
state.applyModelViewMatrix(_modelview.get());
_drawable->draw(state);

View File

@ -97,9 +97,6 @@ void RenderStage::draw(osg::State& state,RenderLeaf*& previous)
glDisable( GL_SCISSOR_TEST );
#endif
// set up projection
state.applyProjectionMatrix(&(_camera->getProjectionMatrix()));
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();

View File

@ -233,6 +233,7 @@ void SceneView::cullStage(osg::Camera* camera, osgUtil::CullVisitor* cullVisitor
}
// get the camera's modelview
osg::Matrix* projection = osgNew osg::Matrix(camera->getProjectionMatrix());
osg::Matrix* modelview = osgNew osg::Matrix(camera->getModelViewMatrix());
@ -243,8 +244,6 @@ void SceneView::cullStage(osg::Camera* camera, osgUtil::CullVisitor* cullVisitor
cullVisitor->setLODBias(_lodBias);
cullVisitor->setCamera(*local_camera);
cullVisitor->setViewport(_viewport.get());
cullVisitor->setEarthSky(NULL); // reset earth sky on each frame.
cullVisitor->setRenderGraph(rendergraph);
@ -266,7 +265,6 @@ void SceneView::cullStage(osg::Camera* camera, osgUtil::CullVisitor* cullVisitor
rendergraph->clean();
renderStage->setViewport(_viewport.get());
renderStage->setCamera(local_camera);
renderStage->setClearColor(_backgroundColor);
@ -285,7 +283,9 @@ void SceneView::cullStage(osg::Camera* camera, osgUtil::CullVisitor* cullVisitor
if (_globalState.valid()) cullVisitor->pushStateSet(_globalState.get());
cullVisitor->pushCullViewState_ModelView(modelview);
cullVisitor->pushViewport(_viewport.get());
cullVisitor->pushProjectionMatrix(projection);
cullVisitor->pushModelViewMatrix(modelview);
// traverse the scene graph to generate the rendergraph.
@ -293,7 +293,9 @@ void SceneView::cullStage(osg::Camera* camera, osgUtil::CullVisitor* cullVisitor
if (_globalState.valid()) cullVisitor->popStateSet();
cullVisitor->popCullViewState();
cullVisitor->popModelViewMatrix();
cullVisitor->popProjectionMatrix();
cullVisitor->popViewport();
const osg::EarthSky* earthSky = cullVisitor->getEarthSky();