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; }
const DrawableList Geode_getDrawableList1(osg::Geode* geode) { const Geode::DrawableList& drawables = geode->getDrawableList(); DrawableList result; for (unsigned int i = 0; i < drawables.size(); ++i) result.push_back(drawables[i].get()); return result; }
void drvMAGICK::show_image(const PSImage & imageinfo) { if (imageinfo.isFileImage) { try { DrawableList drawList; const double sx = imageinfo.normalizedImageCurrentMatrix[0]; const double rx = -imageinfo.normalizedImageCurrentMatrix[1]; const double ry = imageinfo.normalizedImageCurrentMatrix[2]; const double sy = -imageinfo.normalizedImageCurrentMatrix[3]; const double x = 0; const double y = 0; const double tx = imageinfo.normalizedImageCurrentMatrix[4] + x_offset; const double ty = currentDeviceHeight - imageinfo.normalizedImageCurrentMatrix[5] + y_offset; const double width = imageinfo.width; const double height = imageinfo.height; cout << " sx " << sx << " sy " << sy << " rx " << rx << " ry " << ry << " tx " << tx << " ty " << ty << " w " << width << " h " << height << endl; const string filename = imageinfo.FileName.value(); cout << "drawing subimage from " << filename << endl; drawList.push_back(DrawablePushGraphicContext()); drawList.push_back(DrawableAffine(sx, sy, rx, ry, tx, ty)); Image pngimage(filename); // cout << "rows " << pngimage.rows() << " columns " << pngimage.columns() << endl; // drawList.push_back( DrawableCompositeImage(0,0,width, height, filename) ); if ((pngimage.rows() > 0) && (pngimage.columns() > 0)) { DrawableCompositeImage theimage(x, y, width, height, pngimage); theimage.magick("png"); drawList.push_back(theimage); } else { errf << "reading image from " << filename << " failed " << endl; } drawList.push_back(DrawablePopGraphicContext()); imageptr->draw(drawList); } catch (const Exception & error_) { errf << "Caught exception: " << error_.what() << endl; } } else { errf << "Only PNG file based image are supported" << endl; } }
void Control::draw(const ControlContext& cx, DrawableList& out ) { // by default, rendering a Control directly results in a colored quad. Usually however // you will not render a Control directly, but rather one of its subclasses. if ( visible() == true && !(_backColor.isSet() && _backColor->a() == 0) && _renderSize.x() > 0 && _renderSize.y() > 0 ) { float vph = cx._vp->height(); osg::Geometry* geom = new osg::Geometry(); osg::Vec3Array* verts = new osg::Vec3Array(4); geom->setVertexArray( verts ); (*verts)[0].set( _renderPos.x(), vph - _renderPos.y(), 0 ); (*verts)[1].set( _renderPos.x(), vph - _renderPos.y() - _renderSize.y(), 0 ); (*verts)[2].set( _renderPos.x() + _renderSize.x(), vph - _renderPos.y() - _renderSize.y(), 0 ); (*verts)[3].set( _renderPos.x() + _renderSize.x(), vph - _renderPos.y(), 0 ); geom->addPrimitiveSet( new osg::DrawArrays( GL_QUADS, 0, 4 ) ); osg::Vec4Array* colors = new osg::Vec4Array(1); (*colors)[0] = _backColor.value(); geom->setColorArray( colors ); geom->setColorBinding( osg::Geometry::BIND_OVERALL ); out.push_back( geom ); } }
void LabelControl::draw( const ControlContext& cx, DrawableList& out ) { if ( _drawable.valid() && visible() == true ) { //TODO: support alignment here float vph = cx._vp->height(); LabelText* t = static_cast<LabelText*>( _drawable.get() ); osg::BoundingBox bbox = t->getTextBB(); t->setPosition( osg::Vec3( _renderPos.x(), vph - _renderPos.y(), 0 ) ); out.push_back( _drawable.get() ); Control::draw( cx, out ); } }
void ImageControl::draw( const ControlContext& cx, DrawableList& out ) { if ( visible() == true ) { //TODO: this is not precisely correct..images get deformed slightly.. osg::Geometry* g = new osg::Geometry(); float rx = osg::round( _renderPos.x() ); float ry = osg::round( _renderPos.y() ); float vph = cx._vp->height(); osg::Vec3Array* verts = new osg::Vec3Array(4); g->setVertexArray( verts ); (*verts)[0].set( rx, vph - ry, 0 ); (*verts)[1].set( rx, vph - ry - _renderSize.y(), 0 ); (*verts)[2].set( rx + _renderSize.x(), vph - ry - _renderSize.y(), 0 ); (*verts)[3].set( rx + _renderSize.x(), vph - ry, 0 ); g->addPrimitiveSet( new osg::DrawArrays( GL_QUADS, 0, 4 ) ); osg::Vec4Array* c = new osg::Vec4Array(1); (*c)[0] = osg::Vec4f(1,1,1,1); g->setColorArray( c ); g->setColorBinding( osg::Geometry::BIND_OVERALL ); osg::Vec2Array* t = new osg::Vec2Array(4); (*t)[0].set( 0, _renderSize.y()-1 ); (*t)[1].set( 0, 0 ); (*t)[2].set( _renderSize.x()-1, 0 ); (*t)[3].set( _renderSize.x()-1, _renderSize.y()-1 ); g->setTexCoordArray( 0, t ); osg::TextureRectangle* texrec = new osg::TextureRectangle( _image.get() ); texrec->setFilter( osg::Texture::MIN_FILTER, osg::Texture::NEAREST ); texrec->setFilter( osg::Texture::MAG_FILTER, osg::Texture::LINEAR ); g->getOrCreateStateSet()->setTextureAttributeAndModes( 0, texrec, osg::StateAttribute::ON ); osg::TexEnv* texenv = new osg::TexEnv( osg::TexEnv::MODULATE ); g->getStateSet()->setTextureAttributeAndModes( 0, texenv, osg::StateAttribute::ON ); out.push_back( g ); } }
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() ); }