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:
@@ -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
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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(); }
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user