Move the applying of Projection and ModelView matrices into osg::State so that

it now maintains references to the last applied matrices, automatically doing
lazy state updating.  This simplifies the various places in the OSG which
were previously doing the applying, add paves the way for managing the
projection matrix within the scene graph.

Remove MemoryAdapter and mem_ptr as they arn't being used, and can potentially
confuse users by their existance.
This commit is contained in:
Robert Osfield
2002-03-29 17:26:40 +00:00
parent 07f9421f39
commit 56cee8c711
13 changed files with 92 additions and 335 deletions

View File

@@ -1,41 +0,0 @@
//C++ header - Open Scene Graph - Copyright (C) 1998-2001 Robert Osfield
//Distributed under the terms of the GNU Library General Public License (LGPL)
//as published by the Free Software Foundation.
#ifndef OSG_MEMORYADAPTER
#define OSG_MEMORYADAPTER 1
#include <osg/Referenced>
namespace osg {
/** Class for adapting the memory management of external data.
* Typically used to specify the memory management of user data
* which can be attached to osg::Node.
*/
class SG_EXPORT MemoryAdapter : public Referenced
{
public:
MemoryAdapter() {}
/** Increment the reference count of the userData.*/
virtual void ref_data(void* /*userData*/) = 0;
/** Decrement the reference count of the userData.
Is usually implemented such that if reference count
is decremented to zero the userData should be
deleted. However, this is entirely up to the
discretion of the user who is extending this base class.*/
virtual void unref_data(void* /*userData*/) = 0;
/** not current used, but will be used in future.*/
virtual void* clone_data(void* /*userData*/) { return 0L; }
protected:
virtual ~MemoryAdapter() {}
};
}
#endif

View File

@@ -67,6 +67,55 @@ class SG_EXPORT State : public Referenced
return applyAttribute(attribute,_attributeMap[attribute->getType()]);
}
inline void applyProjectionMatrix(const osg::Matrix* matrix)
{
if (_projection!=matrix)
{
glMatrixMode( GL_PROJECTION );
if (matrix)
{
_projection=matrix;
glLoadMatrixf(matrix->ptr());
}
else
{
_projection=_identity;
glLoadIdentity();
}
glMatrixMode( GL_MODELVIEW );
}
}
const osg::Matrix& getProjectionMatrix() const
{
return *_projection;
}
inline void applyModelViewMatrix(const osg::Matrix* matrix)
{
if (_modelView!=matrix)
{
if (matrix)
{
_modelView=matrix;
glLoadMatrixf(matrix->ptr());
}
else
{
_modelView=_identity;
glLoadIdentity();
}
}
}
const osg::Matrix& getModelViewMatrix() const
{
return *_modelView;
}
ClippingVolume getClippingVolume() const;
/** apply stateset.*/
void apply(const StateSet* dstate);
@@ -112,15 +161,7 @@ class SG_EXPORT State : public Referenced
/** Set the frame stamp for the current frame.*/
inline const FrameStamp* getFrameStamp() const { return _frameStamp.get(); }
/** Set the camera. Note, nothing is applied, the camera is just used
* used in the State object to pass the current camera to Drawables
* during rendering. */
inline void setCamera(Camera* camera) { _camera = camera; }
/** Get the camera */
inline const Camera* getCamera() const { return _camera.get(); }
/** Set the DisplaySettings. Note, nothing is applied, the visual settings are just used
* used in the State object to pass the current visual settings to Drawables
* during rendering. */
@@ -138,7 +179,11 @@ class SG_EXPORT State : public Referenced
unsigned int _contextID;
ref_ptr<FrameStamp> _frameStamp;
ref_ptr<Camera> _camera;
ref_ptr<const Matrix> _identity;
ref_ptr<const Matrix> _projection;
ref_ptr<const Matrix> _modelView;
ref_ptr<DisplaySettings> _displaySettings;

View File

@@ -104,6 +104,8 @@ class SG_EXPORT StateAttribute : public Object
TEXTURE_2,
TEXTURE_3,
POLYGONMODE,
POLYGONOFFSET,
MATERIAL,
ALPHAFUNC,
ANTIALIAS,
@@ -126,8 +128,6 @@ class SG_EXPORT StateAttribute : public Object
LINEWIDTH,
LINESTIPPLE,
SHADEMODEL,
POLYGONMODE,
POLYGONOFFSET,
TEXENV,
TEXGEN,
TEXMAT,

View File

@@ -370,7 +370,7 @@ class SG_EXPORT Texture : public StateAttribute
Vec4 _borderColor;
// subloaded images can have different texture and image sizes.
mutable unsigned int _textureWidth, _textureHeight;
mutable GLsizei _textureWidth, _textureHeight;
SubloadMode _subloadMode;
GLint _subloadOffsX, _subloadOffsY;

View File

@@ -1,206 +0,0 @@
//C++ header - Open Scene Graph - Copyright (C) 1998-2001 Robert Osfield
//Distributed under the terms of the GNU Library General Public License (LGPL)
//as published by the Free Software Foundation.
#ifndef OSG_MEM_PTR
#define OSG_MEM_PTR 1
#include <osg/ref_ptr>
#include <osg/MemoryAdapter>
#include <map>
namespace osg {
/** Smart pointer for handling memory pointers via associated memory adapter.*/
template<class T>
class mem_ptr
{
public:
mem_ptr() :_ptr(0L),_ma(0L) {}
mem_ptr(T* t,MemoryAdapter* ma):_ptr(t),_ma(ma)
{
if (_ptr && _ma.valid()) _ma->ref_data(_ptr);
}
mem_ptr(const mem_ptr& rp):_ptr(rp._ptr),_ma(rp._ma)
{
if (_ptr && _ma.valid()) _ma->unref_data(_ptr);
}
~mem_ptr()
{
if (_ptr && _ma.valid()) _ma->ref_data(_ptr);
}
inline mem_ptr& operator = (const mem_ptr& rp)
{
if (_ptr==rp._ptr) return *this;
if (_ptr && _ma.valid()) _ma->unref_data(_ptr);
_ptr = rp._ptr;
_ma = rp._ma;
if (_ptr && _ma.valid()) _ma->ref_data(_ptr);
return *this;
}
inline void set(T* t,MemoryAdapter* ma)
{
if (_ptr==t)
{
if (_ma==ma) return;
if (ma)
{
ma->ref(_ptr);
if (_ma.valid()) _ma->unref_data(_ptr);
}
_ma = ma;
}
else
{
if (_ptr && _ma.valid()) _ma->unref_data(_ptr);
_ptr = t;
_ma = rp._ma;
if (_ptr && _ma.valid()) _ma->ref_data(_ptr);
}
}
inline const bool operator == (const mem_ptr& rp) const
{
return (_ptr==rp._ptr);
}
inline const bool operator == (const T* ptr) const
{
return (_ptr==ptr);
}
inline const bool operator != (const mem_ptr& rp) const
{
return (_ptr!=rp._ptr);
}
inline const bool operator != (const T* ptr) const
{
return (_ptr!=ptr);
}
inline T& operator*() { return *_ptr; }
inline const T& operator*() const { return *_ptr; }
inline T* operator->() { return _ptr; }
inline const T* operator->() const { return _ptr; }
inline const bool operator!() const { return _ptr==0L; }
inline const bool valid() const { return _ptr!=0L; }
inline T* get() { return _ptr; }
inline const T* get() const { return _ptr; }
private:
T* _ptr;
ref_ptr<MemoryAdapter> _ma;
};
// /** Experimental memory adapter implementation.*/
// template<class T>
// class CppMemoryAdapter : public MemoryAdapter
// {
// public:
//
// virtual void ref_data(void* userData)
// {
// ++_memoryMap[(T*)userData];
// }
//
// virtual void unref_data(void* userData)
// {
// --_memoryMap[(T*)userData];
// if (_memoryMap[(T*)userData]<=0) delete userData;
// _memoryMap.erase((T*)userData);
// }
//
// protected:
//
// static std::map<T*,int> _memoryMap;
//
// };
//
// /** Experimental memory adapter implementation.*/
// class NewMemoryAdapter : public MemoryAdapter
// {
// public:
//
// static MemoryAdapter* instance();
//
// virtual void ref_data(void* userData)
// {
// ++_memoryMap[userData];
// }
//
// virtual void unref_data(void* userData)
// {
// --_memoryMap[userData];
// if (_memoryMap[userData]<=0) delete userData;
// _memoryMap.erase(userData);
// }
//
// protected:
//
// NewMemoryAdapter() {}
// NewMemoryAdapter(NewMemoryAdapter&):MemoryAdapter() {}
// ~NewMemoryAdapter() {}
//
// std::map<void*,int> _memoryMap;
//
// };
//
// /** Experimental memory adapter implementation.*/
// template<class T>
// class newMemoryAdapter : public MemoryAdapter
// {
// public:
//
// static newMemoryAdapter<T>* instance()
// {
// static ref_ptr<newMemoryAdapter<T> > s_newMemoryAdapter = new newMemoryAdapter<T>();
// return s_newMemoryAdapter.get();
// }
//
// T* allocate(int no) { cout<<"Allocating Memory"<<endl;return osgNew T[no]; }
//
// virtual void ref_data(void* userData)
// {
// cout<<"Incrementing Memory"<<endl;
// ++_memoryMap[(T*)userData];
// }
//
// virtual void unref_data(void* userData)
// {
// cout<<"Decrementing Memory"<<endl;
// --_memoryMap[(T*)userData];
// if (_memoryMap[(T*)userData]<=0)
// {
// cout<<"Deleting Memory"<<endl;
// delete (T*)userData;
// }
// _memoryMap.erase((T*)userData);
// }
//
// protected:
//
// newMemoryAdapter() {cout<<"*** Constructing nMA"<<endl;}
// newMemoryAdapter(newMemoryAdapter&):MemoryAdapter() {}
// ~newMemoryAdapter() {cout<<"*** Destructing nMA"<<endl;}
//
// std::map<T*,int> _memoryMap;
//
// };
}
#endif

View File

@@ -856,15 +856,6 @@ void Camera::adjustEyeOffsetForStereo(const osg::Vec3& offset)
void Camera::apply(State& state)
{
const Matrix& projectionMat = getProjectionMatrix();
glMatrixMode( GL_PROJECTION );
glLoadMatrixf(projectionMat.ptr());
// set up camera modelview.
const Matrix& modelView = getModelViewMatrix();
glMatrixMode( GL_MODELVIEW );
glLoadMatrixf(modelView.ptr());
state.setCamera(this);
state.applyProjectionMatrix(&getProjectionMatrix());
state.applyModelViewMatrix(&getModelViewMatrix());
}

View File

@@ -111,7 +111,6 @@ TARGET_INCLUDE_FILES = \
osg/Material\
osg/Math\
osg/Matrix\
osg/MemoryAdapter\
osg/MemoryManager\
osg/Node\
osg/NodeCallback\
@@ -145,7 +144,6 @@ TARGET_INCLUDE_FILES = \
osg/Vec4\
osg/Version\
osg/Viewport\
osg/mem_ptr\
osg/ref_ptr\

View File

@@ -8,6 +8,9 @@ using namespace osg;
State::State()
{
_contextID = 0;
_identity = new osg::Matrix(); // default Matrix constructs to identity.
_modelView = _identity;
_projection = _identity;
}
State::~State()
@@ -45,6 +48,9 @@ void State::reset()
// _attributeMap.clear();
_drawStateStack.clear();
_modelView = _identity;
_projection = _identity;
}
void State::pushStateSet(const StateSet* dstate)

View File

@@ -462,11 +462,11 @@ void Texture::applyTexImage(GLenum target, Image* image, State& state) const
// calculate texture dimension
_textureWidth = 1;
for (; _textureWidth < (_subloadOffsX + width); _textureWidth <<= 1)
for (; _textureWidth < (static_cast<GLsizei>(_subloadOffsX) + width); _textureWidth <<= 1)
;
_textureHeight = 1;
for (; _textureHeight < (_subloadOffsY + height); _textureHeight <<= 1)
for (; _textureHeight < (static_cast<GLsizei>(_subloadOffsY) + height); _textureHeight <<= 1)
;
// reserve appropriate texture memory

View File

@@ -30,20 +30,7 @@ void RenderLeaf::render(State& state,RenderLeaf* previous)
}
Matrix* prev_matrix = previous->_matrix.get();
if (_matrix != prev_matrix)
{
if (_matrix.valid())
{
glLoadMatrixf(_matrix->ptr());
}
else
{
glLoadIdentity();
}
}
state.applyModelViewMatrix(_matrix.get());
_drawable->draw(state);
}
@@ -54,14 +41,7 @@ void RenderLeaf::render(State& state,RenderLeaf* previous)
// send state changes and matrix changes to OpenGL.
state.apply(_parent->_stateset.get());
if (_matrix.valid())
{
glLoadMatrixf(_matrix->ptr());
}
else
{
glLoadIdentity();
}
state.applyModelViewMatrix(_matrix.get());
_drawable->draw(state);
}

View File

@@ -96,14 +96,8 @@ void RenderStage::draw(osg::State& state,RenderLeaf*& previous)
glDisable( GL_SCISSOR_TEST );
#endif
// pass the camera we're about to set up to state, so that
// subsequent operatiosn know about it, such as for CLOD etc.
state.setCamera(_camera.get());
// set up projection
const Matrix& projectionMat = _camera->getProjectionMatrix();
glMatrixMode( GL_PROJECTION );
glLoadMatrixf(projectionMat.ptr());
state.applyProjectionMatrix(&(_camera->getProjectionMatrix()));
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();

View File

@@ -29,27 +29,12 @@ void RenderStageLighting::draw(osg::State& state,RenderLeaf*& previous)
previous = NULL;
}
Matrix* prev_matrix = NULL;
// apply the light list.
for(LightList::iterator litr=_lightList.begin();
litr!=_lightList.end();
++litr)
{
Matrix* matrix = (*litr).second.get();
if (matrix != prev_matrix)
{
if (matrix)
{
glLoadMatrixf(matrix->ptr());
}
else
{
glLoadIdentity();
}
prev_matrix = matrix;
}
state.applyModelViewMatrix((*litr).second.get());
// apply the light source.
litr->first->apply(state);

View File

@@ -158,6 +158,9 @@ void SceneView::app()
void SceneView::cull()
{
_state->reset();
if (_displaySettings.valid() && _displaySettings->getStereo())
{
@@ -201,9 +204,23 @@ void SceneView::cullStage(osg::Camera* camera, osgUtil::CullVisitor* cullVisitor
if (!_initCalled) init();
if (!_state)
{
osg::notify(osg::WARN) << "Warning: no valid osgUtil::SceneView::_state"<< std::endl;
osg::notify(osg::WARN) << " creating a state automatically."<< std::endl;
// note the constructor for osg::State will set ContextID to 0.
_state = osgNew osg::State;
}
// we in theory should be able to be able to bypass reset, but we'll call it just incase.
_state->reset();
_state->setFrameStamp(_frameStamp.get());
_state->setDisplaySettings(_displaySettings.get());
camera->adjustAspectRatio(_viewport->aspectRatio());
cullVisitor->reset();
@@ -343,6 +360,7 @@ void SceneView::cullStage(osg::Camera* camera, osgUtil::CullVisitor* cullVisitor
void SceneView::draw()
{
if (_displaySettings.valid() && _displaySettings->getStereo())
{
@@ -442,19 +460,6 @@ void SceneView::drawStage(osgUtil::RenderStage* renderStage)
{
if (!_sceneData || !_viewport->valid()) return;
if (!_state)
{
osg::notify(osg::WARN) << "Warning: no valid osgUtil::SceneView::_state"<< std::endl;
osg::notify(osg::WARN) << " creating a state automatically."<< std::endl;
// note the constructor for osg::State will set ContextID to 0.
_state = osgNew osg::State;
}
// we in theory should be able to
_state->reset();
_state->setFrameStamp(_frameStamp.get());
_state->setDisplaySettings(_displaySettings.get());
// note, to support multi-pipe systems the deletion of OpenGL display list
// and texture objects is deferred until the OpenGL context is the correct