From 40db1a8934347c859d653ccc852acf658dfd17e2 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 1 May 2007 06:28:20 +0000 Subject: [PATCH] Moved VBO switching code into inline methods into osg::State to speed performance --- examples/osgparametric/osgparametric.cpp | 4 +- include/osg/BufferObject | 10 +- include/osg/Geometry | 4 +- include/osg/PrimitiveSet | 22 +-- include/osg/State | 214 ++++++++++++++++++++++- src/osg/BufferObject.cpp | 24 +-- src/osg/Geometry.cpp | 99 ++++++++--- src/osg/PrimitiveSet.cpp | 51 +++++- src/osg/State.cpp | 19 +- src/osgUtil/SceneView.cpp | 5 +- src/osgViewer/CompositeViewer.cpp | 2 + src/osgViewer/Viewer.cpp | 2 + 12 files changed, 377 insertions(+), 79 deletions(-) diff --git a/examples/osgparametric/osgparametric.cpp b/examples/osgparametric/osgparametric.cpp index eca35b106..372cf028b 100644 --- a/examples/osgparametric/osgparametric.cpp +++ b/examples/osgparametric/osgparametric.cpp @@ -223,7 +223,7 @@ osg::Node* createModel(const std::string& shader, const std::string& textureFile osg::VertexBufferObject* vbObject = new osg::VertexBufferObject; vertices->setVertexBufferObject(vbObject); - osg::ElementsBufferObject* ebo = new osg::ElementsBufferObject; + osg::ElementBufferObject* ebo = new osg::ElementBufferObject; for(iy=0; iyaddPrimitiveSet(elements); - if (ebo) elements->setElementsBufferObject(ebo); + if (ebo) elements->setElementBufferObject(ebo); } geom->setUseVertexBufferObjects(vbo); diff --git a/include/osg/BufferObject b/include/osg/BufferObject index 0040e85b1..12db68bf7 100644 --- a/include/osg/BufferObject +++ b/include/osg/BufferObject @@ -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; }; diff --git a/include/osg/Geometry b/include/osg/Geometry index 190279ed8..b1012ab9b 100644 --- a/include/osg/Geometry +++ b/include/osg/Geometry @@ -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; diff --git a/include/osg/PrimitiveSet b/include/osg/PrimitiveSet index 49fb3e94b..69c39c9d3 100644 --- a/include/osg/PrimitiveSet +++ b/include/osg/PrimitiveSet @@ -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 _ebo; + osg::ref_ptr _ebo; unsigned int _eboIndex; }; diff --git a/include/osg/State b/include/osg/State index 8830890e8..9a9c9066c 100644 --- a/include/osg/State +++ b/include/osg/State @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -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 _completeDynamicObjectRenderingCallback; diff --git a/src/osg/BufferObject.cpp b/src/osg/BufferObject.cpp index 03877a78c..a0ad8fa3d 100644 --- a/src/osg/BufferObject.cpp +++ b/src/osg/BufferObject.cpp @@ -457,8 +457,6 @@ void VertexBufferObject::compileBufferImplementation(State& state) const // Unmap the texture image buffer if (vboMemory) extensions->glUnmapBuffer(_target); - - extensions->glBindBuffer(_target, 0); // osg::notify(osg::NOTICE)<<"pbo _totalSize="<<_totalSize<delta_m(start_tick,osg::Timer::instance()->tick())<<"ms"<=_bufferEntryDrawElementsPairs.size()) _bufferEntryDrawElementsPairs.resize(i+1); @@ -503,7 +501,7 @@ void ElementsBufferObject::setDrawElements(unsigned int i, DrawElements* drawEle _bufferEntryDrawElementsPairs[i].first.dataSize = 0; } -bool ElementsBufferObject::needsCompile(unsigned int contextID) const +bool ElementBufferObject::needsCompile(unsigned int contextID) const { if (isDirty(contextID)) return true; @@ -538,13 +536,13 @@ bool ElementsBufferObject::needsCompile(unsigned int contextID) const return false; } -void ElementsBufferObject::compileBufferImplementation(State& state) const +void ElementBufferObject::compileBufferImplementation(State& state) const { unsigned int contextID = state.getContextID(); _compiledList[contextID] = 1; - osg::notify(osg::NOTICE)<<"ElementsBufferObject::compile"<glUnmapBuffer(_target); - extensions->glBindBuffer(_target, 0); - // osg::notify(osg::NOTICE)<<"pbo _totalSize="<<_totalSize<delta_m(start_tick,osg::Timer::instance()->tick())<<"ms"<glUnmapBuffer(_target); - extensions->glBindBuffer(_target, 0); - _bufferEntryImagePair.first.modifiedCount[contextID] = image->getModifiedCount(); // osg::notify(osg::NOTICE)<<"pbo _totalSize="<<_totalSize<getDrawElements(); - if (drawElements && !drawElements->getElementsBufferObject()) + if (drawElements && !drawElements->getElementBufferObject()) { - drawElements->setElementsBufferObject(getOrCreateElementsBufferObject()); + drawElements->setElementBufferObject(getOrCreateElementBufferObject()); } } } @@ -1112,12 +1112,12 @@ osg::VertexBufferObject* Geometry::getOrCreateVertexBufferObject() return vbo; } -osg::ElementsBufferObject* Geometry::getOrCreateElementsBufferObject() +osg::ElementBufferObject* Geometry::getOrCreateElementBufferObject() { DrawElementsList drawElementsList; getDrawElementsList(drawElementsList); - osg::ElementsBufferObject* ebo = 0; + osg::ElementBufferObject* ebo = 0; DrawElementsList::iterator deitr; for(deitr = drawElementsList.begin(); @@ -1125,10 +1125,10 @@ osg::ElementsBufferObject* Geometry::getOrCreateElementsBufferObject() ++deitr) { osg::DrawElements* elements = *deitr; - if (!elements->getElementsBufferObject()) ebo = elements->getElementsBufferObject(); + if (!elements->getElementBufferObject()) ebo = elements->getElementBufferObject(); } - if (!ebo) ebo = new osg::ElementsBufferObject; + if (!ebo) ebo = new osg::ElementBufferObject; return ebo; } @@ -1150,7 +1150,7 @@ void Geometry::setUseVertexBufferObjects(bool flag) getDrawElementsList(drawElementsList); typedef std::vector VertexBufferObjectList; - typedef std::vector ElementsBufferObjectList; + typedef std::vector ElementBufferObjectList; if (_useVertexBufferObjects) { @@ -1183,9 +1183,9 @@ void Geometry::setUseVertexBufferObjects(bool flag) if (!drawElementsList.empty()) { - ElementsBufferObjectList eboList; + ElementBufferObjectList eboList; - osg::ElementsBufferObject* ebo = 0; + osg::ElementBufferObject* ebo = 0; DrawElementsList::iterator deitr; for(deitr = drawElementsList.begin(); @@ -1193,17 +1193,17 @@ void Geometry::setUseVertexBufferObjects(bool flag) ++deitr) { osg::DrawElements* elements = *deitr; - if (!elements->getElementsBufferObject()) ebo = elements->getElementsBufferObject(); + if (!elements->getElementBufferObject()) ebo = elements->getElementBufferObject(); } - if (!ebo) ebo = new osg::ElementsBufferObject; + if (!ebo) ebo = new osg::ElementBufferObject; for(deitr = drawElementsList.begin(); deitr != drawElementsList.end(); ++deitr) { osg::DrawElements* elements = *deitr; - if (!elements->getElementsBufferObject()) elements->setElementsBufferObject(ebo); + if (!elements->getElementBufferObject()) elements->setElementBufferObject(ebo); } } } @@ -1222,7 +1222,7 @@ void Geometry::setUseVertexBufferObjects(bool flag) ++deitr) { osg::DrawElements* elements = *deitr; - if (!elements->getElementsBufferObject()) elements->setElementsBufferObject(0); + if (!elements->getElementBufferObject()) elements->setElementBufferObject(0); } } } @@ -1416,6 +1416,59 @@ void Geometry::drawImplementation(RenderInfo& renderInfo) const // #if 1 + + #if 1 + + + state.setNormalPointer(_normalData.binding==BIND_PER_VERTEX ? _normalData.array.get() : 0); + state.setColorPointer(_colorData.binding==BIND_PER_VERTEX ? _colorData.array.get() : 0); + state.setSecondaryColorPointer(_secondaryColorData.binding==BIND_PER_VERTEX ? _secondaryColorData.array.get() : 0); + state.setFogCoordPointer(_fogCoordData.binding==BIND_PER_VERTEX ? _fogCoordData.array.get() : 0); + + unsigned int unit; + for(unit=0;unit<_texCoordList.size();++unit) + { + state.setTexCoordPointer(unit, _texCoordList[unit].array.get()); + } + state.disableTexCoordPointersAboveAndIncluding(unit); + + if( handleVertexAttributes ) + { + unsigned int index; + for( index = 0; index < _vertexAttribList.size(); ++index ) + { + const Array* array = _vertexAttribList[index].array.get(); + const AttributeBinding ab = _vertexAttribList[index].binding; + state.setVertexAttribPointer(index, (ab==BIND_PER_VERTEX ? array : 0), _vertexAttribList[index].normalize); + + if(array && ab!=BIND_PER_VERTEX) + { + const IndexArray* indexArray = _vertexAttribList[index].indices.get(); + + if( indexArray && indexArray->getNumElements() > 0 ) + { + drawVertexAttribMap[ab].push_back( + new DrawVertexAttrib(extensions,index,_vertexAttribList[index].normalize,array,indexArray) ); + } + else + { + drawVertexAttribMap[ab].push_back( + new DrawVertexAttrib(extensions,index,_vertexAttribList[index].normalize,array,0) ); + } + } + } + state.disableVertexAttribPointersAboveAndIncluding( index ); + + } + else if (vertexVertexAttributesSupported) + { + state.disableVertexAttribPointersAboveAndIncluding( 0 ); + } + + state.setVertexPointer(_vertexData.array.get()); + + #else + // first compile the VBO's const VertexBufferObject* prev_vbo = 0; const VertexBufferObject* new_vbo = 0; @@ -1519,8 +1572,8 @@ void Geometry::drawImplementation(RenderInfo& renderInfo) const SETARRAYPOINTER(_vertexData, state.setVertexPointer, state.disableVertexPointer) - const osg::ElementsBufferObject* prev_ebo = 0; - const osg::ElementsBufferObject* new_ebo = 0; + const osg::ElementBufferObject* prev_ebo = 0; + const osg::ElementBufferObject* new_ebo = 0; for(PrimitiveSetList::const_iterator itr=_primitives.begin(); itr!=_primitives.end(); ++itr) @@ -1528,7 +1581,7 @@ void Geometry::drawImplementation(RenderInfo& renderInfo) const const DrawElements* de = (*itr)->getDrawElements(); if (de) { - new_ebo = de->getElementsBufferObject(); + new_ebo = de->getElementBufferObject(); if (new_ebo && new_ebo!=prev_ebo) { new_ebo->compileBuffer(contextID, state); @@ -1537,6 +1590,8 @@ void Geometry::drawImplementation(RenderInfo& renderInfo) const } } + #endif + #else GLuint& buffer = _vboList[state.getContextID()]; @@ -1861,7 +1916,9 @@ void Geometry::drawImplementation(RenderInfo& renderInfo) const if (usingVertexBufferObjects) { - extensions->glBindBuffer(GL_ARRAY_BUFFER_ARB,0); + // extensions->glBindBuffer(GL_ARRAY_BUFFER_ARB,0); + state.unbindVertexBufferObject(); + state.unbindElementBufferObject(); } } diff --git a/src/osg/PrimitiveSet.cpp b/src/osg/PrimitiveSet.cpp index 5bb8aad3a..286c349ad 100644 --- a/src/osg/PrimitiveSet.cpp +++ b/src/osg/PrimitiveSet.cpp @@ -155,16 +155,28 @@ void DrawElementsUByte::draw(State& state, bool useVertexBufferObjects) const if (useVertexBufferObjects) { #if 1 + #if 1 + const ElementBufferObject* ebo = getElementBufferObject(); + state.bindElementBufferObject(ebo); + if (ebo) + { + glDrawElements(_mode, size(), GL_UNSIGNED_BYTE, ebo->getOffset(getElementBufferObjectIndex())); + } + else + { + glDrawElements(_mode, size(), GL_UNSIGNED_BYTE, &front()); + } + #else unsigned int contextID = state.getContextID(); const BufferObject::Extensions* extensions = BufferObject::getExtensions(contextID, true); - const ElementsBufferObject* ebo = getElementsBufferObject(); + const ElementBufferObject* ebo = getElementBufferObject(); if (ebo) { //ebo->compileBuffer(state); ebo->bindBuffer(contextID); - glDrawElements(_mode, size(), GL_UNSIGNED_BYTE, ebo->getOffset(getElementsBufferObjectIndex())); + glDrawElements(_mode, size(), GL_UNSIGNED_BYTE, ebo->getOffset(getElementBufferObjectIndex())); extensions->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); } @@ -172,6 +184,7 @@ void DrawElementsUByte::draw(State& state, bool useVertexBufferObjects) const { glDrawElements(_mode, size(), GL_UNSIGNED_INT, &front()); } + #endif #else unsigned int contextID = state.getContextID(); const BufferObject::Extensions* extensions = BufferObject::getExtensions(contextID, true); @@ -268,16 +281,28 @@ void DrawElementsUShort::draw(State& state, bool useVertexBufferObjects) const if (useVertexBufferObjects) { #if 1 + #if 1 + const ElementBufferObject* ebo = getElementBufferObject(); + state.bindElementBufferObject(ebo); + if (ebo) + { + glDrawElements(_mode, size(), GL_UNSIGNED_SHORT, ebo->getOffset(getElementBufferObjectIndex())); + } + else + { + glDrawElements(_mode, size(), GL_UNSIGNED_SHORT, &front()); + } + #else unsigned int contextID = state.getContextID(); const BufferObject::Extensions* extensions = BufferObject::getExtensions(contextID, true); - const ElementsBufferObject* ebo = getElementsBufferObject(); + const ElementBufferObject* ebo = getElementBufferObject(); if (ebo) { //ebo->compileBuffer(state); ebo->bindBuffer(contextID); - glDrawElements(_mode, size(), GL_UNSIGNED_SHORT, ebo->getOffset(getElementsBufferObjectIndex())); + glDrawElements(_mode, size(), GL_UNSIGNED_SHORT, ebo->getOffset(getElementBufferObjectIndex())); extensions->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); } @@ -285,6 +310,7 @@ void DrawElementsUShort::draw(State& state, bool useVertexBufferObjects) const { glDrawElements(_mode, size(), GL_UNSIGNED_INT, &front()); } + #endif #else unsigned int contextID = state.getContextID(); const BufferObject::Extensions* extensions = BufferObject::getExtensions(contextID, true); @@ -382,16 +408,28 @@ void DrawElementsUInt::draw(State& state, bool useVertexBufferObjects) const if (useVertexBufferObjects) { #if 1 + #if 1 + const ElementBufferObject* ebo = getElementBufferObject(); + state.bindElementBufferObject(ebo); + if (ebo) + { + glDrawElements(_mode, size(), GL_UNSIGNED_INT, ebo->getOffset(getElementBufferObjectIndex())); + } + else + { + glDrawElements(_mode, size(), GL_UNSIGNED_INT, &front()); + } + #else unsigned int contextID = state.getContextID(); const BufferObject::Extensions* extensions = BufferObject::getExtensions(contextID, true); - const ElementsBufferObject* ebo = getElementsBufferObject(); + const ElementBufferObject* ebo = getElementBufferObject(); if (ebo) { //ebo->compileBuffer(state); ebo->bindBuffer(contextID); - glDrawElements(_mode, size(), GL_UNSIGNED_INT, ebo->getOffset(getElementsBufferObjectIndex())); + glDrawElements(_mode, size(), GL_UNSIGNED_INT, ebo->getOffset(getElementBufferObjectIndex())); extensions->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); } @@ -399,6 +437,7 @@ void DrawElementsUInt::draw(State& state, bool useVertexBufferObjects) const { glDrawElements(_mode, size(), GL_UNSIGNED_INT, &front()); } + #endif #else unsigned int contextID = state.getContextID(); const BufferObject::Extensions* extensions = BufferObject::getExtensions(contextID, true); diff --git a/src/osg/State.cpp b/src/osg/State.cpp index 9602bf9d8..62e441c33 100644 --- a/src/osg/State.cpp +++ b/src/osg/State.cpp @@ -39,6 +39,10 @@ State::State() _currentActiveTextureUnit=0; _currentClientActiveTextureUnit=0; + _currentVBO = 0; + _currentEBO = 0; + _currentPBO = 0; + _isSecondaryColorSupportResolved = false; _isSecondaryColorSupported = false; @@ -728,6 +732,7 @@ void State::initializeExtensionProcs() _glVertexAttribPointer = (VertexAttribPointerProc) osg::getGLExtensionFuncPtr("glVertexAttribPointer","glVertexAttribPointerARB"); _glEnableVertexAttribArray = (EnableVertexAttribProc) osg::getGLExtensionFuncPtr("glEnableVertexAttribArray","glEnableVertexAttribArrayARB"); _glDisableVertexAttribArray = (DisableVertexAttribProc) osg::getGLExtensionFuncPtr("glDisableVertexAttribArray","glDisableVertexAttribArrayARB"); + _glBindBuffer = (BindBufferProc) osg::getGLExtensionFuncPtr("glBindBuffer","glBindBufferARB"); _extensionProcsInitialized = true; } @@ -736,8 +741,6 @@ bool State::setClientActiveTextureUnit( unsigned int unit ) { if (unit!=_currentClientActiveTextureUnit) { - if (!_extensionProcsInitialized) initializeExtensionProcs(); - if (_glClientActiveTexture) { _glClientActiveTexture(GL_TEXTURE0+unit); @@ -758,8 +761,6 @@ bool State::setActiveTextureUnit( unsigned int unit ) { if (unit!=_currentActiveTextureUnit) { - if (!_extensionProcsInitialized) initializeExtensionProcs(); - if (_glActiveTexture) { _glActiveTexture(GL_TEXTURE0+unit); @@ -775,8 +776,6 @@ bool State::setActiveTextureUnit( unsigned int unit ) void State::setFogCoordPointer(GLenum type, GLsizei stride, const GLvoid *ptr) { - if (!_extensionProcsInitialized) initializeExtensionProcs(); - if (_glFogCoordPointer) { @@ -798,8 +797,6 @@ void State::setFogCoordPointer(GLenum type, GLsizei stride, const GLvoid *ptr) void State::setSecondaryColorPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *ptr ) { - if (!_extensionProcsInitialized) initializeExtensionProcs(); - if (_glSecondaryColorPointer) { if (!_secondaryColorArray._enabled || _secondaryColorArray._dirty) @@ -822,8 +819,6 @@ void State::setVertexAttribPointer( unsigned int index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *ptr ) { - if (!_extensionProcsInitialized) initializeExtensionProcs(); - if (_glVertexAttribPointer) { if ( index >= _vertexAttribArrayList.size()) _vertexAttribArrayList.resize(index+1); @@ -848,8 +843,6 @@ void State::setVertexAttribPointer( unsigned int index, * note, only updates values that change.*/ void State::disableVertexAttribPointer( unsigned int index ) { - if (!_extensionProcsInitialized) initializeExtensionProcs(); - if (_glDisableVertexAttribArray) { if ( index >= _vertexAttribArrayList.size()) _vertexAttribArrayList.resize(index+1); @@ -866,8 +859,6 @@ void State::disableVertexAttribPointer( unsigned int index ) void State::disableVertexAttribPointersAboveAndIncluding( unsigned int index ) { - if (!_extensionProcsInitialized) initializeExtensionProcs(); - if (_glDisableVertexAttribArray) { while (index<_vertexAttribArrayList.size()) diff --git a/src/osgUtil/SceneView.cpp b/src/osgUtil/SceneView.cpp index 5bdf66c80..04965b0ff 100644 --- a/src/osgUtil/SceneView.cpp +++ b/src/osgUtil/SceneView.cpp @@ -845,9 +845,10 @@ void SceneView::draw() { if (_camera->getNodeMask()==0) return; - if (!_initCalled) init(); - osg::State* state = _renderInfo.getState(); + state->initializeExtensionProcs(); + + if (!_initCalled) init(); // note, to support multi-pipe systems the deletion of OpenGL display list // and texture objects is deferred until the OpenGL context is the correct diff --git a/src/osgViewer/CompositeViewer.cpp b/src/osgViewer/CompositeViewer.cpp index 146d6bfc2..edbc413e4 100644 --- a/src/osgViewer/CompositeViewer.cpp +++ b/src/osgViewer/CompositeViewer.cpp @@ -224,6 +224,8 @@ struct CompositeViewerCompileOperation : public osg::Operation // OpenThreads::ScopedLock lock(mutex); // osg::notify(osg::NOTICE)<<"Compile "<getState()->initializeExtensionProcs(); + osgUtil::GLObjectsVisitor compileVisitor; compileVisitor.setState(context->getState()); diff --git a/src/osgViewer/Viewer.cpp b/src/osgViewer/Viewer.cpp index ff1dca5b8..97447aebc 100644 --- a/src/osgViewer/Viewer.cpp +++ b/src/osgViewer/Viewer.cpp @@ -940,6 +940,8 @@ struct ViewerCompileOperation : public osg::Operation // osg::notify(osg::NOTICE)<<"Compile "<makeCurrent(); + + context->getState()->initializeExtensionProcs(); osgUtil::GLObjectsVisitor compileVisitor; compileVisitor.setState(context->getState());