Moved VBO switching code into inline methods into osg::State to speed performance

This commit is contained in:
Robert Osfield
2007-05-01 06:28:20 +00:00
parent a67111a64c
commit 40db1a8934
12 changed files with 377 additions and 79 deletions

View File

@@ -269,16 +269,16 @@ class OSG_EXPORT VertexBufferObject : public BufferObject
};
class DrawElements;
class OSG_EXPORT ElementsBufferObject : public BufferObject
class OSG_EXPORT ElementBufferObject : public BufferObject
{
public:
ElementsBufferObject();
ElementBufferObject();
/** Copy constructor using CopyOp to manage deep vs shallow copy.*/
ElementsBufferObject(const ElementsBufferObject& pbo,const CopyOp& copyop=CopyOp::SHALLOW_COPY);
ElementBufferObject(const ElementBufferObject& pbo,const CopyOp& copyop=CopyOp::SHALLOW_COPY);
META_Object(osg,ElementsBufferObject);
META_Object(osg,ElementBufferObject);
typedef std::pair< BufferEntry, DrawElements* > BufferEntryDrawElementstPair;
typedef std::vector< BufferEntryDrawElementstPair > BufferEntryDrawElementsPairs;
@@ -297,7 +297,7 @@ class OSG_EXPORT ElementsBufferObject : public BufferObject
protected:
virtual ~ElementsBufferObject();
virtual ~ElementBufferObject();
BufferEntryDrawElementsPairs _bufferEntryDrawElementsPairs;
};

View File

@@ -308,7 +308,7 @@ class OSG_EXPORT Geometry : public Drawable
osg::VertexBufferObject* getOrCreateVertexBufferObject();
osg::ElementsBufferObject* getOrCreateElementsBufferObject();
osg::ElementBufferObject* getOrCreateElementBufferObject();
/** Set whether fast paths should be used when supported. */
@@ -394,7 +394,7 @@ class OSG_EXPORT Geometry : public Drawable
void computeCorrectBindingsAndArraySizes(Vec3ArrayData& arrayData,const char* arrayName);
void addVertexBufferObjectIfRequired(osg::Array* array);
void addElementsBufferObjectIfRequired(osg::PrimitiveSet* primitiveSet);
void addElementBufferObjectIfRequired(osg::PrimitiveSet* primitiveSet);
PrimitiveSetList _primitives;

View File

@@ -425,8 +425,8 @@ class DrawElements : public PrimitiveSet
virtual void dirty() { ++_modifiedCount; if (_ebo.valid()) _ebo->dirty(); }
/** Set the ElementsBufferObject.*/
inline void setElementsBufferObject(osg::ElementsBufferObject* ebo)
/** Set the ElementBufferObject.*/
inline void setElementBufferObject(osg::ElementBufferObject* ebo)
{
if (_ebo == ebo) return;
@@ -446,17 +446,17 @@ class DrawElements : public PrimitiveSet
}
}
/** Get the ElementsBufferObject. If no EBO is assigned returns NULL*/
inline osg::ElementsBufferObject* getElementsBufferObject() { return _ebo.get(); }
/** Get the ElementBufferObject. If no EBO is assigned returns NULL*/
inline osg::ElementBufferObject* getElementBufferObject() { return _ebo.get(); }
/** Get the const ElementsBufferObject. If no EBO is assigned returns NULL*/
inline const osg::ElementsBufferObject* getElementsBufferObject() const { return _ebo.get(); }
/** Get the const ElementBufferObject. If no EBO is assigned returns NULL*/
inline const osg::ElementBufferObject* getElementBufferObject() const { return _ebo.get(); }
/** Set the index into the ElementsBufferObject, if used.*/
inline void setElementsBufferObjectIndex(unsigned int index) { _eboIndex = index; }
/** Set the index into the ElementBufferObject, if used.*/
inline void setElementBufferObjectIndex(unsigned int index) { _eboIndex = index; }
/** Get the index into the ElementsBufferObject, if used.*/
inline unsigned int getElementsBufferObjectIndex() const { return _eboIndex; }
/** Get the index into the ElementBufferObject, if used.*/
inline unsigned int getElementBufferObjectIndex() const { return _eboIndex; }
protected:
@@ -469,7 +469,7 @@ class DrawElements : public PrimitiveSet
}
}
osg::ref_ptr<ElementsBufferObject> _ebo;
osg::ref_ptr<ElementBufferObject> _ebo;
unsigned int _eboIndex;
};

View File

@@ -18,6 +18,7 @@
#include <osg/StateSet>
#include <osg/Matrix>
#include <osg/Uniform>
#include <osg/BufferObject>
#include <osg/FrameStamp>
#include <osg/DisplaySettings>
@@ -403,11 +404,86 @@ class OSG_EXPORT State : public Referenced
void dirtyAllVertexArrays();
void setCurrentVertexBufferObject(osg::VertexBufferObject* vbo) { _currentVBO = vbo; }
const VertexBufferObject* getCurrentVertexBufferObject() { return _currentVBO; }
inline void bindVertexBufferObject(const osg::VertexBufferObject* vbo)
{
if (vbo == _currentVBO) return;
if (vbo->isDirty(_contextID)) vbo->compileBuffer(_contextID, *this);
else _glBindBuffer(GL_ARRAY_BUFFER_ARB,vbo->buffer(_contextID));
_currentVBO = vbo;
}
inline void unbindVertexBufferObject()
{
if (!_currentVBO) return;
_glBindBuffer(GL_ARRAY_BUFFER_ARB,0);
_currentVBO = 0;
}
void setCurrentElementBufferObject(osg::ElementBufferObject* ebo) { _currentEBO = ebo; }
const ElementBufferObject* getCurrentElementBufferObject() { return _currentEBO; }
inline void bindElementBufferObject(const osg::ElementBufferObject* ebo)
{
if (ebo == _currentEBO) return;
if (ebo->isDirty(_contextID)) ebo->compileBuffer(_contextID, *this);
else _glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB,ebo->buffer(_contextID));
_currentEBO = ebo;
}
inline void unbindElementBufferObject()
{
if (!_currentEBO) return;
_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB,0);
_currentEBO = 0;
}
void setCurrentPixelBufferObject(osg::PixelBufferObject* pbo) { _currentPBO = pbo; }
const PixelBufferObject* getCurrentPixelBufferObject() { return _currentPBO; }
inline void bindPixelBufferObject(const osg::PixelBufferObject* pbo)
{
if (pbo == _currentPBO) return;
if (pbo->isDirty(_contextID)) pbo->compileBuffer(_contextID, *this);
else _glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB,pbo->buffer(_contextID));
_currentPBO = pbo;
}
inline void unbindPixelBufferObject()
{
if (!_currentPBO) return;
_glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB,0);
_currentPBO = 0;
}
/** Wrapper around glInterleavedArrays(..).
* also resets the internal array points and modes within osg::State to keep the other
* vertex array operations consistent. */
void setInterleavedArrays( GLenum format, GLsizei stride, const GLvoid* pointer);
/** Set the vertex pointer using an osg::Array, and manage any VBO that are required.*/
inline void setVertexPointer(const Array* array)
{
if (array)
{
const VertexBufferObject* vbo = array->getVertexBufferObject();
if (vbo)
{
bindVertexBufferObject(vbo);
setVertexPointer(array->getDataSize(),array->getDataType(),0,vbo->getOffset(array->getVertexBufferObjectIndex()));
}
else
{
unbindVertexBufferObject();
setVertexPointer(array->getDataSize(),array->getDataType(),0,array->getDataPointer());
}
}
else disableVertexPointer();
}
/** wrapper around glEnableClientState(GL_VERTEX_ARRAY);glVertexPointer(..);
* note, only updates values that change.*/
@@ -445,6 +521,27 @@ class OSG_EXPORT State : public Referenced
_vertexArray._dirty = true;
}
/** Set the normal pointer using an osg::Array, and manage any VBO that are required.*/
inline void setNormalPointer(const Array* array)
{
if (array)
{
const VertexBufferObject* vbo = array->getVertexBufferObject();
if (vbo)
{
bindVertexBufferObject(vbo);
setNormalPointer(array->getDataType(),0,vbo->getOffset(array->getVertexBufferObjectIndex()));
}
else
{
unbindVertexBufferObject();
setNormalPointer(array->getDataType(),0,array->getDataPointer());
}
}
else disableNormalPointer();
}
/** wrapper around glEnableClientState(GL_NORMAL_ARRAY);glNormalPointer(..);
* note, only updates values that change.*/
inline void setNormalPointer( GLenum type, GLsizei stride,
@@ -481,6 +578,27 @@ class OSG_EXPORT State : public Referenced
_normalArray._dirty = true;
}
/** Set the color pointer using an osg::Array, and manage any VBO that are required.*/
inline void setColorPointer(const Array* array)
{
if (array)
{
const VertexBufferObject* vbo = array->getVertexBufferObject();
if (vbo)
{
bindVertexBufferObject(vbo);
setColorPointer(array->getDataSize(),array->getDataType(),0,vbo->getOffset(array->getVertexBufferObjectIndex()));
}
else
{
unbindVertexBufferObject();
setColorPointer(array->getDataSize(),array->getDataType(),0,array->getDataPointer());
}
}
else disableColorPointer();
}
/** wrapper around glEnableClientState(GL_COLOR_ARRAY);glColorPointer(..);
* note, only updates values that change.*/
inline void setColorPointer( GLint size, GLenum type,
@@ -520,6 +638,27 @@ class OSG_EXPORT State : public Referenced
inline bool isSecondaryColorSupported() const { return _isSecondaryColorSupportResolved?_isSecondaryColorSupported:computeSecondaryColorSupported(); }
/** Set the secondary color pointer using an osg::Array, and manage any VBO that are required.*/
inline void setSecondaryColorPointer(const Array* array)
{
if (array)
{
const VertexBufferObject* vbo = array->getVertexBufferObject();
if (vbo)
{
bindVertexBufferObject(vbo);
setSecondaryColorPointer(array->getDataSize(),array->getDataType(),0,vbo->getOffset(array->getVertexBufferObjectIndex()));
}
else
{
unbindVertexBufferObject();
setSecondaryColorPointer(array->getDataSize(),array->getDataType(),0,array->getDataPointer());
}
}
else disableSecondaryColorPointer();
}
/** 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 );
@@ -581,6 +720,28 @@ class OSG_EXPORT State : public Referenced
inline bool isFogCoordSupported() const { return _isFogCoordSupportResolved?_isFogCoordSupported:computeFogCoordSupported(); }
/** Set the fog coord pointer using an osg::Array, and manage any VBO that are required.*/
inline void setFogCoordPointer(const Array* array)
{
if (array)
{
const VertexBufferObject* vbo = array->getVertexBufferObject();
if (vbo)
{
bindVertexBufferObject(vbo);
setFogCoordPointer(array->getDataType(),0,vbo->getOffset(array->getVertexBufferObjectIndex()));
}
else
{
unbindVertexBufferObject();
setFogCoordPointer(array->getDataType(),0,array->getDataPointer());
}
}
else disableFogCoordPointer();
}
/** wrapper around glEnableClientState(GL_FOG_COORDINATE_ARRAY);glFogCoordPointer(..);
* note, only updates values that change.*/
void setFogCoordPointer( GLenum type, GLsizei stride, const GLvoid *ptr );
@@ -604,6 +765,27 @@ class OSG_EXPORT State : public Referenced
}
/** 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)
{
if (array)
{
const VertexBufferObject* vbo = array->getVertexBufferObject();
if (vbo)
{
bindVertexBufferObject(vbo);
setTexCoordPointer(unit, array->getDataSize(),array->getDataType(),0,vbo->getOffset(array->getVertexBufferObjectIndex()));
}
else
{
unbindVertexBufferObject();
setTexCoordPointer(unit, array->getDataSize(),array->getDataType(),0,array->getDataPointer());
}
}
else disableTexCoordPointer(unit);
}
/** wrapper around glEnableClientState(GL_TEXTURE_COORD_ARRAY);glTexCoordPointer(..);
* note, only updates values that change.*/
inline void setTexCoordPointer( unsigned int unit,
@@ -702,6 +884,26 @@ class OSG_EXPORT State : public Referenced
/** Get the current tex coord array texture unit.*/
unsigned int getClientActiveTextureUnit() const { return _currentClientActiveTextureUnit; }
/** 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, GLboolean normalized)
{
if (array)
{
const VertexBufferObject* vbo = array->getVertexBufferObject();
if (vbo)
{
bindVertexBufferObject(vbo);
setVertexAttribPointer(unit, array->getDataSize(),array->getDataType(),normalized,0,vbo->getOffset(array->getVertexBufferObjectIndex()));
}
else
{
unbindVertexBufferObject();
setVertexAttribPointer(unit, array->getDataSize(),array->getDataType(),normalized,0,array->getDataPointer());
}
}
else disableVertexAttribPointer(unit);
}
/** wrapper around glEnableVertexAttribArrayARB(index);glVertexAttribPointerARB(..);
* note, only updates values that change.*/
void setVertexAttribPointer( unsigned int index,
@@ -825,6 +1027,10 @@ class OSG_EXPORT State : public Referenced
bool checkGLErrors(StateAttribute::GLMode mode) const;
bool checkGLErrors(const StateAttribute* attribute) const;
/** Initialize extension used by osg:::State.*/
void initializeExtensionProcs();
protected:
virtual ~State();
@@ -1007,6 +1213,10 @@ class OSG_EXPORT State : public Referenced
unsigned int _currentActiveTextureUnit;
unsigned int _currentClientActiveTextureUnit;
const VertexBufferObject* _currentVBO;
const ElementBufferObject* _currentEBO;
const PixelBufferObject* _currentPBO;
inline ModeMap& getOrCreateTextureModeMap(unsigned int unit)
{
@@ -1063,6 +1273,7 @@ class OSG_EXPORT State : public Referenced
typedef void (APIENTRY * VertexAttribPointerProc) (unsigned int, GLint, GLenum, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
typedef void (APIENTRY * EnableVertexAttribProc) (unsigned int);
typedef void (APIENTRY * DisableVertexAttribProc) (unsigned int);
typedef void (APIENTRY * BindBufferProc) (GLenum target, GLuint buffer);
bool _extensionProcsInitialized;
@@ -1073,7 +1284,8 @@ class OSG_EXPORT State : public Referenced
VertexAttribPointerProc _glVertexAttribPointer;
EnableVertexAttribProc _glEnableVertexAttribArray;
DisableVertexAttribProc _glDisableVertexAttribArray;
void initializeExtensionProcs();
BindBufferProc _glBindBuffer;
unsigned int _dynamicObjectCount;
osg::ref_ptr<DynamicObjectRenderingCompletedCallback> _completeDynamicObjectRenderingCallback;