diff --git a/include/osg/State b/include/osg/State index 5017c0c0b..5d4b93929 100644 --- a/include/osg/State +++ b/include/osg/State @@ -1238,12 +1238,62 @@ class OSG_EXPORT State : public Referenced, public Observer } } + /** 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) + { + if (array) + { + GLBufferObject* vbo = array->getOrCreateGLBufferObject(_contextID); + if (vbo) + { + bindVertexBufferObject(vbo); + setVertexAttribLPointer(unit, array->getDataSize(),array->getDataType(),0,(const GLvoid *)(vbo->getOffset(array->getBufferIndex()))); + } + else + { + unbindVertexBufferObject(); + setVertexAttribLPointer(unit, array->getDataSize(),array->getDataType(),0,array->getDataPointer()); + } + } + } + + /** 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) + { + if (array) + { + GLBufferObject* vbo = array->getOrCreateGLBufferObject(_contextID); + if (vbo) + { + bindVertexBufferObject(vbo); + setVertexAttribIPointer(unit, array->getDataSize(),array->getDataType(),0,(const GLvoid *)(vbo->getOffset(array->getBufferIndex()))); + } + else + { + unbindVertexBufferObject(); + setVertexAttribIPointer(unit, array->getDataSize(),array->getDataType(),0,array->getDataPointer()); + } + } + } + /** wrapper around glEnableVertexAttribArrayARB(index);glVertexAttribPointerARB(..); * note, only updates values that change.*/ void setVertexAttribPointer( unsigned int index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *ptr ); + /** wrapper around glEnableVertexAttribArrayARB(index);glVertexAttribIPointer(..); + * note, only updates values that change.*/ + void setVertexAttribIPointer( unsigned int index, + GLint size, GLenum type, + GLsizei stride, const GLvoid *ptr ); + + /** wrapper around glEnableVertexAttribArrayARB(index);glVertexAttribLPointer(..); + * note, only updates values that change.*/ + void setVertexAttribLPointer( unsigned int index, + GLint size, GLenum type, + GLsizei stride, const GLvoid *ptr ); + /** wrapper around DisableVertexAttribArrayARB(index); * note, only updates values that change.*/ void disableVertexAttribPointer( unsigned int index ); @@ -1839,6 +1889,8 @@ class OSG_EXPORT State : public Referenced, public Observer typedef void (GL_APIENTRY * VertexAttrib4fProc)(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (GL_APIENTRY * VertexAttrib4fvProc)(GLuint index, const GLfloat *v); typedef void (GL_APIENTRY * VertexAttribPointerProc) (unsigned int, GLint, GLenum, GLboolean normalized, GLsizei stride, const GLvoid *pointer); + typedef void (GL_APIENTRY * VertexAttribIPointerProc) (unsigned int, GLint, GLenum, GLsizei stride, const GLvoid *pointer); + typedef void (GL_APIENTRY * VertexAttribLPointerProc) (unsigned int, GLint, GLenum, GLsizei stride, const GLvoid *pointer); typedef void (GL_APIENTRY * EnableVertexAttribProc) (unsigned int); typedef void (GL_APIENTRY * DisableVertexAttribProc) (unsigned int); typedef void (GL_APIENTRY * BindBufferProc) (GLenum target, GLuint buffer); @@ -1857,6 +1909,8 @@ class OSG_EXPORT State : public Referenced, public Observer FogCoordPointerProc _glFogCoordPointer; SecondaryColorPointerProc _glSecondaryColorPointer; VertexAttribPointerProc _glVertexAttribPointer; + VertexAttribIPointerProc _glVertexAttribIPointer; + VertexAttribLPointerProc _glVertexAttribLPointer; EnableVertexAttribProc _glEnableVertexAttribArray; DisableVertexAttribProc _glDisableVertexAttribArray; BindBufferProc _glBindBuffer; diff --git a/src/osg/Geometry.cpp b/src/osg/Geometry.cpp index cbff518fa..d758e939f 100644 --- a/src/osg/Geometry.cpp +++ b/src/osg/Geometry.cpp @@ -752,14 +752,24 @@ void Geometry::drawImplementation(RenderInfo& renderInfo) const } } - if( handleVertexAttributes ) + if ( handleVertexAttributes ) { - for(unsigned int index = 0; index < _vertexAttribList.size(); ++index ) + for(unsigned int index = 0; index < _vertexAttribList.size(); ++index) { const Array* array = _vertexAttribList[index].get(); - if(array && array->getBinding()==osg::Array::BIND_PER_VERTEX) + if (array && array->getBinding()==osg::Array::BIND_PER_VERTEX) { - state.setVertexAttribPointer( index, array ); + if (array->getPreserveDataType()) + { + GLenum dataType = array->getDataType(); + if (dataType==GL_FLOAT) state.setVertexAttribPointer( index, array ); + else if (dataType==GL_DOUBLE) state.setVertexAttribLPointer( index, array ); + else state.setVertexAttribIPointer( index, array ); + } + else + { + state.setVertexAttribPointer( index, array ); + } } } } diff --git a/src/osg/State.cpp b/src/osg/State.cpp index 8816474e7..65a8b5b6c 100644 --- a/src/osg/State.cpp +++ b/src/osg/State.cpp @@ -103,6 +103,8 @@ State::State(): _glFogCoordPointer = 0; _glSecondaryColorPointer = 0; _glVertexAttribPointer = 0; + _glVertexAttribIPointer = 0; + _glVertexAttribLPointer = 0; _glEnableVertexAttribArray = 0; _glDisableVertexAttribArray = 0; _glDrawArraysInstanced = 0; @@ -902,6 +904,8 @@ void State::initializeExtensionProcs() setGLExtensionFuncPtr(_glFogCoordPointer, "glFogCoordPointer","glFogCoordPointerEXT"); setGLExtensionFuncPtr(_glSecondaryColorPointer, "glSecondaryColorPointer","glSecondaryColorPointerEXT"); setGLExtensionFuncPtr(_glVertexAttribPointer, "glVertexAttribPointer","glVertexAttribPointerARB"); + setGLExtensionFuncPtr(_glVertexAttribIPointer, "glVertexAttribIPointer"); + setGLExtensionFuncPtr(_glVertexAttribLPointer, "glVertexAttribLPointer","glVertexAttribPointerARB"); setGLExtensionFuncPtr(_glEnableVertexAttribArray, "glEnableVertexAttribArray","glEnableVertexAttribArrayARB"); setGLExtensionFuncPtr(_glMultiTexCoord4f, "glMultiTexCoord4f","glMultiTexCoord4fARB"); setGLExtensionFuncPtr(_glVertexAttrib4f, "glVertexAttrib4f"); @@ -1075,6 +1079,66 @@ void State::setVertexAttribPointer( unsigned int index, } } +/** wrapper around glEnableVertexAttribArrayARB(index);glVertexAttribIPointer(..); +* note, only updates values that change.*/ +void State::setVertexAttribIPointer( unsigned int index, + GLint size, GLenum type, + GLsizei stride, const GLvoid *ptr ) +{ + if (_glVertexAttribIPointer) + { + // OSG_NOTICE<<"State::setVertexAttribIPointer("<= _vertexAttribArrayList.size()) _vertexAttribArrayList.resize(index+1); + EnabledArrayPair& eap = _vertexAttribArrayList[index]; + + if (!eap._enabled || eap._dirty) + { + eap._enabled = true; + // OSG_NOTICE<<" _glEnableVertexAttribArray( "<= _vertexAttribArrayList.size()) _vertexAttribArrayList.resize(index+1); + EnabledArrayPair& eap = _vertexAttribArrayList[index]; + + if (!eap._enabled || eap._dirty) + { + eap._enabled = true; + // OSG_NOTICE<<" _glEnableVertexAttribArray( "<