diff --git a/include/osg/Drawable b/include/osg/Drawable index 257639e2d..8ed6c5654 100644 --- a/include/osg/Drawable +++ b/include/osg/Drawable @@ -302,8 +302,8 @@ class OSG_EXPORT Drawable : public Object */ inline void draw(RenderInfo& renderInfo) const; - /** Immediately compile this \c Drawable into an OpenGL Display List. - * @note Operation is ignored if \c _useDisplayList is \c false. + /** Immediately compile this \c Drawable into an OpenGL Display List/VertexBufferObjects. + * @note Operation is ignored if \c _useDisplayList is \c false or VertexBufferObjects are not used. */ virtual void compileGLObjects(RenderInfo& renderInfo) const; diff --git a/include/osg/Geometry b/include/osg/Geometry index 7214a21b1..63d882935 100644 --- a/include/osg/Geometry +++ b/include/osg/Geometry @@ -121,7 +121,7 @@ class OSG_EXPORT Geometry : public Drawable inline bool empty() const { return !array.valid(); } - ref_ptr array; + ref_ptr array; ref_ptr indices; AttributeBinding binding; GLboolean normalize; @@ -372,7 +372,12 @@ class OSG_EXPORT Geometry : public Drawable /** Return the estimated size of GLObjects (display lists/vertex buffer objects) that are associated with this drawable. * This size is used a hint for reuse of deleted display lists/vertex buffer objects. */ virtual unsigned int getGLObjectSizeHint() const; - + + /** Immediately compile this \c Drawable into an OpenGL Display List/VertexBufferObjects. + * @note Operation is ignored if \c _useDisplayList is \c false or VertexBufferObjects are not used. + */ + virtual void compileGLObjects(RenderInfo& renderInfo) const; + /** Draw Geometry directly ignoring an OpenGL display list which could be attached. * This is the internal draw method which does the drawing itself, * and is the method to override when deriving from Geometry for user-drawn objects. diff --git a/src/osg/Drawable.cpp b/src/osg/Drawable.cpp index 45953a22a..751ba379d 100644 --- a/src/osg/Drawable.cpp +++ b/src/osg/Drawable.cpp @@ -465,18 +465,6 @@ void Drawable::dirtyBound() void Drawable::compileGLObjects(RenderInfo& renderInfo) const { - bool useVertexArrays = _supportsVertexBufferObjects && _useVertexBufferObjects && renderInfo.getState()->isVertexBufferObjectSupported(); - if (useVertexArrays) - { - if (_drawCallback.valid()) - _drawCallback->drawImplementation(renderInfo,this); - else - drawImplementation(renderInfo); - - return; - } - - if (!_useDisplayList) return; #ifdef OSG_GL_DISPLAYLISTS_AVAILABLE diff --git a/src/osg/Geometry.cpp b/src/osg/Geometry.cpp index 98d29ece4..785a8df8b 100644 --- a/src/osg/Geometry.cpp +++ b/src/osg/Geometry.cpp @@ -904,6 +904,76 @@ void Geometry::releaseGLObjects(State* state) const } +void Geometry::compileGLObjects(RenderInfo& renderInfo) const +{ + bool useVertexArrays = _supportsVertexBufferObjects && + _useVertexBufferObjects && + renderInfo.getState()->isVertexBufferObjectSupported() && + areFastPathsUsed(); + if (useVertexArrays) + { + // osg::notify(osg::NOTICE)<<"Geometry::compileGLObjects() use VBO's "< BufferObjects; + BufferObjects bufferObjects; + + // first collect all the active unique BufferObjects + if (_vertexData.array.valid() && _vertexData.array->getBufferObject()) bufferObjects.insert(_vertexData.array->getBufferObject()); + if (_normalData.array.valid() && _normalData.array->getBufferObject()) bufferObjects.insert(_normalData.array->getBufferObject()); + if (_colorData.array.valid() && _colorData.array->getBufferObject()) bufferObjects.insert(_colorData.array->getBufferObject()); + if (_secondaryColorData.array.valid() && _secondaryColorData.array->getBufferObject()) bufferObjects.insert(_secondaryColorData.array->getBufferObject()); + if (_fogCoordData.array.valid() && _fogCoordData.array->getBufferObject()) bufferObjects.insert(_fogCoordData.array->getBufferObject()); + + for(ArrayDataList::const_iterator itr = _texCoordList.begin(); + itr != _texCoordList.end(); + ++itr) + { + if (itr->array.valid() && itr->array->getBufferObject()) bufferObjects.insert(itr->array->getBufferObject()); + } + + for(ArrayDataList::const_iterator itr = _vertexAttribList.begin(); + itr != _vertexAttribList.end(); + ++itr) + { + if (itr->array.valid() && itr->array->getBufferObject()) bufferObjects.insert(itr->array->getBufferObject()); + } + + for(PrimitiveSetList::const_iterator itr = _primitives.begin(); + itr != _primitives.end(); + ++itr) + { + if ((*itr)->getBufferObject()) bufferObjects.insert((*itr)->getBufferObject()); + } + + + // now compile any buffer objects that require it. + for(BufferObjects::iterator itr = bufferObjects.begin(); + itr != bufferObjects.end(); + ++itr) + { + GLBufferObject* glBufferObject = (*itr)->getOrCreateGLBufferObject(contextID); + if (glBufferObject && glBufferObject->isDirty()) + { + // osg::notify(osg::NOTICE)<<"Compile buffer "<compileBuffer(); + } + } + + // unbind the BufferObjects + extensions->glBindBuffer(GL_ARRAY_BUFFER_ARB,0); + extensions->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB,0); + + } + else + { + Drawable::compileGLObjects(renderInfo); + } +} + void Geometry::drawImplementation(RenderInfo& renderInfo) const { if (_internalOptimizedGeometry.valid())