Implemented a different approach to vertex array object support to enable creation of a single global vertex array object as well as provide individual vertex array objects per Drawable when required.

This commit is contained in:
Robert Osfield
2016-07-23 15:02:08 +01:00
parent 4d8a29b987
commit 7d83d735ad
13 changed files with 1841 additions and 1481 deletions

View File

@@ -66,14 +66,6 @@ class Geometry;
class NodeVisitor;
class ArrayDispatchers;
// this is defined to alter the way display lists are compiled inside the
// the draw method, it has been found that the NVidia drivers fail completely
// to optimize COMPILE_AND_EXECUTE in fact make it go slower than for no display
// lists, but optimize a separate COMPILE very well?! Define it as default
// the use of a separate COMPILE, then glCallList rather than use COMPILE_AND_EXECUTE.
#define USE_SEPARATE_COMPILE_AND_EXECUTE
/** Pure virtual base class for drawable geometry. In OSG, everything that can
* be rendered is implemented as a class derived from \c Drawable. The
* \c Drawable class contains no drawing primitives, since these are provided
@@ -235,9 +227,19 @@ class OSG_EXPORT Drawable : public Node
inline bool getUseVertexBufferObjects() const { return _useVertexBufferObjects; }
/** Force a recompile on next draw() of any OpenGL display list associated with this geoset.*/
/** Set whether to use a local VertexArrayObject for this Drawable.*/
void setUseVertexArrayObject(bool flag);
/** Return whether to use a local VertexArrayObject for this Drawable.*/
bool getUseVertexArrayObject() const { return _useVertexArrayObject; }
/** Deprecated, use dirtyGLObjects() instead. */
virtual void dirtyDisplayList();
/** Force a recompile on next draw() of any OpenGL objects associated with this geoset.*/
virtual void dirtyGLObjects();
/** Return the estimated size of GLObjects (display lists/vertex buffer objects) that are associated with this drawable.
* This size is used a hint for reuse of deleted display lists/vertex buffer objects. */
@@ -254,13 +256,29 @@ class OSG_EXPORT Drawable : public Node
* \c virtual). Subclasses should override
* \c drawImplementation() instead.
*/
#if 0
inline void draw(RenderInfo& renderInfo) const;
#else
void draw(RenderInfo& renderInfo) const;
#endif
inline void drawInner(RenderInfo& renderInfo) const
{
if (_drawCallback.valid())
_drawCallback->drawImplementation(renderInfo,this);
else
drawImplementation(renderInfo);
}
/** Immediately compile this \c Drawable into an OpenGL Display List/VertexBufferObjects.
* @note Operation is ignored if \c _useDisplayList is \c false or VertexBufferObjects are not used.
*/
virtual void compileGLObjects(RenderInfo& renderInfo) const;
virtual VertexArrayState* setUpVertexArrayState(RenderInfo& renderInfo, bool usingVBOs) const;
/** Set whether to use a mutex to ensure ref() and unref() are thread safe.*/
virtual void setThreadSafeRefUnref(bool threadSafe);
@@ -466,14 +484,18 @@ class OSG_EXPORT Drawable : public Node
bool _useDisplayList;
bool _supportsVertexBufferObjects;
bool _useVertexBufferObjects;
bool _useVertexArrayObject;
typedef osg::buffered_value<GLuint> GLObjectList;
mutable GLObjectList _globjList;
typedef buffered_object< osg::ref_ptr<VertexArrayState> > VertexArrayStateList;
mutable VertexArrayStateList _vertexArrayStateList;
ref_ptr<DrawCallback> _drawCallback;
};
#if 0
inline void Drawable::draw(RenderInfo& renderInfo) const
{
#ifdef OSG_GL_DISPLAYLISTS_AVAILABLE
@@ -486,36 +508,24 @@ inline void Drawable::draw(RenderInfo& renderInfo) const
// get the globj for the current contextID.
GLuint& globj = _globjList[contextID];
// call the globj if already set otherwise compile and execute.
if( globj != 0 )
if( globj == 0 )
{
glCallList( globj );
}
else if (_useDisplayList)
{
#ifdef USE_SEPARATE_COMPILE_AND_EXECUTE
// compile the display list
globj = generateDisplayList(contextID, getGLObjectSizeHint());
glNewList( globj, GL_COMPILE );
if (_drawCallback.valid())
_drawCallback->drawImplementation(renderInfo,this);
else
drawImplementation(renderInfo);
glEndList();
glCallList( globj);
#else
globj = generateDisplayList(contextID, getGLObjectSizeHint());
glNewList( globj, GL_COMPILE_AND_EXECUTE );
if (_drawCallback.valid())
_drawCallback->drawImplementation(renderInfo,this);
else
drawImplementation(renderInfo);
glEndList();
#endif
}
return;
// call the display list
glCallList( globj);
return;
}
#endif
@@ -525,6 +535,7 @@ inline void Drawable::draw(RenderInfo& renderInfo) const
else
drawImplementation(renderInfo);
}
#endif
class AttributeFunctorArrayVisitor : public ArrayVisitor
{

View File

@@ -140,8 +140,8 @@ class OSG_EXPORT Geometry : public Drawable
method to use OpenGL vertex buffer objects for rendering.*/
virtual void setUseVertexBufferObjects(bool flag);
/** Force a recompile on next draw() of any OpenGL display list associated with this geoset.*/
virtual void dirtyDisplayList();
/** Force a recompile on next draw() of any OpenGL objects associated with this geoset.*/
virtual void dirtyGLObjects();
/** Resize any per context GLObject buffers to specified size. */
@@ -178,14 +178,10 @@ class OSG_EXPORT Geometry : public Drawable
/** Set up the vertex arrays for the purpose of rendering, called by drawImplemtation() prior to it calling drawPrimitivesImplementation().*/
void old_drawVertexArraysImplementation(RenderInfo& renderInfo) const;
void drawVertexArraysImplementation(RenderInfo& renderInfo) const;
/** dispatch the primitives to OpenGL, called by drawImplemtation() after calling drawVertexArraysImplementation().*/
void old_drawPrimitivesImplementation(RenderInfo& renderInfo) const;
/** Set up the vertex arrays for the purpose of rendering, called by drawImplemtation() prior to it calling drawPrimitivesImplementation().*/
void new_drawImplementation(RenderInfo& renderInfo) const;
void drawPrimitivesImplementation(RenderInfo& renderInfo) const;
/** Return true, osg::Geometry does support accept(Drawable::AttributeFunctor&). */
@@ -223,10 +219,6 @@ class OSG_EXPORT Geometry : public Drawable
void addVertexBufferObjectIfRequired(osg::Array* array);
void addElementBufferObjectIfRequired(osg::PrimitiveSet* primitiveSet);
typedef buffered_object< osg::ref_ptr<VertexArrayState> > VertexArrayStateList;
mutable VertexArrayStateList _vertexArrayStateList;
PrimitiveSetList _primitives;
osg::ref_ptr<Array> _vertexArray;
osg::ref_ptr<Array> _normalArray;

View File

@@ -517,8 +517,17 @@ class OSG_EXPORT State : public Referenced
#if 1
void setCurrentVertexBufferObject(osg::GLBufferObject* vbo);
const GLBufferObject* getCurrentVertexBufferObject();
void bindVertexBufferObject(osg::GLBufferObject* vbo);
void unbindVertexBufferObject();
#else
void setCurrentVertexBufferObject(osg::GLBufferObject* vbo) { _currentVBO = vbo; }
const GLBufferObject* getCurrentVertexBufferObject() { return _currentVBO; }
inline void bindVertexBufferObject(osg::GLBufferObject* vbo)
{
if (vbo)
@@ -537,7 +546,15 @@ class OSG_EXPORT State : public Referenced
_glBindBuffer(GL_ARRAY_BUFFER_ARB,0);
_currentVBO = 0;
}
#endif
#if 1
void setCurrentElementBufferObject(osg::GLBufferObject* ebo);
const GLBufferObject* getCurrentElementBufferObject();
void bindElementBufferObject(osg::GLBufferObject* ebo);
void unbindElementBufferObject();
#else
void setCurrentElementBufferObject(osg::GLBufferObject* ebo) { _currentEBO = ebo; }
const GLBufferObject* getCurrentElementBufferObject() { return _currentEBO; }
@@ -559,6 +576,7 @@ class OSG_EXPORT State : public Referenced
_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB,0);
_currentEBO = 0;
}
#endif
void setCurrentPixelBufferObject(osg::GLBufferObject* pbo) { _currentPBO = pbo; }
const GLBufferObject* getCurrentPixelBufferObject() { return _currentPBO; }
@@ -681,6 +699,9 @@ class OSG_EXPORT State : public Referenced
void setInterleavedArrays( GLenum format, GLsizei stride, const GLvoid* pointer);
/** Set the vertex pointer using an osg::Array, and manage any VBO that are required.*/
#if 1
void setVertexPointer(const Array* array);
#else
inline void setVertexPointer(const Array* array)
{
if (array)
@@ -698,7 +719,7 @@ class OSG_EXPORT State : public Referenced
}
}
}
#endif
/** wrapper around glEnableClientState(GL_VERTEX_ARRAY);glVertexPointer(..);
* note, only updates values that change.*/
inline void setVertexPointer( GLint size, GLenum type,
@@ -730,6 +751,9 @@ class OSG_EXPORT State : public Referenced
#endif
}
#if 1
void disableVertexPointer();
#else
/** wrapper around glDisableClientState(GL_VERTEX_ARRAY).
* note, only updates values that change.*/
inline void disableVertexPointer()
@@ -753,7 +777,11 @@ class OSG_EXPORT State : public Referenced
disableVertexAttribPointer(_vertexAlias._location);
#endif
}
#endif
#if 1
void dirtyVertexPointer();
#else
inline void dirtyVertexPointer()
{
#ifdef OSG_GL_VERTEX_ARRAY_FUNCS_AVAILABLE
@@ -770,8 +798,12 @@ class OSG_EXPORT State : public Referenced
dirtyVertexAttribPointer(_vertexAlias._location);
#endif
}
#endif
#if 1
void setNormalPointer(const Array* array);
#else
/** Set the normal pointer using an osg::Array, and manage any VBO that are required.*/
inline void setNormalPointer(const Array* array)
{
@@ -790,7 +822,7 @@ class OSG_EXPORT State : public Referenced
}
}
}
#endif
/** wrapper around glEnableClientState(GL_NORMAL_ARRAY);glNormalPointer(..);
* note, only updates values that change.*/
inline void setNormalPointer( GLenum type, GLsizei stride,
@@ -822,6 +854,9 @@ class OSG_EXPORT State : public Referenced
#endif
}
#if 1
void disableNormalPointer();
#else
/** wrapper around glDisableClientState(GL_NORMAL_ARRAY);
* note, only updates values that change.*/
inline void disableNormalPointer()
@@ -845,7 +880,11 @@ class OSG_EXPORT State : public Referenced
disableVertexAttribPointer(_normalAlias._location);
#endif
}
#endif
#if 1
void dirtyNormalPointer();
#else
inline void dirtyNormalPointer()
{
#ifdef OSG_GL_VERTEX_ARRAY_FUNCS_AVAILABLE
@@ -862,7 +901,11 @@ class OSG_EXPORT State : public Referenced
dirtyVertexAttribPointer(_normalAlias._location);
#endif
}
#endif
#if 1
void setColorPointer(const Array* array);
#else
/** Set the color pointer using an osg::Array, and manage any VBO that are required.*/
inline void setColorPointer(const Array* array)
{
@@ -881,7 +924,7 @@ class OSG_EXPORT State : public Referenced
}
}
}
#endif
/** wrapper around glEnableClientState(GL_COLOR_ARRAY);glColorPointer(..);
* note, only updates values that change.*/
@@ -914,6 +957,9 @@ class OSG_EXPORT State : public Referenced
#endif
}
#if 1
void disableColorPointer();
#else
/** wrapper around glDisableClientState(GL_COLOR_ARRAY);
* note, only updates values that change.*/
inline void disableColorPointer()
@@ -937,7 +983,11 @@ class OSG_EXPORT State : public Referenced
disableVertexAttribPointer(_colorAlias._location);
#endif
}
#endif
#if 1
void dirtyColorPointer();
#else
inline void dirtyColorPointer()
{
#ifdef OSG_GL_VERTEX_ARRAY_FUNCS_AVAILABLE
@@ -954,11 +1004,14 @@ class OSG_EXPORT State : public Referenced
dirtyVertexAttribPointer(_colorAlias._location);
#endif
}
#endif
inline bool isSecondaryColorSupported() const { return _isSecondaryColorSupportResolved?_isSecondaryColorSupported:computeSecondaryColorSupported(); }
#if 1
void setSecondaryColorPointer(const Array* array);
#else
/** Set the secondary color pointer using an osg::Array, and manage any VBO that are required.*/
inline void setSecondaryColorPointer(const Array* array)
{
@@ -977,11 +1030,15 @@ class OSG_EXPORT State : public Referenced
}
}
}
#endif
/** wrapper around glEnableClientState(GL_SECONDARY_COLOR_ARRAY);glSecondayColorPointer(..);
* note, only updates values that change.*/
void setSecondaryColorPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *ptr, GLboolean normalized=GL_TRUE );
#if 1
void disableSecondaryColorPointer();
#else
/** wrapper around glDisableClientState(GL_SECONDARY_COLOR_ARRAY);
* note, only updates values that change.*/
inline void disableSecondaryColorPointer()
@@ -1005,7 +1062,11 @@ class OSG_EXPORT State : public Referenced
disableVertexAttribPointer(_secondaryColorAlias._location);
#endif
}
#endif
#if 1
inline void dirtySecondaryColorPointer();
#else
inline void dirtySecondaryColorPointer()
{
#ifdef OSG_GL_VERTEX_ARRAY_FUNCS_AVAILABLE
@@ -1022,10 +1083,14 @@ class OSG_EXPORT State : public Referenced
dirtyVertexAttribPointer(_secondaryColorAlias._location);
#endif
}
#endif
inline bool isFogCoordSupported() const { return _isFogCoordSupportResolved?_isFogCoordSupported:computeFogCoordSupported(); }
#if 1
void setFogCoordPointer(const Array* array);
#else
/** Set the fog coord pointer using an osg::Array, and manage any VBO that are required.*/
inline void setFogCoordPointer(const Array* array)
{
@@ -1044,12 +1109,15 @@ class OSG_EXPORT State : public Referenced
}
}
}
#endif
/** wrapper around glEnableClientState(GL_FOG_COORDINATE_ARRAY);glFogCoordPointer(..);
* note, only updates values that change.*/
void setFogCoordPointer( GLenum type, GLsizei stride, const GLvoid *ptr, GLboolean normalized=GL_FALSE );
#if 1
void disableFogCoordPointer();
#else
/** wrapper around glDisableClientState(GL_FOG_COORDINATE_ARRAY);
* note, only updates values that change.*/
inline void disableFogCoordPointer()
@@ -1073,7 +1141,11 @@ class OSG_EXPORT State : public Referenced
disableVertexAttribPointer(_fogCoordAlias._location);
#endif
}
#endif
#if 1
void dirtyFogCoordPointer();
#else
inline void dirtyFogCoordPointer()
{
#ifdef OSG_GL_VERTEX_ARRAY_FUNCS_AVAILABLE
@@ -1090,9 +1162,12 @@ class OSG_EXPORT State : public Referenced
dirtyVertexAttribPointer(_fogCoordAlias._location);
#endif
}
#endif
#if 1
void setTexCoordPointer(unsigned int unit, const Array* array);
#else
/** Set the tex coord pointer using an osg::Array, and manage any VBO that are required.*/
inline void setTexCoordPointer(unsigned int unit, const Array* array)
{
@@ -1111,7 +1186,7 @@ class OSG_EXPORT State : public Referenced
}
}
}
#endif
/** wrapper around glEnableClientState(GL_TEXTURE_COORD_ARRAY);glTexCoordPointer(..);
* note, only updates values that change.*/
inline void setTexCoordPointer( unsigned int unit,
@@ -1150,6 +1225,9 @@ class OSG_EXPORT State : public Referenced
#endif
}
#if 1
void disableTexCoordPointer( unsigned int unit );
#else
/** wrapper around glDisableClientState(GL_TEXTURE_COORD_ARRAY);
* note, only updates values that change.*/
inline void disableTexCoordPointer( unsigned int unit )
@@ -1179,7 +1257,11 @@ class OSG_EXPORT State : public Referenced
disableVertexAttribPointer(_texCoordAliasList[unit]._location);
#endif
}
#endif
#if 1
void dirtyTexCoordPointer( unsigned int unit );
#else
inline void dirtyTexCoordPointer( unsigned int unit )
{
#ifdef OSG_GL_VERTEX_ARRAY_FUNCS_AVAILABLE
@@ -1198,8 +1280,11 @@ class OSG_EXPORT State : public Referenced
dirtyVertexAttribPointer(_texCoordAliasList[unit]._location);
#endif
}
#endif
#if 1
void disableTexCoordPointersAboveAndIncluding( unsigned int unit );
#else
inline void disableTexCoordPointersAboveAndIncluding( unsigned int unit )
{
#ifdef OSG_GL_VERTEX_ARRAY_FUNCS_AVAILABLE
@@ -1229,7 +1314,11 @@ class OSG_EXPORT State : public Referenced
disableVertexAttribPointersAboveAndIncluding(_texCoordAliasList[unit]._location);
#endif
}
#endif
#if 1
void dirtyTexCoordPointersAboveAndIncluding( unsigned int unit );
#else
inline void dirtyTexCoordPointersAboveAndIncluding( unsigned int unit )
{
#ifdef OSG_GL_VERTEX_ARRAY_FUNCS_AVAILABLE
@@ -1251,7 +1340,7 @@ class OSG_EXPORT State : public Referenced
dirtyVertexAttribPointersAboveAndIncluding(_texCoordAliasList[unit]._location);
#endif
}
#endif
/// For GL>=2.0 uses GL_MAX_TEXTURE_COORDS, for GL<2 uses GL_MAX_TEXTURE_UNITS
inline GLint getMaxTextureCoords() const { return _glMaxTextureCoords; }
@@ -1274,8 +1363,11 @@ class OSG_EXPORT State : public Referenced
bool setClientActiveTextureUnit( unsigned int unit );
/** Get the current tex coord array texture unit.*/
unsigned int getClientActiveTextureUnit() const { return _currentClientActiveTextureUnit; }
unsigned int getClientActiveTextureUnit() const;
#if 1
void setVertexAttribPointer(unsigned int unit, const Array* array);
#else
/** Set the vertex attrib pointer using an osg::Array, and manage any VBO that are required.*/
inline void setVertexAttribPointer(unsigned int unit, const Array* array)
{
@@ -1294,7 +1386,11 @@ class OSG_EXPORT State : public Referenced
}
}
}
#endif
#if 1
void setVertexAttribLPointer(unsigned int unit, const Array* array);
#else
/** Set the vertex attrib pointer using an osg::Array, and manage any VBO that are required.*/
inline void setVertexAttribLPointer(unsigned int unit, const Array* array)
{
@@ -1313,7 +1409,11 @@ class OSG_EXPORT State : public Referenced
}
}
}
#endif
#if 1
void setVertexAttribIPointer(unsigned int unit, const Array* array);
#else
/** Set the vertex attrib pointer using an osg::Array, and manage any VBO that are required.*/
inline void setVertexAttribIPointer(unsigned int unit, const Array* array)
{
@@ -1332,6 +1432,7 @@ class OSG_EXPORT State : public Referenced
}
}
}
#endif
/** wrapper around glEnableVertexAttribArrayARB(index);glVertexAttribPointerARB(..);
* note, only updates values that change.*/
@@ -1357,6 +1458,9 @@ class OSG_EXPORT State : public Referenced
void disableVertexAttribPointersAboveAndIncluding( unsigned int index );
#if 1
void dirtyVertexAttribPointer( unsigned int index );
#else
inline void dirtyVertexAttribPointer( unsigned int index )
{
if (index<_vertexAttribArrayList.size())
@@ -1366,7 +1470,11 @@ class OSG_EXPORT State : public Referenced
eap._dirty = true;
}
}
#endif
#if 1
void dirtyVertexAttribPointersAboveAndIncluding( unsigned int index );
#else
inline void dirtyVertexAttribPointersAboveAndIncluding( unsigned int index )
{
while (index<_vertexAttribArrayList.size())
@@ -1377,6 +1485,7 @@ class OSG_EXPORT State : public Referenced
++index;
}
}
#endif
bool isVertexBufferObjectSupported() const { return _isVertexBufferObjectSupportResolved?_isVertexBufferObjectSupported:computeVertexBufferObjectSupported(); }

View File

@@ -21,8 +21,6 @@
namespace osg {
class VertexArrayState : public osg::Referenced
{
public:
@@ -31,113 +29,109 @@ public:
struct ArrayDispatch : public osg::Referenced
{
ArrayDispatch(Array* in_array):
array(in_array),
modifiedCount(0xffffffff) {}
ArrayDispatch():
array(0),
modifiedCount(0xffffffff),
active(false) {}
inline void dispatchIfDirty(osg::State& state, unsigned int index=0)
{
if (modifiedCount!=array->getModifiedCount()) dispatch(state, index);
}
virtual void enable_and_dispatch(osg::State& /*state*/, const osg::Array* /*new_array*/) {} // = 0;
virtual void dispatch(osg::State& state, unsigned int index=0) = 0;
virtual void enable_and_dispatch(osg::State& /*state*/, const osg::Array* /*new_array*/, const osg::GLBufferObject* /*vbo*/) {} // = 0;
virtual void dispatchDeprecated(osg::State& state, unsigned int index=0);
virtual void dispatch(osg::State& /*state*/, const osg::Array* /*new_array*/) {} // = 0;
osg::Array* array;
unsigned int modifiedCount;
virtual void dispatch(osg::State& /*state*/, const osg::Array* /*new_array*/, const osg::GLBufferObject* /*vbo*/) {} // = 0;
virtual void disable(osg::State& /*state*/) {} // = 0;
const osg::Array* array;
unsigned int modifiedCount;
bool active;
};
typedef std::vector< ref_ptr<ArrayDispatch> > ArrayDispatchList;
ArrayDispatchList& getArrayDispatchList(Array::Binding binding)
void setCurrentVertexBufferObject(osg::GLBufferObject* vbo) { _currentVBO = vbo; }
GLBufferObject* getCurrentVertexBufferObject() { return _currentVBO; }
inline void bindVertexBufferObject(osg::GLBufferObject* vbo)
{
switch(binding)
{
case(osg::Array::BIND_PER_VERTEX): return _dispatchArrays;
case(osg::Array::BIND_PER_PRIMITIVE_SET): return _dispatchPerPrimitiveSet;
default: return _dispatchOverall;
}
if (vbo == _currentVBO) return;
if (vbo->isDirty()) vbo->compileBuffer();
else vbo->bindBuffer();
_currentVBO = vbo;
}
inline void unbindVertexBufferObject()
{
if (!_currentVBO) return;
_ext->glBindBuffer(GL_ARRAY_BUFFER_ARB,0);
_currentVBO = 0;
}
enum VertexArrayIdentifier
void setCurrentElementBufferObject(osg::GLBufferObject* ebo) { _currentEBO = ebo; }
GLBufferObject* getCurrentElementBufferObject() { return _currentEBO; }
inline void bindElementBufferObject(osg::GLBufferObject* ebo)
{
VERTEX_ARRAY,
NORMAL_ARRAY,
COLOR_ARRAY,
SECONDARY_COLOR_ARRAY,
FOG_COORD_ARRAY,
TEX_COORD_ARRAY,
VERTEX_ATTRIB_ARRAY=TEX_COORD_ARRAY+32
};
void assignVertexArray(osg::Array* array);
void assignColorArray(osg::Array* array);
void assignNormalArray(osg::Array* array);
void assignSecondaryColorArray(osg::Array* array);
void assignFogCoordArray(osg::Array* array);
void assignTexCoordArray(unsigned int unit, osg::Array* array);
void assignVertexAttribArray(unsigned int unit, osg::Array* array);
inline void dispatchOverall(osg::State& state)
{
for(ArrayDispatchList::iterator itr = _dispatchOverall.begin();
itr != _dispatchOverall.end();
++itr)
{
(*(*itr)).dispatch(state);
}
if (ebo == _currentEBO) return;
if (ebo->isDirty()) ebo->compileBuffer();
else ebo->bindBuffer();
_currentEBO = ebo;
}
void dispatchPerPrimitveSet(osg::State& state, unsigned int index)
inline void unbindElementBufferObject()
{
for(ArrayDispatchList::iterator itr = _dispatchPerPrimitiveSet.begin();
itr != _dispatchPerPrimitiveSet.end();
++itr)
{
(*(*itr)).dispatch(state, index);
}
if (!_currentEBO) return;
_ext->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB,0);
_currentEBO = 0;
}
inline void dispatchArrays(osg::State& state)
{
// need to check previous enabled/disabled mode
void assignAllDispatchers();
if (_vertexArrayObject)
{
for(ArrayDispatchList::iterator itr = _dispatchArrays.begin();
itr != _dispatchArrays.end();
++itr)
{
(*(*itr)).dispatch(state);
}
}
else
{
for(ArrayDispatchList::iterator itr = _dispatchArrays.begin();
itr != _dispatchArrays.end();
++itr)
{
(*(*itr)).dispatchDeprecated(state);
}
}
}
virtual void assignVertexArrayDispatcher();
virtual void assignNormalArrayDispatcher();
virtual void assignColorArrayDispatcher();
virtual void assignSecondaryColorArrayDispatcher();
virtual void assignFogCoordArrayDispatcher();
virtual void assignTexCoordArrayDispatcher(unsigned int numUnits);
virtual void assignVertexAttribArrayDispatcher(unsigned int numUnits);
inline void dispatchArraysIfDirty(osg::State& state)
{
// need to check previous enabled/disabled mode
inline bool isVertexBufferObjectSupported() const { return true; }
void setArray(ArrayDispatch* vad, osg::State& state, const osg::Array* new_array);
void disable(ArrayDispatch* vad, osg::State& state) { vad->disable(state); vad->array=0; vad->modifiedCount=0xffffffff; vad->active=false; }
inline void setVertexArray(osg::State& state, const osg::Array* array) { setArray(_vertexArray.get(), state, array); }
inline void disableVertexArray(osg::State& state) { disable(_vertexArray.get(), state); }
inline void setNormalArray(osg::State& state, const osg::Array* array) { setArray(_normalArray.get(), state, array); }
inline void disableNormalArray(osg::State& state) { disable(_normalArray.get(), state); }
inline void setColorArray(osg::State& state, const osg::Array* array) { setArray(_colorArray.get(), state, array); }
inline void disableColorArray(osg::State& state) { disable(_colorArray.get(), state); }
inline void setSecondaryColorArray(osg::State& state, const osg::Array* array) { setArray(_secondaryColorArray.get(), state, array); }
inline void disableSecondaryColorArray(osg::State& state) { disable(_secondaryColorArray.get(), state); }
inline void setFogCoordArray(osg::State& state, const osg::Array* array) { setArray(_fogCoordArray.get(), state, array); }
inline void disableFogCoordArray(osg::State& state) { disable(_fogCoordArray.get(), state); }
inline void setTexCoordArray(osg::State& state, unsigned int unit, const osg::Array* array) { setArray(_texCoordArrays[unit].get(), state, array); }
inline void disableTexCoordArray(osg::State& state, unsigned int unit) { disable(_texCoordArrays[unit].get(),state); }
void disableTexCoordArrayAboveAndIncluding(osg::State& state, unsigned int index);
inline void setVertexAttribArray(osg::State& state, unsigned int unit, const osg::Array* array) { setArray(_vertexAttribArrays[unit].get(), state, array); }
inline void disableVertexAttribArray(osg::State& state, unsigned int unit) { disable(_vertexAttribArrays[unit].get(), state); }
void disableVertexAttribArrayAboveAndIncluding(osg::State& state, unsigned int index);
/** Mark all the vertex attributes as being disabled but leave the disabling till a later call to applyDisablingOfVertexAttributes.*/
void lazyDisablingOfVertexAttributes();
/** Disable all the vertex attributes that have been marked as to be disabled.*/
void applyDisablingOfVertexAttributes(osg::State& state);
for(ArrayDispatchList::iterator itr = _dispatchArrays.begin();
itr != _dispatchArrays.end();
++itr)
{
(*(*itr)).dispatchIfDirty(state);
}
}
@@ -154,49 +148,6 @@ public:
void setCurrentVertexBufferObject(osg::GLBufferObject* vbo) { _currentVBO = vbo; }
GLBufferObject* getCurrentVertexBufferObject() { return _currentVBO; }
inline void bindVertexBufferObject(osg::GLBufferObject* vbo)
{
if (vbo)
{
if (vbo == _currentVBO) return;
if (vbo->isDirty()) vbo->compileBuffer();
else vbo->bindBuffer();
_currentVBO = vbo;
}
else unbindVertexBufferObject();
}
inline void unbindVertexBufferObject()
{
if (!_currentVBO) return;
_ext->glBindBuffer(GL_ARRAY_BUFFER_ARB,0);
_currentVBO = 0;
}
void setCurrentElementBufferObject(osg::GLBufferObject* ebo) { _currentEBO = ebo; }
GLBufferObject* getCurrentElementBufferObject() { return _currentEBO; }
inline void bindElementBufferObject(osg::GLBufferObject* ebo)
{
if (ebo)
{
//if (ebo == _currentEBO) return;
if (ebo->isDirty()) ebo->compileBuffer();
else ebo->bindBuffer();
_currentEBO = ebo;
}
else unbindElementBufferObject();
}
inline void unbindElementBufferObject()
{
//if (!_currentEBO) return;
_ext->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB,0);
_currentEBO = 0;
}
public:
@@ -208,12 +159,21 @@ public:
GLuint _vertexArrayObject;
osg::ref_ptr<ArrayDispatch> _vertexArray;
osg::ref_ptr<ArrayDispatch> _normalArray;
osg::ref_ptr<ArrayDispatch> _colorArray;
osg::ref_ptr<ArrayDispatch> _secondaryColorArray;
osg::ref_ptr<ArrayDispatch> _fogCoordArray;
ArrayDispatchList _texCoordArrays;
ArrayDispatchList _vertexAttribArrays;
typedef std::vector<ArrayDispatch*> ActiveDispatchers;
ActiveDispatchers _activeDispatchers;
ActiveDispatchers _previous_activeDispatchers;
GLBufferObject* _currentVBO;
GLBufferObject* _currentEBO;
ArrayDispatchList _dispatchOverall;
ArrayDispatchList _dispatchPerPrimitiveSet;
ArrayDispatchList _dispatchArrays;
};