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

Revision 6263, 8.4 kB (checked in by robert, 7 years ago)

Added new --Viewer and --CompositeViewer? for implementation of HUDs

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 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
17#include <osgViewer/Viewer>
18#include <osgViewer/CompositeViewer>
19
20#include <osgGA/TrackballManipulator>
21
22#include <osg/Material>
23#include <osg/Geode>
24#include <osg/BlendFunc>
25#include <osg/Depth>
26#include <osg/PolygonOffset>
27#include <osg/MatrixTransform>
28#include <osg/Camera>
29
30#include <osgText/Text>
31
32
33osg::Camera* createHUD()
34{
35    // create a camera to set up the projection and model view matrices, and the subgraph to drawn in the HUD
36    osg::Camera* camera = new osg::Camera;
37
38    // set the projection matrix
39    camera->setProjectionMatrix(osg::Matrix::ortho2D(0,1280,0,1024));
40
41    // set the view matrix   
42    camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
43    camera->setViewMatrix(osg::Matrix::identity());
44
45    // only clear the depth buffer
46    camera->setClearMask(GL_DEPTH_BUFFER_BIT);
47
48    // draw subgraph after main camera view.
49    camera->setRenderOrder(osg::Camera::POST_RENDER);
50
51    // we don't want the camera to grab event focus from the viewers main camera(s).
52    camera->setAllowEventFocus(false);
53   
54
55
56    // add to this camera a subgraph to render
57    {
58
59        osg::Geode* geode = new osg::Geode();
60
61        std::string timesFont("fonts/arial.ttf");
62
63        // turn lighting off for the text and disable depth test to ensure its always ontop.
64        osg::StateSet* stateset = geode->getOrCreateStateSet();
65        stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
66
67        osg::Vec3 position(150.0f,800.0f,0.0f);
68        osg::Vec3 delta(0.0f,-120.0f,0.0f);
69
70        {
71            osgText::Text* text = new  osgText::Text;
72            geode->addDrawable( text );
73
74            text->setFont(timesFont);
75            text->setPosition(position);
76            text->setText("Head Up Displays are simple :-)");
77
78            position += delta;
79        }   
80
81
82        {
83            osgText::Text* text = new  osgText::Text;
84            geode->addDrawable( text );
85
86            text->setFont(timesFont);
87            text->setPosition(position);
88            text->setText("All you need to do is create your text in a subgraph.");
89
90            position += delta;
91        }   
92
93
94        {
95            osgText::Text* text = new  osgText::Text;
96            geode->addDrawable( text );
97
98            text->setFont(timesFont);
99            text->setPosition(position);
100            text->setText("Then place an osg::Camera above the subgraph\n"
101                          "to create an orthographic projection.\n");
102
103            position += delta;
104        }
105
106        {
107            osgText::Text* text = new  osgText::Text;
108            geode->addDrawable( text );
109
110            text->setFont(timesFont);
111            text->setPosition(position);
112            text->setText("Set the Camera's ReferenceFrame to ABSOLUTE_RF to ensure\n"
113                          "it remains independent from any external model view matrices.");
114
115            position += delta;
116        }
117
118        {
119            osgText::Text* text = new  osgText::Text;
120            geode->addDrawable( text );
121
122            text->setFont(timesFont);
123            text->setPosition(position);
124            text->setText("And set the Camera's clear mask to just clear the depth buffer.");
125
126            position += delta;
127        }   
128
129        {
130            osgText::Text* text = new  osgText::Text;
131            geode->addDrawable( text );
132
133            text->setFont(timesFont);
134            text->setPosition(position);
135            text->setText("And finally set the Camera's RenderOrder to POST_RENDER\n"
136                          "to make sure its drawn last.");
137
138            position += delta;
139        }   
140
141
142        {
143            osg::BoundingBox bb;
144            for(unsigned int i=0;i<geode->getNumDrawables();++i)
145            {
146                bb.expandBy(geode->getDrawable(i)->getBound());
147            }
148
149            osg::Geometry* geom = new osg::Geometry;
150
151            osg::Vec3Array* vertices = new osg::Vec3Array;
152            float depth = bb.zMin()-0.1;
153            vertices->push_back(osg::Vec3(bb.xMin(),bb.yMax(),depth));
154            vertices->push_back(osg::Vec3(bb.xMin(),bb.yMin(),depth));
155            vertices->push_back(osg::Vec3(bb.xMax(),bb.yMin(),depth));
156            vertices->push_back(osg::Vec3(bb.xMax(),bb.yMax(),depth));
157            geom->setVertexArray(vertices);
158
159            osg::Vec3Array* normals = new osg::Vec3Array;
160            normals->push_back(osg::Vec3(0.0f,0.0f,1.0f));
161            geom->setNormalArray(normals);
162            geom->setNormalBinding(osg::Geometry::BIND_OVERALL);
163
164            osg::Vec4Array* colors = new osg::Vec4Array;
165            colors->push_back(osg::Vec4(1.0f,1.0,0.8f,0.2f));
166            geom->setColorArray(colors);
167            geom->setColorBinding(osg::Geometry::BIND_OVERALL);
168
169            geom->addPrimitiveSet(new osg::DrawArrays(GL_QUADS,0,4));
170
171            osg::StateSet* stateset = geom->getOrCreateStateSet();
172            stateset->setMode(GL_BLEND,osg::StateAttribute::ON);
173            //stateset->setAttribute(new osg::PolygonOffset(1.0f,1.0f),osg::StateAttribute::ON);
174            stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
175
176            geode->addDrawable(geom);
177        }
178
179        camera->addChild(geode);
180    }
181
182    return camera;
183}
184
185int main( int argc, char **argv )
186{
187    // use an ArgumentParser object to manage the program arguments.
188    osg::ArgumentParser arguments(&argc,argv);
189
190
191    // read the scene from the list of file specified commandline args.
192    osg::ref_ptr<osg::Node> scene = osgDB::readNodeFiles(arguments);
193   
194    if (!scene)
195    {
196        osg::notify(osg::NOTICE)<<"No model loaded"<<std::endl;
197        return 1;
198    }
199
200
201    if (arguments.read("--Viewer"))
202    {
203        // construct the viewer.
204        osgViewer::Viewer viewer;
205
206        // create a HUD as slave camera attached to the master view.
207       
208        viewer.setUpViewAcrossAllScreens();
209
210        osgViewer::Viewer::Windows windows;
211        viewer.getWindows(windows);
212       
213        if (windows.empty()) return 1;
214       
215        osg::Camera* hudCamera = createHUD();
216       
217        // set up cameras to rendering on the first window available.
218        hudCamera->setGraphicsContext(windows[0]);
219        hudCamera->setViewport(0,0,windows[0]->getTraits()->width, windows[0]->getTraits()->height);
220
221        viewer.addSlave(hudCamera, false);
222
223        // set the scene to render
224        viewer.setSceneData(scene.get());
225
226        return viewer.run();
227
228    }
229    if (arguments.read("--CompositeViewer"))
230    {
231        // construct the viewer.
232        osgViewer::CompositeViewer viewer;
233
234        // create the main 3D view
235        osgViewer::View* view = new osgViewer::View;
236        viewer.addView(view);
237
238        view->setSceneData(scene.get());
239        view->setUpViewAcrossAllScreens();;
240        view->setCameraManipulator(new osgGA::TrackballManipulator);
241
242        // now create the HUD camera's view
243       
244        osgViewer::Viewer::Windows windows;
245        viewer.getWindows(windows);
246       
247        if (windows.empty()) return 1;
248       
249        osg::Camera* hudCamera = createHUD();
250       
251        // set up cameras to rendering on the first window available.
252        hudCamera->setGraphicsContext(windows[0]);
253        hudCamera->setViewport(0,0,windows[0]->getTraits()->width, windows[0]->getTraits()->height);
254       
255        osgViewer::View* hudView = new osgViewer::View;
256        hudView->setCamera(hudCamera);
257       
258        viewer.addView(hudView);
259
260        return viewer.run();
261
262    }
263    else
264    {
265        // construct the viewer.
266        osgViewer::Viewer viewer;
267
268        osg::ref_ptr<osg::Group> group  = new osg::Group;
269
270        // add the HUD subgraph.   
271        if (scene.valid()) group->addChild(scene.get());
272        group->addChild(createHUD());
273
274        // set the scene to render
275        viewer.setSceneData(group.get());
276
277        return viewer.run();
278    }
279   
280}
Note: See TracBrowser for help on using the browser.