Added support for releasing GLObjects, and renamed DisplayListVisitor the
GLObjectVisitor to better fit its function, and added support for releasing objects as well as compiling them.
This commit is contained in:
@@ -199,7 +199,7 @@ void Drawable::dirtyBound()
|
||||
}
|
||||
}
|
||||
|
||||
void Drawable::compile(State& state) const
|
||||
void Drawable::compileGLObjects(State& state) const
|
||||
{
|
||||
if (!_useDisplayList) return;
|
||||
|
||||
@@ -216,12 +216,6 @@ void Drawable::compile(State& state) const
|
||||
glDeleteLists( globj, 1 );
|
||||
}
|
||||
|
||||
|
||||
if (_stateset.valid())
|
||||
{
|
||||
_stateset->compile(state);
|
||||
}
|
||||
|
||||
globj = glGenLists( 1 );
|
||||
glNewList( globj, GL_COMPILE );
|
||||
|
||||
@@ -234,6 +228,32 @@ void Drawable::compile(State& state) const
|
||||
|
||||
}
|
||||
|
||||
void Drawable::releaseGLObjects(State* state) const
|
||||
{
|
||||
if (!_useDisplayList) return;
|
||||
|
||||
if (state)
|
||||
{
|
||||
// get the contextID (user defined ID of 0 upwards) for the
|
||||
// current OpenGL context.
|
||||
unsigned int contextID = state->getContextID();
|
||||
|
||||
// get the globj for the current contextID.
|
||||
GLuint& globj = _globjList[contextID];
|
||||
|
||||
// call the globj if already set otherwise comple and execute.
|
||||
if( globj != 0 )
|
||||
{
|
||||
glDeleteLists( globj, 1 );
|
||||
globj = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const_cast<Drawable*>(this)->dirtyDisplayList();
|
||||
}
|
||||
}
|
||||
|
||||
void Drawable::setSupportsDisplayList(bool flag)
|
||||
{
|
||||
// if value unchanged simply return.
|
||||
|
||||
@@ -177,6 +177,11 @@ void FragmentProgram::apply(State& state) const
|
||||
}
|
||||
}
|
||||
|
||||
void FragmentProgram::releaseGLObjects(State* state) const
|
||||
{
|
||||
const_cast<FragmentProgram*>(this)->dirtyFragmentProgramObject();
|
||||
}
|
||||
|
||||
|
||||
typedef buffered_value< ref_ptr<FragmentProgram::Extensions> > BufferedExtensions;
|
||||
static BufferedExtensions s_extensions;
|
||||
|
||||
@@ -190,6 +190,6 @@ void Geode::compileDrawables(State& state)
|
||||
itr!=_drawables.end();
|
||||
++itr)
|
||||
{
|
||||
(*itr)->compile(state);
|
||||
(*itr)->compileGLObjects(state);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -752,13 +752,13 @@ const StateSet::RefAttributePair* StateSet::getTextureAttributePair(unsigned int
|
||||
}
|
||||
|
||||
|
||||
void StateSet::compile(State& state) const
|
||||
void StateSet::compileGLObjects(State& state) const
|
||||
{
|
||||
for(AttributeList::const_iterator itr = _attributeList.begin();
|
||||
itr!=_attributeList.end();
|
||||
++itr)
|
||||
{
|
||||
itr->second.first->compile(state);
|
||||
itr->second.first->compileGLObjects(state);
|
||||
}
|
||||
|
||||
for(TextureAttributeList::const_iterator taitr=_textureAttributeList.begin();
|
||||
@@ -769,7 +769,29 @@ void StateSet::compile(State& state) const
|
||||
itr!=taitr->end();
|
||||
++itr)
|
||||
{
|
||||
itr->second.first->compile(state);
|
||||
itr->second.first->compileGLObjects(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StateSet::releaseGLObjects(State* state) const
|
||||
{
|
||||
for(AttributeList::const_iterator itr = _attributeList.begin();
|
||||
itr!=_attributeList.end();
|
||||
++itr)
|
||||
{
|
||||
itr->second.first->releaseGLObjects(state);
|
||||
}
|
||||
|
||||
for(TextureAttributeList::const_iterator taitr=_textureAttributeList.begin();
|
||||
taitr!=_textureAttributeList.end();
|
||||
++taitr)
|
||||
{
|
||||
for(AttributeList::const_iterator itr = taitr->begin();
|
||||
itr!=taitr->end();
|
||||
++itr)
|
||||
{
|
||||
itr->second.first->releaseGLObjects(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1046,11 +1046,15 @@ void Texture::applyTexImage2D_subload(State& state, GLenum target, const Image*
|
||||
#include <set>
|
||||
|
||||
|
||||
void Texture::compile(State& state) const
|
||||
void Texture::compileGLObjects(State& state) const
|
||||
{
|
||||
apply(state);
|
||||
}
|
||||
|
||||
void Texture::releaseGLObjects(State* state) const
|
||||
{
|
||||
const_cast<Texture*>(this)->dirtyTextureObject();
|
||||
}
|
||||
|
||||
typedef buffered_value< ref_ptr<Texture::Extensions> > BufferedExtensions;
|
||||
static BufferedExtensions s_extensions;
|
||||
|
||||
@@ -177,6 +177,11 @@ void VertexProgram::apply(State& state) const
|
||||
}
|
||||
}
|
||||
|
||||
void VertexProgram::releaseGLObjects(State* state) const
|
||||
{
|
||||
const_cast<VertexProgram*>(this)->dirtyVertexProgramObject();
|
||||
}
|
||||
|
||||
|
||||
typedef buffered_value< ref_ptr<VertexProgram::Extensions> > BufferedExtensions;
|
||||
static BufferedExtensions s_extensions;
|
||||
|
||||
@@ -28,6 +28,12 @@ DatabasePager::DatabasePager()
|
||||
_threadPriorityDuringFrame = PRIORITY_MIN;
|
||||
_threadPriorityOutwithFrame = PRIORITY_MIN;
|
||||
|
||||
_changeAutoUnRef = false;
|
||||
_valueAutoUnRef = false;
|
||||
_changeAnisotropy = false;
|
||||
_valueAnisotropy = 1.0f;
|
||||
|
||||
|
||||
#if 1
|
||||
_deleteRemovedSubgraphsInDatabaseThread = true;
|
||||
#else
|
||||
@@ -209,11 +215,13 @@ void DatabasePager::signalEndFrame()
|
||||
class FindCompileableGLObjectsVisitor : public osg::NodeVisitor
|
||||
{
|
||||
public:
|
||||
FindCompileableGLObjectsVisitor(DatabasePager::DataToCompile& dataToCompile, bool unrefImageOnApply, bool clientStorageHint):
|
||||
osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
|
||||
_dataToCompile(dataToCompile),
|
||||
_unrefImageOnApply(unrefImageOnApply),
|
||||
_clientStorageHint(clientStorageHint)
|
||||
FindCompileableGLObjectsVisitor(DatabasePager::DataToCompile& dataToCompile,
|
||||
bool changeAutoUnRef, bool valueAutoUnRef,
|
||||
bool changeAnisotropy, float valueAnisotropy):
|
||||
osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
|
||||
_dataToCompile(dataToCompile),
|
||||
_changeAutoUnRef(changeAutoUnRef), _valueAutoUnRef(valueAutoUnRef),
|
||||
_changeAnisotropy(changeAnisotropy), _valueAnisotropy(valueAnisotropy)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -247,8 +255,8 @@ public:
|
||||
osg::Texture* texture = dynamic_cast<osg::Texture*>(stateset->getTextureAttribute(i,osg::StateAttribute::TEXTURE));
|
||||
if (texture)
|
||||
{
|
||||
texture->setUnRefImageDataAfterApply(_unrefImageOnApply);
|
||||
//texture->setClientStorageHint(_clientStorageHint);
|
||||
if (_changeAutoUnRef) texture->setUnRefImageDataAfterApply(_valueAutoUnRef);
|
||||
if (_changeAnisotropy) texture->setMaxAnisotropy(_valueAnisotropy);
|
||||
foundTextureState = true;
|
||||
}
|
||||
}
|
||||
@@ -274,8 +282,10 @@ public:
|
||||
}
|
||||
|
||||
DatabasePager::DataToCompile& _dataToCompile;
|
||||
bool _unrefImageOnApply;
|
||||
bool _clientStorageHint;
|
||||
bool _changeAutoUnRef;
|
||||
bool _valueAutoUnRef;
|
||||
bool _changeAnisotropy;
|
||||
float _valueAnisotropy;
|
||||
};
|
||||
|
||||
|
||||
@@ -367,7 +377,10 @@ void DatabasePager::run()
|
||||
++itr;
|
||||
|
||||
// find all the compileable rendering objects
|
||||
FindCompileableGLObjectsVisitor frov(dtc, true, true);
|
||||
FindCompileableGLObjectsVisitor frov(dtc,
|
||||
_changeAutoUnRef, _valueAutoUnRef,
|
||||
_changeAnisotropy, _valueAnisotropy);
|
||||
|
||||
databaseRequest->_loadedModel->accept(frov);
|
||||
|
||||
if (!dtc.first.empty() || !dtc.second.empty())
|
||||
@@ -499,7 +512,7 @@ public:
|
||||
if ((*titr)->referenceCount()==1)
|
||||
{
|
||||
osg::Texture* texture = const_cast<osg::Texture*>(titr->get());
|
||||
texture->dirtyTextureObject();
|
||||
texture->releaseGLObjects();
|
||||
objectsToDelete.push_back(texture);
|
||||
}
|
||||
}
|
||||
@@ -511,7 +524,7 @@ public:
|
||||
if ((*ditr)->referenceCount()==1)
|
||||
{
|
||||
osg::Drawable* drawable = const_cast<osg::Drawable*>(ditr->get());
|
||||
drawable->dirtyDisplayList();
|
||||
drawable->releaseGLObjects();
|
||||
objectsToDelete.push_back(drawable);
|
||||
}
|
||||
}
|
||||
@@ -725,7 +738,7 @@ void DatabasePager::compileGLObjects(osg::State& state, double& availableTime)
|
||||
++itr)
|
||||
{
|
||||
//osg::notify(osg::INFO)<<" Compiling stateset "<<(*itr).get()<<std::endl;
|
||||
(*itr)->compile(state);
|
||||
(*itr)->compileGLObjects(state);
|
||||
elapsedTime = timer.delta_s(start_tick,timer.tick());
|
||||
}
|
||||
// remove the compiled stateset from the list.
|
||||
@@ -742,7 +755,7 @@ void DatabasePager::compileGLObjects(osg::State& state, double& availableTime)
|
||||
++itr)
|
||||
{
|
||||
//osg::notify(osg::INFO)<<" Compiling drawable "<<(*itr).get()<<std::endl;
|
||||
(*itr)->compile(state);
|
||||
(*itr)->compileGLObjects(state);
|
||||
elapsedTime = timer.delta_s(start_tick,timer.tick());
|
||||
}
|
||||
// remove the compiled drawables from the list.
|
||||
|
||||
@@ -183,6 +183,11 @@ void ProgramObject::dirtyShaderObjects()
|
||||
}
|
||||
}
|
||||
|
||||
void ProgramObject::releaseGLObjects(osg::State* state) const
|
||||
{
|
||||
const_cast<ProgramObject*>(this)->dirtyShaderObjects();
|
||||
}
|
||||
|
||||
|
||||
void ProgramObject::addShader( ShaderObject* shadObj )
|
||||
{
|
||||
|
||||
@@ -10,13 +10,13 @@
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
#include <osgUtil/DisplayListVisitor>
|
||||
#include <osgUtil/GLObjectsVisitor>
|
||||
#include <osg/Drawable>
|
||||
|
||||
using namespace osg;
|
||||
using namespace osgUtil;
|
||||
|
||||
DisplayListVisitor::DisplayListVisitor(Mode mode)
|
||||
GLObjectsVisitor::GLObjectsVisitor(Mode mode)
|
||||
{
|
||||
setTraversalMode(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN);
|
||||
|
||||
@@ -26,55 +26,68 @@ DisplayListVisitor::DisplayListVisitor(Mode mode)
|
||||
}
|
||||
|
||||
|
||||
void DisplayListVisitor::apply(osg::Node& node)
|
||||
void GLObjectsVisitor::apply(osg::Node& node)
|
||||
{
|
||||
if ((_mode&COMPILE_STATE_ATTRIBUTES) && node.getStateSet() && _state.valid())
|
||||
if (node.getStateSet())
|
||||
{
|
||||
node.getStateSet()->compile(*_state);
|
||||
apply(*(node.getStateSet()));
|
||||
}
|
||||
|
||||
traverse(node);
|
||||
}
|
||||
|
||||
void DisplayListVisitor::apply(osg::Geode& node)
|
||||
void GLObjectsVisitor::apply(osg::Geode& node)
|
||||
{
|
||||
if (_mode&COMPILE_STATE_ATTRIBUTES && _state.valid())
|
||||
if (node.getStateSet())
|
||||
{
|
||||
if (node.getStateSet())
|
||||
{
|
||||
node.getStateSet()->compile(*_state);
|
||||
}
|
||||
apply(*(node.getStateSet()));
|
||||
}
|
||||
|
||||
for(unsigned int i=0;i<node.getNumDrawables();++i)
|
||||
for(unsigned int i=0;i<node.getNumDrawables();++i)
|
||||
{
|
||||
Drawable* drawable = node.getDrawable(i);
|
||||
if (drawable)
|
||||
{
|
||||
Drawable* drawable = node.getDrawable(i);
|
||||
apply(*drawable);
|
||||
if (drawable->getStateSet())
|
||||
{
|
||||
drawable->getStateSet()->compile(*_state);
|
||||
apply(*(drawable->getStateSet()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GLObjectsVisitor::apply(osg::Drawable& drawable)
|
||||
{
|
||||
if (_mode&SWITCH_OFF_DISPLAY_LISTS)
|
||||
{
|
||||
for(unsigned int i=0;i<node.getNumDrawables();++i)
|
||||
{
|
||||
node.getDrawable(i)->setUseDisplayList(false);
|
||||
}
|
||||
drawable.setUseDisplayList(false);
|
||||
}
|
||||
|
||||
if (_mode&SWITCH_ON_DISPLAY_LISTS)
|
||||
{
|
||||
for(unsigned int i=0;i<node.getNumDrawables();++i)
|
||||
{
|
||||
node.getDrawable(i)->setUseDisplayList(true);
|
||||
}
|
||||
drawable.setUseDisplayList(true);
|
||||
}
|
||||
|
||||
if (_mode&COMPILE_DISPLAY_LISTS && _state.valid())
|
||||
{
|
||||
for(unsigned int i=0;i<node.getNumDrawables();++i)
|
||||
{
|
||||
node.getDrawable(i)->compile(*_state);
|
||||
}
|
||||
drawable.compileGLObjects(*_state);
|
||||
}
|
||||
|
||||
if (_mode&RELEASE_DISPLAY_LISTS)
|
||||
{
|
||||
drawable.releaseGLObjects(_state.get());
|
||||
}
|
||||
}
|
||||
|
||||
void GLObjectsVisitor::apply(osg::StateSet& stateset)
|
||||
{
|
||||
if (_mode&COMPILE_STATE_ATTRIBUTES && _state.valid())
|
||||
{
|
||||
stateset.compileGLObjects(*_state);
|
||||
}
|
||||
if (_mode&RELEASE_STATE_ATTRIBUTES)
|
||||
{
|
||||
stateset.releaseGLObjects(_state.get());
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ CXXFILES = \
|
||||
CubeMapGenerator.cpp\
|
||||
CullVisitor.cpp\
|
||||
DelaunayTriangulator.cpp\
|
||||
DisplayListVisitor.cpp\
|
||||
GLObjectsVisitor.cpp\
|
||||
DisplayRequirementsVisitor.cpp\
|
||||
HalfWayMapGenerator.cpp\
|
||||
HighlightMapGenerator.cpp\
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
*/
|
||||
#include <osgUtil/SceneView>
|
||||
#include <osgUtil/UpdateVisitor>
|
||||
#include <osgUtil/DisplayListVisitor>
|
||||
#include <osgUtil/GLObjectsVisitor>
|
||||
|
||||
#include <osg/Timer>
|
||||
#include <osg/Notify>
|
||||
@@ -82,17 +82,17 @@ void SceneView::setDefaults()
|
||||
_renderStage = new RenderStage;
|
||||
|
||||
|
||||
DisplayListVisitor::Mode dlvMode = DisplayListVisitor::COMPILE_DISPLAY_LISTS|DisplayListVisitor::COMPILE_STATE_ATTRIBUTES;
|
||||
GLObjectsVisitor::Mode dlvMode = GLObjectsVisitor::COMPILE_DISPLAY_LISTS|GLObjectsVisitor::COMPILE_STATE_ATTRIBUTES;
|
||||
|
||||
#ifdef __sgi
|
||||
dlvMode = DisplayListVisitor::COMPILE_STATE_ATTRIBUTES;
|
||||
dlvMode = GLObjectsVisitor::COMPILE_STATE_ATTRIBUTES;
|
||||
#endif
|
||||
|
||||
// sgi's IR graphics has a problem with lighting and display lists, as it seems to store
|
||||
// lighting state with the display list, and the display list visitor doesn't currently apply
|
||||
// state before creating display lists. So will disable the init visitor default, this won't
|
||||
// affect functionality since the display lists will be created as and when needed.
|
||||
DisplayListVisitor* dlv = new DisplayListVisitor(dlvMode);
|
||||
GLObjectsVisitor* dlv = new GLObjectsVisitor(dlvMode);
|
||||
dlv->setNodeMaskOverride(0xffffffff);
|
||||
_initVisitor = dlv;
|
||||
|
||||
@@ -139,7 +139,7 @@ void SceneView::init()
|
||||
_initVisitor->reset();
|
||||
_initVisitor->setFrameStamp(_frameStamp.get());
|
||||
|
||||
DisplayListVisitor* dlv = dynamic_cast<DisplayListVisitor*>(_initVisitor.get());
|
||||
GLObjectsVisitor* dlv = dynamic_cast<GLObjectsVisitor*>(_initVisitor.get());
|
||||
if (dlv) dlv->setState(_state.get());
|
||||
|
||||
if (_frameStamp.valid())
|
||||
|
||||
Reference in New Issue
Block a user