void ControlCanvas::update() { //int bin = 999999; for( ControlList::iterator i = _controls.begin(); i != _controls.end(); ++i ) { Control* control = i->get(); if ( control->isDirty() || _contextDirty ) { osg::Vec2f size; control->calcSize( _context, size ); osg::Vec2f surfaceSize( _context._vp->width(), _context._vp->height() ); control->calcPos( _context, osg::Vec2f(0,0), surfaceSize ); osg::Geode* geode = _geodeTable[control]; geode->removeDrawables( 0, geode->getNumDrawables() ); DrawableList drawables; control->draw( _context, drawables ); for( DrawableList::iterator j = drawables.begin(); j != drawables.end(); ++j ) { j->get()->setDataVariance( osg::Object::DYNAMIC ); // j->get()->getOrCreateStateSet()->setRenderBinDetails( bin++, "RenderBin" ); geode->addDrawable( j->get() ); } } } _contextDirty = false; }
void MeshConsolidator::run( osg::Geode& geode ) { bool useVBOs = false; // NOTE: we'd rather use the IndexMeshVisitor instead of our own code here, // but the IMV does not preserve the user data attached to the primitive sets. // We need that since it holds the feature index information. //osgUtil::IndexMeshVisitor mesher; //geode.accept(mesher); // trivial bailout: if ( geode.getNumDrawables() <= 1 ) return; // list of geometries to consolidate and not to consolidate. DrawableList consolidate, dontConsolidate; // list of texture coordinate array image units in use std::vector<unsigned> texCoordArrayUnits; texCoordArrayUnits.reserve(32); // sort the drawables: for( unsigned i=0; i<geode.getNumDrawables(); ++i ) { osg::Geometry* geom = geode.getDrawable(i)->asGeometry(); if ( geom ) { if ( canOptimize(*geom) ) { // convert all primitives to triangles. convertToTriangles( *geom ); // NOTE!! tex/attrib array counts much already be equal. if ( texCoordArrayUnits.size() == 0 ) { for( unsigned u=0; u<32; ++u ) { if ( geom->getTexCoordArray(u) != 0L ) texCoordArrayUnits.push_back( u ); } if ( geom->getUseVertexBufferObjects() ) useVBOs = true; } consolidate.push_back(geom); } else { dontConsolidate.push_back(geom); } } } // start consolidating the geometries. unsigned targetNumVertsPerGeom = 100000; //TODO: configurable? DrawableList results; unsigned numVerts = 0, numColors = 0, numNormals = 0; DrawableList::iterator start = consolidate.begin(); for( DrawableList::iterator end = consolidate.begin(); end != consolidate.end(); ) { osg::Geometry* geom = end->get()->asGeometry(); // already type-checked this earlier. unsigned geomNumVerts = geom->getVertexArray()->getNumElements(); ++end; numVerts += geomNumVerts; if ( geom->getColorArray() ) numColors += geom->getColorArray()->getNumElements(); if ( geom->getNormalArray() ) numNormals += geom->getNormalArray()->getNumElements(); if ( numVerts > targetNumVertsPerGeom || end == consolidate.end() ) { OE_DEBUG << LC << "Merging " << ((unsigned)(end-start)) << " geoms with " << numVerts << " verts." << std::endl; merge( start, end, numVerts, numColors, numNormals, texCoordArrayUnits, useVBOs, results ); start = end; numVerts = 0, numColors = 0, numNormals = 0; } } // re-build the geode: geode.removeDrawables( 0, geode.getNumDrawables() ); for( DrawableList::iterator i = results.begin(); i != results.end(); ++i ) geode.addDrawable( i->get() ); for( DrawableList::iterator i = dontConsolidate.begin(); i != dontConsolidate.end(); ++i ) geode.addDrawable( i->get() ); }