625 lines
22 KiB
C++
625 lines
22 KiB
C++
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
|
|
*
|
|
* This library is open source and may be redistributed and/or modified under
|
|
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
|
* (at your option) any later version. The full license is in LICENSE file
|
|
* included with this distribution, and on the openscenegraph.org website.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* OpenSceneGraph Public License for more details.
|
|
*/
|
|
|
|
#include <osg/VertexArrayState>
|
|
#include <osg/State>
|
|
|
|
using namespace osg;
|
|
|
|
#define VAS_NOTICE OSG_INFO
|
|
//#define VAS_NOTICE OSG_NOTICE
|
|
|
|
#ifdef OSG_GL_VERTEX_ARRAY_FUNCS_AVAILABLE
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// VertexArrayDispatch
|
|
//
|
|
struct VertexArrayDispatch : public VertexArrayState::ArrayDispatch
|
|
{
|
|
VertexArrayDispatch() {}
|
|
|
|
virtual void enable_and_dispatch(osg::State&, const osg::Array* new_array)
|
|
{
|
|
VAS_NOTICE<<" VertexArrayDispatch::enable_and_dispatch("<<new_array->getNumElements()<<")"<<std::endl;
|
|
glEnableClientState(GL_VERTEX_ARRAY);
|
|
glVertexPointer(new_array->getDataSize(), new_array->getDataType(), 0, new_array->getDataPointer());
|
|
}
|
|
|
|
virtual void enable_and_dispatch(osg::State&, const osg::Array* new_array, const osg::GLBufferObject* vbo)
|
|
{
|
|
VAS_NOTICE<<" VertexArrayDispatch::enable_and_dispatch("<<new_array->getNumElements()<<", vbo="<<vbo<<")"<<std::endl;
|
|
glEnableClientState(GL_VERTEX_ARRAY);
|
|
glVertexPointer(new_array->getDataSize(), new_array->getDataType(), 0, (const GLvoid *)(vbo->getOffset(new_array->getBufferIndex())));
|
|
}
|
|
|
|
virtual void dispatch(osg::State& state, const osg::Array* new_array)
|
|
{
|
|
VAS_NOTICE<<" VertexArrayDispatch::dispatch("<<new_array->getNumElements()<<")"<<std::endl;
|
|
glVertexPointer(new_array->getDataSize(), new_array->getDataType(), 0, new_array->getDataPointer());
|
|
}
|
|
|
|
virtual void dispatch(osg::State& state, const osg::Array* new_array, const osg::GLBufferObject* vbo)
|
|
{
|
|
VAS_NOTICE<<" VertexArrayDispatch::dispatch("<<new_array->getNumElements()<<", vbo"<<vbo<<")"<<std::endl;
|
|
glVertexPointer(new_array->getDataSize(), new_array->getDataType(), 0, (const GLvoid *)(vbo->getOffset(new_array->getBufferIndex())));
|
|
}
|
|
|
|
virtual void disable(osg::State& state)
|
|
{
|
|
VAS_NOTICE<<" VertexArrayDispatch::disable()"<<std::endl;
|
|
glDisableClientState(GL_VERTEX_ARRAY);
|
|
}
|
|
};
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// ColorArrayDispatch
|
|
//
|
|
struct ColorArrayDispatch : public VertexArrayState::ArrayDispatch
|
|
{
|
|
ColorArrayDispatch() {}
|
|
|
|
virtual void enable_and_dispatch(osg::State&, const osg::Array* new_array)
|
|
{
|
|
VAS_NOTICE<<" ColorArrayDispatch::enable_and_dispatch("<<new_array->getNumElements()<<")"<<std::endl;
|
|
glEnableClientState(GL_COLOR_ARRAY);
|
|
glColorPointer(new_array->getDataSize(), new_array->getDataType(), 0, new_array->getDataPointer());
|
|
}
|
|
|
|
virtual void enable_and_dispatch(osg::State&, const osg::Array* new_array, const osg::GLBufferObject* vbo)
|
|
{
|
|
VAS_NOTICE<<" ColorArrayDispatch::enable_and_dispatch("<<new_array->getNumElements()<<", vbo="<<vbo<<")"<<std::endl;
|
|
|
|
glEnableClientState(GL_COLOR_ARRAY);
|
|
glColorPointer(new_array->getDataSize(), new_array->getDataType(), 0, (const GLvoid *)(vbo->getOffset(new_array->getBufferIndex())));
|
|
}
|
|
|
|
virtual void dispatch(osg::State& state, const osg::Array* new_array)
|
|
{
|
|
VAS_NOTICE<<" ColorArrayDispatch::dispatch("<<new_array->getNumElements()<<")"<<std::endl;
|
|
glColorPointer(new_array->getDataSize(), new_array->getDataType(), 0, new_array->getDataPointer());
|
|
}
|
|
|
|
virtual void dispatch(osg::State& state, const osg::Array* new_array, const osg::GLBufferObject* vbo)
|
|
{
|
|
VAS_NOTICE<<" ColorArrayDispatch::dispatch("<<new_array->getNumElements()<<", vbo="<<vbo<<")"<<std::endl;
|
|
glColorPointer(new_array->getDataSize(), new_array->getDataType(), 0, (const GLvoid *)(vbo->getOffset(new_array->getBufferIndex())));
|
|
}
|
|
|
|
virtual void disable(osg::State& state)
|
|
{
|
|
VAS_NOTICE<<" ColorArrayDispatch::disable()"<<std::endl;
|
|
glDisableClientState(GL_COLOR_ARRAY);
|
|
}
|
|
|
|
};
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// NormalArrayDispatch
|
|
//
|
|
struct NormalArrayDispatch : public VertexArrayState::ArrayDispatch
|
|
{
|
|
NormalArrayDispatch() {}
|
|
|
|
virtual void enable_and_dispatch(osg::State&, const osg::Array* new_array)
|
|
{
|
|
VAS_NOTICE<<" NormalArrayDispatch::enable_and_dispatch("<<new_array->getNumElements()<<")"<<std::endl;
|
|
glEnableClientState(GL_NORMAL_ARRAY);
|
|
glNormalPointer(new_array->getDataType(), 0, new_array->getDataPointer());
|
|
}
|
|
|
|
virtual void enable_and_dispatch(osg::State&, const osg::Array* new_array, const osg::GLBufferObject* vbo)
|
|
{
|
|
VAS_NOTICE<<" NormalArrayDispatch::enable_and_dispatch("<<new_array->getNumElements()<<", vbo="<<vbo<<")"<<std::endl;
|
|
glEnableClientState(GL_NORMAL_ARRAY);
|
|
glNormalPointer(new_array->getDataType(), 0, (const GLvoid *)(vbo->getOffset(new_array->getBufferIndex())));
|
|
}
|
|
|
|
virtual void dispatch(osg::State& state, const osg::Array* new_array)
|
|
{
|
|
VAS_NOTICE<<" NormalArrayDispatch::dispatch("<<new_array->getNumElements()<<")"<<std::endl;
|
|
glNormalPointer(new_array->getDataType(), 0, new_array->getDataPointer());
|
|
}
|
|
|
|
virtual void dispatch(osg::State& state, const osg::Array* new_array, const osg::GLBufferObject* vbo)
|
|
{
|
|
VAS_NOTICE<<" NormalArrayDispatch::dispatch("<<new_array->getNumElements()<<", vbo="<<vbo<<")"<<std::endl;
|
|
glNormalPointer(new_array->getDataType(), 0, (const GLvoid *)(vbo->getOffset(new_array->getBufferIndex())));
|
|
}
|
|
|
|
virtual void disable(osg::State& state)
|
|
{
|
|
VAS_NOTICE<<" NormalArrayDispatch::disable()"<<std::endl;
|
|
glDisableClientState(GL_NORMAL_ARRAY);
|
|
}
|
|
};
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// SecondaryColorArrayDispatch
|
|
//
|
|
struct SecondaryColorArrayDispatch : public VertexArrayState::ArrayDispatch
|
|
{
|
|
SecondaryColorArrayDispatch() {}
|
|
|
|
virtual void enable_and_dispatch(osg::State& state, const osg::Array* new_array)
|
|
{
|
|
glEnableClientState(GL_SECONDARY_COLOR_ARRAY);
|
|
state.get<GLExtensions>()->glSecondaryColorPointer(new_array->getDataSize(), new_array->getDataType(), 0, new_array->getDataPointer());
|
|
}
|
|
|
|
virtual void enable_and_dispatch(osg::State& state, const osg::Array* new_array, const osg::GLBufferObject* vbo)
|
|
{
|
|
glEnableClientState(GL_SECONDARY_COLOR_ARRAY);
|
|
state.get<GLExtensions>()->glSecondaryColorPointer(new_array->getDataSize(), new_array->getDataType(), 0, (const GLvoid *)(vbo->getOffset(new_array->getBufferIndex())));
|
|
}
|
|
|
|
virtual void dispatch(osg::State& state, const osg::Array* new_array)
|
|
{
|
|
state.get<GLExtensions>()->glSecondaryColorPointer(new_array->getDataSize(), new_array->getDataType(), 0, new_array->getDataPointer());
|
|
}
|
|
|
|
virtual void dispatch(osg::State& state, const osg::Array* new_array, const osg::GLBufferObject* vbo)
|
|
{
|
|
state.get<GLExtensions>()->glSecondaryColorPointer(new_array->getDataSize(), new_array->getDataType(), 0, (const GLvoid *)(vbo->getOffset(new_array->getBufferIndex())));
|
|
}
|
|
|
|
virtual void disable(osg::State& state)
|
|
{
|
|
glDisableClientState(GL_SECONDARY_COLOR_ARRAY);
|
|
}
|
|
};
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// FogCoordArrayDispatch
|
|
//
|
|
struct FogCoordArrayDispatch : public VertexArrayState::ArrayDispatch
|
|
{
|
|
FogCoordArrayDispatch() {}
|
|
|
|
virtual void enable_and_dispatch(osg::State& state, const osg::Array* new_array)
|
|
{
|
|
glEnableClientState(GL_FOG_COORD_ARRAY);
|
|
state.get<GLExtensions>()->glFogCoordPointer(new_array->getDataType(), 0, new_array->getDataPointer());
|
|
}
|
|
|
|
virtual void enable_and_dispatch(osg::State& state, const osg::Array* new_array, const osg::GLBufferObject* vbo)
|
|
{
|
|
glEnableClientState(GL_FOG_COORD_ARRAY);
|
|
state.get<GLExtensions>()->glFogCoordPointer(new_array->getDataType(), 0, (const GLvoid *)(vbo->getOffset(new_array->getBufferIndex())));
|
|
}
|
|
|
|
virtual void dispatch(osg::State& state, const osg::Array* new_array)
|
|
{
|
|
state.get<GLExtensions>()->glFogCoordPointer(new_array->getDataType(), 0, new_array->getDataPointer());
|
|
}
|
|
|
|
virtual void dispatch(osg::State& state, const osg::Array* new_array, const osg::GLBufferObject* vbo)
|
|
{
|
|
state.get<GLExtensions>()->glFogCoordPointer(new_array->getDataType(), 0, (const GLvoid *)(vbo->getOffset(new_array->getBufferIndex())));
|
|
}
|
|
|
|
virtual void disable(osg::State& state)
|
|
{
|
|
glDisableClientState(GL_FOG_COORD_ARRAY);
|
|
}
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// TexCoordArrayDispatch
|
|
//
|
|
struct TexCoordArrayDispatch : public VertexArrayState::ArrayDispatch
|
|
{
|
|
TexCoordArrayDispatch(unsigned int in_unit) : unit(in_unit) {}
|
|
|
|
virtual void enable_and_dispatch(osg::State& state, const osg::Array* new_array)
|
|
{
|
|
VAS_NOTICE<<" TexCoordArrayDispatch::enable_and_dispatch("<<new_array->getNumElements()<<") unit="<<unit<<std::endl;
|
|
|
|
glClientActiveTexture(static_cast<GLenum>(GL_TEXTURE0+unit));
|
|
//state.setClientActiveTextureUnit(unit);
|
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
glTexCoordPointer(new_array->getDataSize(), new_array->getDataType(), 0, new_array->getDataPointer());
|
|
}
|
|
|
|
virtual void enable_and_dispatch(osg::State& state, const osg::Array* new_array, const osg::GLBufferObject* vbo)
|
|
{
|
|
VAS_NOTICE<<" TexCoordArrayDispatch::enable_and_dispatch("<<new_array->getNumElements()<<", vbo="<<vbo<<") unit="<<unit<<std::endl;
|
|
|
|
//glClientActiveTexture(static_cast<GLenum>(GL_TEXTURE0+unit));
|
|
state.setClientActiveTextureUnit(unit);
|
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
glTexCoordPointer(new_array->getDataSize(), new_array->getDataType(), 0, (const GLvoid *)(vbo->getOffset(new_array->getBufferIndex())));
|
|
}
|
|
|
|
virtual void dispatch(osg::State& state, const osg::Array* new_array)
|
|
{
|
|
VAS_NOTICE<<" TexCoordArrayDispatch::dispatch("<<new_array->getNumElements()<<") unit="<<unit<<std::endl;
|
|
|
|
//glClientActiveTexture(static_cast<GLenum>(GL_TEXTURE0+unit));
|
|
state.setClientActiveTextureUnit(unit);
|
|
glTexCoordPointer(new_array->getDataSize(), new_array->getDataType(), 0, new_array->getDataPointer());
|
|
}
|
|
|
|
virtual void dispatch(osg::State& state, const osg::Array* new_array, const osg::GLBufferObject* vbo)
|
|
{
|
|
VAS_NOTICE<<" TexCoordArrayDispatch::dispatch("<<new_array->getNumElements()<<", vbo="<<vbo<<") unit="<<unit<<std::endl;
|
|
|
|
//glClientActiveTexture(static_cast<GLenum>(GL_TEXTURE0+unit));
|
|
state.setClientActiveTextureUnit(unit);
|
|
glTexCoordPointer(new_array->getDataSize(), new_array->getDataType(), 0, (const GLvoid *)(vbo->getOffset(new_array->getBufferIndex())));
|
|
}
|
|
|
|
virtual void disable(osg::State& state)
|
|
{
|
|
VAS_NOTICE<<" TexCoordArrayDispatch::disable() unit="<<unit<<std::endl;
|
|
|
|
//state.glClientActiveTexture(static_cast<GLenum>(GL_TEXTURE0+unit));
|
|
state.setClientActiveTextureUnit(unit);
|
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
}
|
|
|
|
unsigned int unit;
|
|
};
|
|
#endif
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// VertexAttribArrayDispatch
|
|
//
|
|
|
|
struct VertexAttribArrayDispatch : public VertexArrayState::ArrayDispatch
|
|
{
|
|
VertexAttribArrayDispatch(unsigned int in_unit) : unit(in_unit) {}
|
|
|
|
inline void callVertexAttribPointer(GLExtensions* ext, const osg::Array* new_array, const GLvoid * ptr)
|
|
{
|
|
if (new_array->getDataType()==GL_FLOAT)
|
|
ext->glVertexAttribPointer(static_cast<GLuint>(unit), new_array->getDataSize(), new_array->getDataType(), new_array->getNormalize(), 0, ptr);
|
|
else if (array->getDataType()==GL_DOUBLE)
|
|
ext->glVertexAttribLPointer(static_cast<GLuint>(unit), new_array->getDataSize(), new_array->getDataType(), 0, ptr);
|
|
else
|
|
ext->glVertexAttribIPointer(static_cast<GLuint>(unit), new_array->getDataSize(), new_array->getDataType(), 0, ptr);
|
|
}
|
|
|
|
virtual void enable_and_dispatch(osg::State& state, const osg::Array* new_array)
|
|
{
|
|
GLExtensions* ext = state.get<GLExtensions>();
|
|
|
|
ext->glEnableVertexAttribArray( unit );
|
|
callVertexAttribPointer(ext, new_array, new_array->getDataPointer());
|
|
}
|
|
|
|
virtual void enable_and_dispatch(osg::State& state, const osg::Array* new_array, const osg::GLBufferObject* vbo)
|
|
{
|
|
GLExtensions* ext = state.get<GLExtensions>();
|
|
|
|
ext->glEnableVertexAttribArray( unit );
|
|
callVertexAttribPointer(ext, new_array, (const GLvoid *)(vbo->getOffset(new_array->getBufferIndex())));
|
|
}
|
|
|
|
virtual void dispatch(osg::State& state, const osg::Array* new_array)
|
|
{
|
|
GLExtensions* ext = state.get<GLExtensions>();
|
|
callVertexAttribPointer(ext, new_array, new_array->getDataPointer());
|
|
}
|
|
|
|
virtual void dispatch(osg::State& state, const osg::Array* new_array, const osg::GLBufferObject* vbo)
|
|
{
|
|
GLExtensions* ext = state.get<GLExtensions>();
|
|
callVertexAttribPointer(ext, new_array, (const GLvoid *)(vbo->getOffset(new_array->getBufferIndex())));
|
|
}
|
|
|
|
virtual void disable(osg::State& state)
|
|
{
|
|
GLExtensions* ext = state.get<GLExtensions>();
|
|
ext->glDisableVertexAttribArray( unit );
|
|
}
|
|
|
|
unsigned int unit;
|
|
};
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// VertexArrayState
|
|
//
|
|
VertexArrayState::VertexArrayState(osg::GLExtensions* ext):
|
|
_ext(ext),
|
|
_vertexArrayObject(0),
|
|
_currentVBO(0),
|
|
_currentEBO(0),
|
|
_requiresSetArrays(true)
|
|
{
|
|
}
|
|
|
|
#if 0
|
|
osg::GLBufferObject* VertexArrayState::getGLBufferObject(osg::Array* array)
|
|
{
|
|
if (_ext->isBufferObjectSupported && array->getBufferObject())
|
|
{
|
|
return array->getBufferObject()->getOrCreateGLBufferObject(_ext->contextID);
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
void VertexArrayState::generateVretexArrayObject()
|
|
{
|
|
_ext->glGenVertexArrays(1, &_vertexArrayObject);
|
|
}
|
|
|
|
void VertexArrayState::bindVertexArrayObject() const
|
|
{
|
|
VAS_NOTICE<<"glBindVertexArray() _vertexArrayObject="<<_vertexArrayObject<<std::endl;
|
|
|
|
_ext->glBindVertexArray (_vertexArrayObject);
|
|
}
|
|
|
|
void VertexArrayState::unbindVertexArrayObject() const
|
|
{
|
|
_ext->glBindVertexArray (0);
|
|
}
|
|
|
|
void VertexArrayState::releaseGLObjects()
|
|
{
|
|
if (_vertexArrayObject)
|
|
{
|
|
_ext->glDeleteVertexArrays(1, &_vertexArrayObject);
|
|
}
|
|
}
|
|
|
|
|
|
void VertexArrayState::assignVertexArrayDispatcher()
|
|
{
|
|
#ifdef OSG_GL_VERTEX_ARRAY_FUNCS_AVAILABLE
|
|
if (!_ext->getUseVertexAttributeAliasing())
|
|
{
|
|
_vertexArray = new VertexArrayDispatch();
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
_vertexArray = new VertexAttribArrayDispatch(_ext->getVertexAlias()._location);
|
|
}
|
|
}
|
|
|
|
void VertexArrayState::assignNormalArrayDispatcher()
|
|
{
|
|
#ifdef OSG_GL_VERTEX_ARRAY_FUNCS_AVAILABLE
|
|
if (!_ext->getUseVertexAttributeAliasing())
|
|
{
|
|
_normalArray = new NormalArrayDispatch();
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
_normalArray = new VertexAttribArrayDispatch(_ext->getNormalAlias()._location);
|
|
}
|
|
}
|
|
|
|
void VertexArrayState::assignColorArrayDispatcher()
|
|
{
|
|
#ifdef OSG_GL_VERTEX_ARRAY_FUNCS_AVAILABLE
|
|
if (!_ext->getUseVertexAttributeAliasing())
|
|
{
|
|
_colorArray = new ColorArrayDispatch();
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
_colorArray = new VertexAttribArrayDispatch(_ext->getColorAlias()._location);
|
|
}
|
|
}
|
|
|
|
void VertexArrayState::assignSecondaryColorArrayDispatcher()
|
|
{
|
|
#ifdef OSG_GL_VERTEX_ARRAY_FUNCS_AVAILABLE
|
|
if (!_ext->getUseVertexAttributeAliasing())
|
|
{
|
|
_secondaryColorArray = new SecondaryColorArrayDispatch();
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
_secondaryColorArray = new VertexAttribArrayDispatch(_ext->getSecondaryColorAlias()._location);
|
|
}
|
|
}
|
|
|
|
void VertexArrayState::assignFogCoordArrayDispatcher()
|
|
{
|
|
#ifdef OSG_GL_VERTEX_ARRAY_FUNCS_AVAILABLE
|
|
if (!_ext->getUseVertexAttributeAliasing())
|
|
{
|
|
_fogCoordArray = new FogCoordArrayDispatch();
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
_fogCoordArray = new VertexAttribArrayDispatch(_ext->getFogCoordAlias()._location);
|
|
}
|
|
}
|
|
|
|
void VertexArrayState::assignTexCoordArrayDispatcher(unsigned int numUnits)
|
|
{
|
|
#ifdef OSG_GL_VERTEX_ARRAY_FUNCS_AVAILABLE
|
|
if (!_ext->getUseVertexAttributeAliasing())
|
|
{
|
|
_texCoordArrays.clear();
|
|
for(unsigned int i=0; i<numUnits; ++i)
|
|
{
|
|
_texCoordArrays.push_back( new TexCoordArrayDispatch(i) );
|
|
}
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
_texCoordArrays.clear();
|
|
for(unsigned int i=0; i<numUnits; ++i)
|
|
{
|
|
_texCoordArrays.push_back( new VertexAttribArrayDispatch(_ext->getTexCoordAliasList()[i]._location) );
|
|
}
|
|
}
|
|
}
|
|
|
|
void VertexArrayState::assignVertexAttribArrayDispatcher(unsigned int numUnits)
|
|
{
|
|
_vertexAttribArrays.clear();
|
|
for(unsigned int i=0; i<numUnits; ++i)
|
|
{
|
|
_vertexAttribArrays.push_back( new VertexAttribArrayDispatch(i) );
|
|
}
|
|
}
|
|
|
|
void VertexArrayState::assignAllDispatchers()
|
|
{
|
|
unsigned int numUnits = 8;
|
|
unsigned int numVertexAttrib = 16;
|
|
|
|
assignVertexArrayDispatcher();
|
|
assignNormalArrayDispatcher();
|
|
assignColorArrayDispatcher();
|
|
assignSecondaryColorArrayDispatcher();
|
|
assignFogCoordArrayDispatcher();
|
|
assignTexCoordArrayDispatcher(numUnits);
|
|
assignVertexAttribArrayDispatcher(numVertexAttrib);
|
|
}
|
|
|
|
void VertexArrayState::lazyDisablingOfVertexAttributes()
|
|
{
|
|
VAS_NOTICE<<" VertexArrayState<"<<this<<">::lazyDisablingOfVertexAttributes() _activeDispatchers.size()="<<_activeDispatchers.size()<<", _previous_activeDispatchers.size()="<<_previous_activeDispatchers.size()<<std::endl;
|
|
|
|
_activeDispatchers.swap(_previous_activeDispatchers);
|
|
_activeDispatchers.clear();
|
|
|
|
for(ActiveDispatchers::iterator itr = _previous_activeDispatchers.begin();
|
|
itr != _previous_activeDispatchers.end();
|
|
++itr)
|
|
{
|
|
ArrayDispatch* ad = (*itr);
|
|
// ad->array = 0;
|
|
ad->active = false;
|
|
}
|
|
}
|
|
|
|
void VertexArrayState::applyDisablingOfVertexAttributes(osg::State& state)
|
|
{
|
|
VAS_NOTICE<<" VertexArrayState<"<<this<<">::applyDisablingOfVertexAttributes() _activeDispatchers.size()="<<_activeDispatchers.size()<<", _previous_activeDispatchers.size()="<<_previous_activeDispatchers.size()<<std::endl;
|
|
|
|
for(ActiveDispatchers::iterator itr = _previous_activeDispatchers.begin();
|
|
itr != _previous_activeDispatchers.end();
|
|
++itr)
|
|
{
|
|
ArrayDispatch* ad = (*itr);
|
|
if (!ad->active)
|
|
{
|
|
ad->disable(state);
|
|
ad->array = 0;
|
|
ad->modifiedCount = 0xffffffff;
|
|
}
|
|
}
|
|
_previous_activeDispatchers.clear();
|
|
}
|
|
|
|
void VertexArrayState::setArray(ArrayDispatch* vad, osg::State& state, const osg::Array* new_array)
|
|
{
|
|
if (new_array)
|
|
{
|
|
VAS_NOTICE<<" VertexArrayState<"<<this<<">::setArray() "<<typeid(*vad).name()<<" new_array="<<new_array<<", size()="<<new_array->getNumElements()<<std::endl;
|
|
|
|
if (!vad->active)
|
|
{
|
|
vad->active = true;
|
|
_activeDispatchers.push_back(vad);
|
|
}
|
|
|
|
#define LAZY_UPDATE
|
|
#define CHECK_IF_UPDATE
|
|
|
|
#ifdef LAZY_UPDATE
|
|
if (vad->array==0)
|
|
#endif
|
|
{
|
|
GLBufferObject* vbo = isVertexBufferObjectSupported() ? new_array->getOrCreateGLBufferObject(state.getContextID()) : 0;
|
|
if (vbo)
|
|
{
|
|
bindVertexBufferObject(vbo);
|
|
vad->enable_and_dispatch(state, new_array, vbo);
|
|
}
|
|
else
|
|
{
|
|
unbindVertexBufferObject();
|
|
vad->enable_and_dispatch(state, new_array);
|
|
}
|
|
}
|
|
#ifdef LAZY_UPDATE
|
|
else
|
|
#ifdef CHECK_IF_UPDATE
|
|
if (new_array!=vad->array || new_array->getModifiedCount()!=vad->modifiedCount)
|
|
#endif
|
|
{
|
|
GLBufferObject* vbo = isVertexBufferObjectSupported() ? new_array->getOrCreateGLBufferObject(state.getContextID()) : 0;
|
|
if (vbo)
|
|
{
|
|
bindVertexBufferObject(vbo);
|
|
vad->dispatch(state, new_array, vbo);
|
|
}
|
|
else
|
|
{
|
|
unbindVertexBufferObject();
|
|
vad->dispatch(state, new_array);
|
|
}
|
|
}
|
|
#ifdef CHECK_IF_UPDATE
|
|
else
|
|
{
|
|
VAS_NOTICE<<"**************** No need to update *************************"<<std::endl;
|
|
return;
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
vad->array = new_array;
|
|
vad->modifiedCount = new_array->getModifiedCount();
|
|
|
|
}
|
|
else if (vad->array)
|
|
{
|
|
VAS_NOTICE<<" VertexArrayState::setArray() need to disable "<<typeid(*vad).name()<<std::endl;
|
|
|
|
disable(vad, state);
|
|
}
|
|
}
|
|
|
|
void VertexArrayState::disableTexCoordArrayAboveAndIncluding(osg::State& state, unsigned int index)
|
|
{
|
|
for(unsigned int i=index; i<_texCoordArrays.size(); ++i)
|
|
{
|
|
disable(_texCoordArrays[i].get(), state);
|
|
}
|
|
}
|
|
|
|
void VertexArrayState::disableVertexAttribArrayAboveAndIncluding(osg::State& state, unsigned int index)
|
|
{
|
|
for(unsigned int i=index; i<_vertexAttribArrays.size(); ++i)
|
|
{
|
|
disable(_vertexAttribArrays[i].get(), state);
|
|
}
|
|
}
|