From 4d8a29b987b87cdf3a97456a84956258b9ea98c5 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 18 Jul 2016 20:09:22 +0100 Subject: [PATCH] Added ability to initializer GL vertex array object id with Geometry::compileGLObjects(). Improved the handling of buffer object state when not using VAO's --- include/osg/Geometry | 2 + include/osg/VertexArrayState | 8 +-- src/osg/Geometry.cpp | 108 ++++++++++++++++++++++++----------- src/osg/VertexArrayState.cpp | 51 ++++++++++++++--- 4 files changed, 124 insertions(+), 45 deletions(-) diff --git a/include/osg/Geometry b/include/osg/Geometry index 3527a608a..2f450561c 100644 --- a/include/osg/Geometry +++ b/include/osg/Geometry @@ -238,6 +238,8 @@ class OSG_EXPORT Geometry : public Drawable bool _containsDeprecatedData; + virtual VertexArrayState* setUpVertexArrayState(RenderInfo& renderInfo, bool usingVBOs) const; + public: diff --git a/include/osg/VertexArrayState b/include/osg/VertexArrayState index a897230fa..eefca0120 100644 --- a/include/osg/VertexArrayState +++ b/include/osg/VertexArrayState @@ -155,7 +155,7 @@ public: void setCurrentVertexBufferObject(osg::GLBufferObject* vbo) { _currentVBO = vbo; } - const GLBufferObject* getCurrentVertexBufferObject() { return _currentVBO; } + GLBufferObject* getCurrentVertexBufferObject() { return _currentVBO; } inline void bindVertexBufferObject(osg::GLBufferObject* vbo) { if (vbo) @@ -177,13 +177,13 @@ public: void setCurrentElementBufferObject(osg::GLBufferObject* ebo) { _currentEBO = ebo; } - const GLBufferObject* getCurrentElementBufferObject() { return _currentEBO; } + GLBufferObject* getCurrentElementBufferObject() { return _currentEBO; } inline void bindElementBufferObject(osg::GLBufferObject* ebo) { if (ebo) { - if (ebo == _currentEBO) return; + //if (ebo == _currentEBO) return; if (ebo->isDirty()) ebo->compileBuffer(); else ebo->bindBuffer(); _currentEBO = ebo; @@ -193,7 +193,7 @@ public: inline void unbindElementBufferObject() { - if (!_currentEBO) return; + //if (!_currentEBO) return; _ext->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB,0); _currentEBO = 0; } diff --git a/src/osg/Geometry.cpp b/src/osg/Geometry.cpp index 6ca761c43..a41385780 100644 --- a/src/osg/Geometry.cpp +++ b/src/osg/Geometry.cpp @@ -23,9 +23,14 @@ using namespace osg; Geometry::Geometry(): _containsDeprecatedData(false) { +#if 0 _supportsVertexBufferObjects = true; // temporary test // setSupportsDisplayList(false); +#else + _supportsVertexBufferObjects = true; + _useVertexBufferObjects = true; +#endif } Geometry::Geometry(const Geometry& geometry,const CopyOp& copyop): @@ -660,14 +665,56 @@ void Geometry::releaseGLObjects(State* state) const } +VertexArrayState* Geometry::setUpVertexArrayState(RenderInfo& renderInfo, bool usingVBOs) const +{ + OSG_NOTICE<<"Creating new osg::VertexArrayState"<()); + + if (_vertexArray.valid()) vas->assignVertexArray(_vertexArray.get()); + if (_colorArray.valid()) vas->assignColorArray(_colorArray.get()); + if (_normalArray.valid()) vas->assignNormalArray(_normalArray.get()); + if (_secondaryColorArray.valid()) vas->assignSecondaryColorArray(_secondaryColorArray.get()); + if (_fogCoordArray.valid()) vas->assignFogCoordArray(_fogCoordArray.get()); + + for(unsigned int i=0; i<_texCoordList.size(); ++i) + { + if (_texCoordList[i].valid()) vas->assignTexCoordArray(i, _texCoordList[i].get()); + } + + for(unsigned int i=0; i<_vertexAttribList.size(); ++i) + { + if (_vertexAttribList[i].valid()) vas->assignVertexAttribArray(i, _vertexAttribList[i].get()); + } + + if (usingVBOs && ds->getGeometryImplementation()==DisplaySettings::VERTEX_ARRAY_OBJECT) + { + OSG_NOTICE<<" Setup VertexArrayState to use VAO"<generateVretexArrayObject(); + } + else + { + OSG_NOTICE<<" Setup VertexArrayState to without using VAO"<isVertexBufferObjectSupported(); if (useVertexArrays) { - State& state = *renderInfo.getState(); unsigned int contextID = state.getContextID(); GLExtensions* extensions = state.get(); if (!extensions) return; @@ -724,9 +771,18 @@ void Geometry::compileGLObjects(RenderInfo& renderInfo) const extensions->glBindBuffer(GL_ARRAY_BUFFER_ARB,0); extensions->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB,0); + if (ds->getGeometryImplementation()!=DisplaySettings::OLD_GEOMETRY_IMPLEMENTATION) + { + setUpVertexArrayState(renderInfo, !bufferObjects.empty()); + } } else { + if (ds->getGeometryImplementation()!=DisplaySettings::OLD_GEOMETRY_IMPLEMENTATION) + { + setUpVertexArrayState(renderInfo, false); + } + Drawable::compileGLObjects(renderInfo); } } @@ -879,12 +935,16 @@ void Geometry::new_drawImplementation(RenderInfo& renderInfo) const unsigned int contextID = state.getContextID(); - bool usingVertexBufferObjects = _useVertexBufferObjects && state.isVertexBufferObjectSupported(); + bool usingVertexBufferObjects = _supportsVertexBufferObjects && _useVertexBufferObjects && state.isVertexBufferObjectSupported(); bool useVAO = usingVertexBufferObjects && (ds->getGeometryImplementation()==DisplaySettings::VERTEX_ARRAY_OBJECT); bool dispatchIfDirty = useVAO; + VertexArrayState* vas = _vertexArrayStateList[contextID].get(); + OSG_NOTICE<<"Geometry::new_drawImplementation() "<()); - - if (_vertexArray.valid()) vas->assignVertexArray(_vertexArray.get()); - if (_colorArray.valid()) vas->assignColorArray(_colorArray.get()); - if (_normalArray.valid()) vas->assignNormalArray(_normalArray.get()); - if (_secondaryColorArray.valid()) vas->assignSecondaryColorArray(_secondaryColorArray.get()); - if (_fogCoordArray.valid()) vas->assignFogCoordArray(_fogCoordArray.get()); - - for(unsigned int i=0; i<_texCoordList.size(); ++i) - { - if (_texCoordList[i].valid()) vas->assignTexCoordArray(i, _texCoordList[i].get()); - } - - for(unsigned int i=0; i<_vertexAttribList.size(); ++i) - { - if (_vertexAttribList[i].valid()) vas->assignVertexAttribArray(i, _vertexAttribList[i].get()); - } - - if (useVAO) - { - OSG_NOTICE<<" Setup VertexArrayState to use VAO"<generateVretexArrayObject(); - dispatchIfDirty = false; - } - else - { - OSG_NOTICE<<" Setup VertexArrayState to wihtout using VAO"<unbindVertexArrayObject(); + + state.setCurrentVertexBufferObject(vas->getCurrentVertexBufferObject()); + state.setCurrentElementBufferObject(vas->getCurrentElementBufferObject()); + + // unbind the VBO's if any are used. + state.unbindVertexBufferObject(); + state.unbindElementBufferObject(); + } + if (checkForGLErrors) state.checkGLErrors("Geometry::new_drawImplementation() after primitive dispatch."); } diff --git a/src/osg/VertexArrayState.cpp b/src/osg/VertexArrayState.cpp index ecf5ab02b..187ed904a 100644 --- a/src/osg/VertexArrayState.cpp +++ b/src/osg/VertexArrayState.cpp @@ -78,12 +78,17 @@ struct VertexArrayWithVBODispatch : public VertexArrayState::ArrayDispatch { VertexArrayWithVBODispatch(Array* in_array, GLBufferObject* in_vbo) : ArrayDispatch(in_array), vbo(in_vbo) {} - virtual void dispatch(osg::State&, unsigned int) + virtual void dispatch(osg::State& state, unsigned int) { - OSG_INFO<<"VertexArrayWithVBODispatch::dispatch()"<getNumElements()<<", "<getDataPointer()<bindVertexBufferObject(vbo); +#else if (vbo->isDirty()) vbo->compileBuffer(); else vbo->bindBuffer(); +#endif glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(array->getDataSize(), array->getDataType(), 0, (const GLvoid *)(vbo->getOffset(array->getBufferIndex()))); @@ -93,7 +98,7 @@ struct VertexArrayWithVBODispatch : public VertexArrayState::ArrayDispatch virtual void dispatchDeprecated(osg::State& state, unsigned int) { - OSG_INFO<<"VertexArrayDispatchWitVBO::dispatchDeprecated() "<getNumElements()<<", "<getDataPointer()<getNumElements()<<", "<getDataPointer()<bindVertexBufferObject(vbo); +#else if (vbo->isDirty()) vbo->compileBuffer(); else vbo->bindBuffer(); - +#endif glEnableClientState(GL_COLOR_ARRAY); glColorPointer(array->getDataSize(), array->getDataType(), 0, (const GLvoid *)(vbo->getOffset(array->getBufferIndex()))); @@ -337,12 +344,16 @@ struct NormalArrayWithVBODispatch : public VertexArrayState::ArrayDispatch { NormalArrayWithVBODispatch(Array* in_array, GLBufferObject* in_vbo) : ArrayDispatch(in_array), vbo(in_vbo) {} - virtual void dispatch(osg::State&, unsigned int) + virtual void dispatch(osg::State& state, unsigned int) { OSG_INFO<<"NormalArrayWithVBODispatch::dispatch()"<bindVertexBufferObject(vbo); +#else if (vbo->isDirty()) vbo->compileBuffer(); else vbo->bindBuffer(); +#endif glEnableClientState(GL_NORMAL_ARRAY); glNormalPointer(array->getDataType(), 0, (const GLvoid *)(vbo->getOffset(array->getBufferIndex()))); @@ -445,8 +456,12 @@ struct SecondaryColorArrayWithVBODispatch : public VertexArrayState::ArrayDispat { OSG_INFO<<"SecondaryColorArrayWithVBODispatch::dispatch()"<bindVertexBufferObject(vbo); +#else if (vbo->isDirty()) vbo->compileBuffer(); else vbo->bindBuffer(); +#endif glEnableClientState(GL_FOG_COORDINATE_ARRAY); state.get()->glSecondaryColorPointer(array->getDataSize(), array->getDataType(), 0, (const GLvoid *)(vbo->getOffset(array->getBufferIndex()))); @@ -555,8 +570,12 @@ struct FogCoordArrayWithVBODispatch : public VertexArrayState::ArrayDispatch { OSG_INFO<<"FogCoordArrayWithVBODispatch::dispatch()"<bindVertexBufferObject(vbo); +#else if (vbo->isDirty()) vbo->compileBuffer(); else vbo->bindBuffer(); +#endif glEnableClientState(GL_FOG_COORDINATE_ARRAY); state.get()->glFogCoordPointer(array->getDataType(), 0, (const GLvoid *)(vbo->getOffset(array->getBufferIndex()))); @@ -665,12 +684,16 @@ struct TexCoordArrayWithVBODispatch : public VertexArrayState::ArrayDispatch { TexCoordArrayWithVBODispatch(unsigned int in_unit, Array* in_array, GLBufferObject* in_vbo) : ArrayDispatch(in_array), unit(in_unit), vbo(in_vbo) {} - virtual void dispatch(osg::State&, unsigned int) + virtual void dispatch(osg::State& state, unsigned int) { OSG_INFO<<"TexCoordArrayWithVBODispatch::dispatch()"<bindVertexBufferObject(vbo); +#else if (vbo->isDirty()) vbo->compileBuffer(); else vbo->bindBuffer(); +#endif glClientActiveTexture(static_cast(GL_TEXTURE0+unit)); glEnableClientState(GL_TEXTURE_COORD_ARRAY); @@ -805,8 +828,12 @@ struct VertexAttribArrayWithVBODispatch : public VertexArrayState::ArrayDispatch virtual void dispatch(osg::State& state, unsigned int) { +#if 1 + state.getCurrentVertexArrayState()->bindVertexBufferObject(vbo); +#else if (vbo->isDirty()) vbo->compileBuffer(); else vbo->bindBuffer(); +#endif GLExtensions* ext = state.get(); ext->glEnableVertexAttribArray( unit ); @@ -856,8 +883,12 @@ struct VertexAttribLArrayWithVBODispatch : public VertexArrayState::ArrayDispatc virtual void dispatch(osg::State& state, unsigned int) { +#if 1 + state.getCurrentVertexArrayState()->bindVertexBufferObject(vbo); +#else if (vbo->isDirty()) vbo->compileBuffer(); else vbo->bindBuffer(); +#endif GLExtensions* ext = state.get(); ext->glEnableVertexAttribArray( unit ); @@ -907,8 +938,12 @@ struct VertexAttribIArrayWithVBODispatch : public VertexArrayState::ArrayDispatc virtual void dispatch(osg::State& state, unsigned int) { +#if 1 + state.getCurrentVertexArrayState()->bindVertexBufferObject(vbo); +#else if (vbo->isDirty()) vbo->compileBuffer(); else vbo->bindBuffer(); +#endif GLExtensions* ext = state.get(); ext->glEnableVertexAttribArray( unit );