Added osg::Geometry::configureBufferObjects() and ConfigureBufferObjectsVisitor visitor to help with setting up buffer objects in a coherent fashion.

This commit is contained in:
Robert Osfield 2016-11-14 17:59:25 +00:00
parent 99cb8ebacf
commit 5b375124cc
2 changed files with 68 additions and 0 deletions

View File

@ -129,6 +129,9 @@ class OSG_EXPORT Geometry : public Drawable
unsigned int getPrimitiveSetIndex(const PrimitiveSet* primitiveset) const;
/** Convinience method that checks all the vertex arrays to make sure that the buffer objects are all assigned appropriate.*/
void configureBufferObjects();
/** return true if any arrays are shared.*/
bool containsSharedArrays() const;
@ -276,6 +279,21 @@ class OSG_EXPORT Geometry : public Drawable
#endif
};
/** Convinience visitor for making sure that any BufferObjects that might be required are set up in the scene graph.*/
class ConfigureBufferObjectsVisitor : public osg::NodeVisitor
{
public:
ConfigureBufferObjectsVisitor():
osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {}
void apply(osg::Geometry& geometry)
{
geometry.configureBufferObjects();
}
};
/** Convenience function to be used for creating quad geometry with texture coords.
* Tex coords go from left bottom (l,b) to right top (r,t).
*/

View File

@ -103,6 +103,56 @@ bool Geometry::empty() const
return true;
}
void Geometry::configureBufferObjects()
{
osg::Array* vertices = getVertexArray();
if (!vertices) return;
osg::BufferObject* vbo = vertices->getBufferObject();
unsigned int numVertices = vertices->getNumElements();
typedef std::vector< osg::ref_ptr<osg::Array> > Arrays;
Arrays arrays;
if (getNormalArray()) arrays.push_back(getNormalArray());
if (getColorArray()) arrays.push_back(getColorArray());
if (getSecondaryColorArray()) arrays.push_back(getSecondaryColorArray());
if (getFogCoordArray()) arrays.push_back(getFogCoordArray());
for(unsigned int i=0; i<getNumTexCoordArrays(); ++i)
{
if (getTexCoordArray(i)) arrays.push_back(getTexCoordArray(i));
}
for(unsigned int i=0; i<getNumVertexAttribArrays(); ++i)
{
if (getVertexAttribArray(i)) arrays.push_back(getVertexAttribArray(i));
}
for(Arrays::iterator itr = arrays.begin();
itr != arrays.end();
++itr)
{
osg::Array* array = *itr;
if (array->getBinding()==osg::Array::BIND_PER_VERTEX)
{
if (array->getNumElements()==numVertices)
{
if (!array->getBufferObject()) array->setBufferObject(vbo);
}
else if (array->getNumElements()>=1)
{
array->setBinding(osg::Array::BIND_OVERALL);
}
else
{
array->setBinding(osg::Array::BIND_OFF);
}
}
}
}
void Geometry::setVertexArray(Array* array)
{
if (array && array->getBinding()==osg::Array::BIND_UNDEFINED) array->setBinding(osg::Array::BIND_PER_VERTEX);