From 67a9ac2055c4ccdef2044706938b740c4e04dbee Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 23 Feb 2007 11:52:28 +0000 Subject: [PATCH] Added new --Viewer and --CompositeViewer for implementation of HUDs --- examples/osghud/osghud.cpp | 356 +++++++++++++++++++++++-------------- 1 file changed, 221 insertions(+), 135 deletions(-) diff --git a/examples/osghud/osghud.cpp b/examples/osghud/osghud.cpp index a5269b4dd..327c94be1 100644 --- a/examples/osghud/osghud.cpp +++ b/examples/osghud/osghud.cpp @@ -13,7 +13,11 @@ #include #include + #include +#include + +#include #include #include @@ -26,128 +30,9 @@ #include -osg::Node* createHUD() +osg::Camera* createHUD() { - osg::Geode* geode = new osg::Geode(); - - std::string timesFont("fonts/arial.ttf"); - - // turn lighting off for the text and disable depth test to ensure its always ontop. - osg::StateSet* stateset = geode->getOrCreateStateSet(); - stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF); - - osg::Vec3 position(150.0f,800.0f,0.0f); - osg::Vec3 delta(0.0f,-120.0f,0.0f); - - { - osgText::Text* text = new osgText::Text; - geode->addDrawable( text ); - - text->setFont(timesFont); - text->setPosition(position); - text->setText("Head Up Displays are simple :-)"); - - position += delta; - } - - - { - osgText::Text* text = new osgText::Text; - geode->addDrawable( text ); - - text->setFont(timesFont); - text->setPosition(position); - text->setText("All you need to do is create your text in a subgraph."); - - position += delta; - } - - - { - osgText::Text* text = new osgText::Text; - geode->addDrawable( text ); - - text->setFont(timesFont); - text->setPosition(position); - text->setText("Then place an osg::Camera above the subgraph\n" - "to create an orthographic projection.\n"); - - position += delta; - } - - { - osgText::Text* text = new osgText::Text; - geode->addDrawable( text ); - - text->setFont(timesFont); - text->setPosition(position); - text->setText("Set the Camera's ReferenceFrame to ABSOLUTE_RF to ensure\n" - "it remains independent from any external model view matrices."); - - position += delta; - } - - { - osgText::Text* text = new osgText::Text; - geode->addDrawable( text ); - - text->setFont(timesFont); - text->setPosition(position); - text->setText("And set the Camera's clear mask to just clear the depth buffer."); - - position += delta; - } - - { - osgText::Text* text = new osgText::Text; - geode->addDrawable( text ); - - text->setFont(timesFont); - text->setPosition(position); - text->setText("And finally set the Camera's RenderOrder to POST_RENDER\n" - "to make sure its drawn last."); - - position += delta; - } - - - { - osg::BoundingBox bb; - for(unsigned int i=0;igetNumDrawables();++i) - { - bb.expandBy(geode->getDrawable(i)->getBound()); - } - - osg::Geometry* geom = new osg::Geometry; - - osg::Vec3Array* vertices = new osg::Vec3Array; - float depth = bb.zMin()-0.1; - vertices->push_back(osg::Vec3(bb.xMin(),bb.yMax(),depth)); - vertices->push_back(osg::Vec3(bb.xMin(),bb.yMin(),depth)); - vertices->push_back(osg::Vec3(bb.xMax(),bb.yMin(),depth)); - vertices->push_back(osg::Vec3(bb.xMax(),bb.yMax(),depth)); - geom->setVertexArray(vertices); - - osg::Vec3Array* normals = new osg::Vec3Array; - normals->push_back(osg::Vec3(0.0f,0.0f,1.0f)); - geom->setNormalArray(normals); - geom->setNormalBinding(osg::Geometry::BIND_OVERALL); - - osg::Vec4Array* colors = new osg::Vec4Array; - colors->push_back(osg::Vec4(1.0f,1.0,0.8f,0.2f)); - geom->setColorArray(colors); - geom->setColorBinding(osg::Geometry::BIND_OVERALL); - - geom->addPrimitiveSet(new osg::DrawArrays(GL_QUADS,0,4)); - - osg::StateSet* stateset = geom->getOrCreateStateSet(); - stateset->setMode(GL_BLEND,osg::StateAttribute::ON); - //stateset->setAttribute(new osg::PolygonOffset(1.0f,1.0f),osg::StateAttribute::ON); - stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); - - geode->addDrawable(geom); - } - + // create a camera to set up the projection and model view matrices, and the subgraph to drawn in the HUD osg::Camera* camera = new osg::Camera; // set the projection matrix @@ -163,32 +48,233 @@ osg::Node* createHUD() // draw subgraph after main camera view. camera->setRenderOrder(osg::Camera::POST_RENDER); - camera->addChild(geode); + // we don't want the camera to grab event focus from the viewers main camera(s). + camera->setAllowEventFocus(false); - return camera; + + // add to this camera a subgraph to render + { + + osg::Geode* geode = new osg::Geode(); + + std::string timesFont("fonts/arial.ttf"); + + // turn lighting off for the text and disable depth test to ensure its always ontop. + osg::StateSet* stateset = geode->getOrCreateStateSet(); + stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF); + + osg::Vec3 position(150.0f,800.0f,0.0f); + osg::Vec3 delta(0.0f,-120.0f,0.0f); + + { + osgText::Text* text = new osgText::Text; + geode->addDrawable( text ); + + text->setFont(timesFont); + text->setPosition(position); + text->setText("Head Up Displays are simple :-)"); + + position += delta; + } + + + { + osgText::Text* text = new osgText::Text; + geode->addDrawable( text ); + + text->setFont(timesFont); + text->setPosition(position); + text->setText("All you need to do is create your text in a subgraph."); + + position += delta; + } + + + { + osgText::Text* text = new osgText::Text; + geode->addDrawable( text ); + + text->setFont(timesFont); + text->setPosition(position); + text->setText("Then place an osg::Camera above the subgraph\n" + "to create an orthographic projection.\n"); + + position += delta; + } + + { + osgText::Text* text = new osgText::Text; + geode->addDrawable( text ); + + text->setFont(timesFont); + text->setPosition(position); + text->setText("Set the Camera's ReferenceFrame to ABSOLUTE_RF to ensure\n" + "it remains independent from any external model view matrices."); + + position += delta; + } + + { + osgText::Text* text = new osgText::Text; + geode->addDrawable( text ); + + text->setFont(timesFont); + text->setPosition(position); + text->setText("And set the Camera's clear mask to just clear the depth buffer."); + + position += delta; + } + + { + osgText::Text* text = new osgText::Text; + geode->addDrawable( text ); + + text->setFont(timesFont); + text->setPosition(position); + text->setText("And finally set the Camera's RenderOrder to POST_RENDER\n" + "to make sure its drawn last."); + + position += delta; + } + + + { + osg::BoundingBox bb; + for(unsigned int i=0;igetNumDrawables();++i) + { + bb.expandBy(geode->getDrawable(i)->getBound()); + } + + osg::Geometry* geom = new osg::Geometry; + + osg::Vec3Array* vertices = new osg::Vec3Array; + float depth = bb.zMin()-0.1; + vertices->push_back(osg::Vec3(bb.xMin(),bb.yMax(),depth)); + vertices->push_back(osg::Vec3(bb.xMin(),bb.yMin(),depth)); + vertices->push_back(osg::Vec3(bb.xMax(),bb.yMin(),depth)); + vertices->push_back(osg::Vec3(bb.xMax(),bb.yMax(),depth)); + geom->setVertexArray(vertices); + + osg::Vec3Array* normals = new osg::Vec3Array; + normals->push_back(osg::Vec3(0.0f,0.0f,1.0f)); + geom->setNormalArray(normals); + geom->setNormalBinding(osg::Geometry::BIND_OVERALL); + + osg::Vec4Array* colors = new osg::Vec4Array; + colors->push_back(osg::Vec4(1.0f,1.0,0.8f,0.2f)); + geom->setColorArray(colors); + geom->setColorBinding(osg::Geometry::BIND_OVERALL); + + geom->addPrimitiveSet(new osg::DrawArrays(GL_QUADS,0,4)); + + osg::StateSet* stateset = geom->getOrCreateStateSet(); + stateset->setMode(GL_BLEND,osg::StateAttribute::ON); + //stateset->setAttribute(new osg::PolygonOffset(1.0f,1.0f),osg::StateAttribute::ON); + stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); + + geode->addDrawable(geom); + } + + camera->addChild(geode); + } + + return camera; } int main( int argc, char **argv ) { // use an ArgumentParser object to manage the program arguments. osg::ArgumentParser arguments(&argc,argv); - - + + // read the scene from the list of file specified commandline args. osg::ref_ptr scene = osgDB::readNodeFiles(arguments); - - osg::ref_ptr group = new osg::Group; - // add the HUD subgraph. - if (scene.valid()) group->addChild(scene.get()); - group->addChild(createHUD()); + if (!scene) + { + osg::notify(osg::NOTICE)<<"No model loaded"<setGraphicsContext(windows[0]); + hudCamera->setViewport(0,0,windows[0]->getTraits()->width, windows[0]->getTraits()->height); + + viewer.addSlave(hudCamera, false); + + // set the scene to render + viewer.setSceneData(scene.get()); + + return viewer.run(); + + } + if (arguments.read("--CompositeViewer")) + { + // construct the viewer. + osgViewer::CompositeViewer viewer; + + // create the main 3D view + osgViewer::View* view = new osgViewer::View; + viewer.addView(view); + + view->setSceneData(scene.get()); + view->setUpViewAcrossAllScreens();; + view->setCameraManipulator(new osgGA::TrackballManipulator); + + // now create the HUD camera's view + + osgViewer::Viewer::Windows windows; + viewer.getWindows(windows); + + if (windows.empty()) return 1; + + osg::Camera* hudCamera = createHUD(); + + // set up cameras to rendering on the first window available. + hudCamera->setGraphicsContext(windows[0]); + hudCamera->setViewport(0,0,windows[0]->getTraits()->width, windows[0]->getTraits()->height); + + osgViewer::View* hudView = new osgViewer::View; + hudView->setCamera(hudCamera); + + viewer.addView(hudView); + + return viewer.run(); + + } + else + { + // construct the viewer. + osgViewer::Viewer viewer; + + osg::ref_ptr group = new osg::Group; + + // add the HUD subgraph. + if (scene.valid()) group->addChild(scene.get()); + group->addChild(createHUD()); + + // set the scene to render + viewer.setSceneData(group.get()); + + return viewer.run(); + } + }