Moved VBO switching code into inline methods into osg::State to speed performance
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user