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

Revision 4332, 8.1 kB (checked in by robert, 9 years ago)

Work on the RenderToTexture? usage of the new osg::CameraNode?. Both osghud
and osgprerender now ported across to osg::CameraNode?.

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