root/OpenSceneGraph/trunk/examples/osghud/osghud.cpp @ 1983

Revision 1983, 7.6 kB (checked in by don, 11 years ago)

*** empty log message ***

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under 
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * OpenSceneGraph Public License for more details.
12*/
13
14#include <osgUtil/Optimizer>
15#include <osgDB/ReadFile>
16#include <osgProducer/Viewer>
17
18#include <osg/Material>
19#include <osg/Geode>
20#include <osg/BlendFunc>
21#include <osg/Depth>
22#include <osg/Projection>
23#include <osg/PolygonOffset>
24#include <osg/MatrixTransform>
25
26#include <osgText/Text>
27
28
29osg::Node* createHUD()
30{
31    osg::Geode* geode = new osg::Geode();
32   
33    std::string timesFont("fonts/arial.ttf");
34
35    // turn lighting off for the text and disable depth test to ensure its always ontop.
36    osg::StateSet* stateset = geode->getOrCreateStateSet();
37    stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
38
39#if 0
40    // to ensure the hud appears on top we can either use osg::Depth to force the
41    // depth fragments to be placed at the front of the screen.
42    stateset->setAttribute(new osg::Depth(osg::Depth::LESS,0.0,0.0001));
43#else
44    // or disable depth test, and make sure that the hud is drawn after everything
45    // else so that it always appears ontop.
46    stateset->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF);
47    stateset->setRenderBinDetails(11,"RenderBin");
48#endif
49
50    osg::Vec3 position(150.0f,800.0f,0.0f);
51    osg::Vec3 delta(0.0f,-120.0f,0.0f);
52
53    {
54        osgText::Text* text = new  osgText::Text;
55        geode->addDrawable( text );
56
57        text->setFont(timesFont);
58        text->setPosition(position);
59        text->setText("Head Up Displays are simple :-)");
60       
61        position += delta;
62    }   
63
64
65    {
66        osgText::Text* text = new  osgText::Text;
67        geode->addDrawable( text );
68
69        text->setFont(timesFont);
70        text->setPosition(position);
71        text->setText("All you need to do is create your text in a subgraph.");
72       
73        position += delta;
74    }   
75
76
77    {
78        osgText::Text* text = new  osgText::Text;
79        geode->addDrawable( text );
80
81        text->setFont(timesFont);
82        text->setPosition(position);
83        text->setText("Disable depth test in this subgraph to ensure its always ontop.");
84       
85        position += delta;
86    }   
87
88    {
89        osgText::Text* text = new  osgText::Text;
90        geode->addDrawable( text );
91
92        text->setFont(timesFont);
93        text->setPosition(position);
94        text->setText("Then place an osg::Projection node above the subgraph\nto create an orthographic projection.");
95       
96        position += delta;
97    }   
98
99    {
100        osgText::Text* text = new  osgText::Text;
101        geode->addDrawable( text );
102
103        text->setFont(timesFont);
104        text->setPosition(position);
105        text->setText("And add an osg::ModelViewMatrix set to ABSOLUTE to ensure\nit remains independent from any external model view matrices.");
106       
107        position += delta;
108    }
109   
110   
111   
112    {
113        osg::BoundingBox bb;
114        for(unsigned int i=0;i<geode->getNumDrawables();++i)
115        {
116            bb.expandBy(geode->getDrawable(i)->getBound());
117        }
118
119        osg::Geometry* geom = new osg::Geometry;
120
121        osg::Vec3Array* vertices = new osg::Vec3Array;
122        float depth = bb.zMin()-0.1;
123        vertices->push_back(osg::Vec3(bb.xMin(),bb.yMax(),depth));
124        vertices->push_back(osg::Vec3(bb.xMin(),bb.yMin(),depth));
125        vertices->push_back(osg::Vec3(bb.xMax(),bb.yMin(),depth));
126        vertices->push_back(osg::Vec3(bb.xMax(),bb.yMax(),depth));
127        geom->setVertexArray(vertices);
128
129        osg::Vec3Array* normals = new osg::Vec3Array;
130        normals->push_back(osg::Vec3(0.0f,0.0f,1.0f));
131        geom->setNormalArray(normals);
132        geom->setNormalBinding(osg::Geometry::BIND_OVERALL);
133
134        osg::Vec4Array* colors = new osg::Vec4Array;
135        colors->push_back(osg::Vec4(1.0f,1.0,0.8f,0.2f));
136        geom->setColorArray(colors);
137        geom->setColorBinding(osg::Geometry::BIND_OVERALL);
138
139        geom->addPrimitiveSet(new osg::DrawArrays(GL_QUADS,0,4));
140       
141        osg::StateSet* stateset = geom->getOrCreateStateSet();
142        stateset->setMode(GL_BLEND,osg::StateAttribute::ON);
143        //stateset->setAttribute(new osg::PolygonOffset(1.0f,1.0f),osg::StateAttribute::ON);
144        stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
145
146        geode->addDrawable(geom);
147    }
148
149    // create the hud.
150    osg::MatrixTransform* modelview_abs = new osg::MatrixTransform;
151    modelview_abs->setReferenceFrame(osg::Transform::RELATIVE_TO_ABSOLUTE);
152    modelview_abs->setMatrix(osg::Matrix::identity());
153    modelview_abs->addChild(geode);
154
155    osg::Projection* projection = new osg::Projection;
156    projection->setMatrix(osg::Matrix::ortho2D(0,1280,0,1024));
157    projection->addChild(modelview_abs);
158
159    return projection;
160
161}
162
163int main( int argc, char **argv )
164{
165
166    // use an ArgumentParser object to manage the program arguments.
167    osg::ArgumentParser arguments(&argc,argv);
168   
169    // set up the usage document, in case we need to print out how to use this program.
170    arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the example which demonstrates how to do Head Up Displays.");
171    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] [filename] ...");
172    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
173   
174
175    // construct the viewer.
176    osgProducer::Viewer viewer(arguments);
177
178    // set up the value with sensible default event handlers.
179    viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS);
180
181    // get details on keyboard and mouse bindings used by the viewer.
182    viewer.getUsage(*arguments.getApplicationUsage());
183
184    // if user request help write it out to cout.
185    if (arguments.read("-h") || arguments.read("--help"))
186    {
187        arguments.getApplicationUsage()->write(std::cout);
188        return 1;
189    }
190
191    // any option left unread are converted into errors to write out later.
192    arguments.reportRemainingOptionsAsUnrecognized();
193
194    // report any errors if they have occured when parsing the program aguments.
195    if (arguments.errors())
196    {
197        arguments.writeErrorMessages(std::cout);
198        return 1;
199    }
200   
201    // read the scene from the list of file specified commandline args.
202    osg::ref_ptr<osg::Node> scene = osgDB::readNodeFiles(arguments);
203
204    osg::ref_ptr<osg::Group> group = dynamic_cast<osg::Group*>(scene.get());
205    if (!group)
206    {
207        group = new osg::Group;
208        group->addChild(scene.get());
209    }
210
211    // add the HUD subgraph.   
212    group->addChild(createHUD());
213
214    // set the scene to render
215    viewer.setSceneData(group.get());
216
217    // create the windows and run the threads.
218    viewer.realize();
219
220    while( !viewer.done() )
221    {
222        // wait for all cull and draw threads to complete.
223        viewer.sync();
224
225        // update the scene by traversing it with the the update visitor which will
226        // call all node update callbacks and animations.
227        viewer.update();
228         
229        // fire off the cull and draw traversals of the scene.
230        viewer.frame();
231       
232    }
233   
234    // wait for all cull and draw threads to complete before exit.
235    viewer.sync();
236   
237    return 0;
238}
Note: See TracBrowser for help on using the browser.