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

Revision 9459, 11.4 kB (checked in by robert, 5 years ago)

Fixed warnings

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* OpenSceneGraph example, osghud.
2*
3*  Permission is hereby granted, free of charge, to any person obtaining a copy
4*  of this software and associated documentation files (the "Software"), to deal
5*  in the Software without restriction, including without limitation the rights
6*  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7*  copies of the Software, and to permit persons to whom the Software is
8*  furnished to do so, subject to the following conditions:
9*
10*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
11*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12*  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
13*  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
14*  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
15*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
16*  THE SOFTWARE.
17*/
18
19#include <osgUtil/Optimizer>
20#include <osgDB/ReadFile>
21
22#include <osgViewer/Viewer>
23#include <osgViewer/CompositeViewer>
24
25#include <osgGA/TrackballManipulator>
26
27#include <osg/Material>
28#include <osg/Geode>
29#include <osg/BlendFunc>
30#include <osg/Depth>
31#include <osg/PolygonOffset>
32#include <osg/MatrixTransform>
33#include <osg/Camera>
34#include <osg/RenderInfo>
35
36#include <osgDB/WriteFile>
37
38#include <osgText/Text>
39
40
41osg::Camera* createHUD()
42{
43    // create a camera to set up the projection and model view matrices, and the subgraph to drawn in the HUD
44    osg::Camera* camera = new osg::Camera;
45
46    // set the projection matrix
47    camera->setProjectionMatrix(osg::Matrix::ortho2D(0,1280,0,1024));
48
49    // set the view matrix   
50    camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
51    camera->setViewMatrix(osg::Matrix::identity());
52
53    // only clear the depth buffer
54    camera->setClearMask(GL_DEPTH_BUFFER_BIT);
55
56    // draw subgraph after main camera view.
57    camera->setRenderOrder(osg::Camera::POST_RENDER);
58
59    // we don't want the camera to grab event focus from the viewers main camera(s).
60    camera->setAllowEventFocus(false);
61   
62
63
64    // add to this camera a subgraph to render
65    {
66
67        osg::Geode* geode = new osg::Geode();
68
69        std::string timesFont("fonts/arial.ttf");
70
71        // turn lighting off for the text and disable depth test to ensure its always ontop.
72        osg::StateSet* stateset = geode->getOrCreateStateSet();
73        stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
74
75        osg::Vec3 position(150.0f,800.0f,0.0f);
76        osg::Vec3 delta(0.0f,-120.0f,0.0f);
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("Head Up Displays are simple :-)");
85
86            position += delta;
87        }   
88
89
90        {
91            osgText::Text* text = new  osgText::Text;
92            geode->addDrawable( text );
93
94            text->setFont(timesFont);
95            text->setPosition(position);
96            text->setText("All you need to do is create your text in a subgraph.");
97
98            position += delta;
99        }   
100
101
102        {
103            osgText::Text* text = new  osgText::Text;
104            geode->addDrawable( text );
105
106            text->setFont(timesFont);
107            text->setPosition(position);
108            text->setText("Then place an osg::Camera above the subgraph\n"
109                          "to create an orthographic projection.\n");
110
111            position += delta;
112        }
113
114        {
115            osgText::Text* text = new  osgText::Text;
116            geode->addDrawable( text );
117
118            text->setFont(timesFont);
119            text->setPosition(position);
120            text->setText("Set the Camera's ReferenceFrame to ABSOLUTE_RF to ensure\n"
121                          "it remains independent from any external model view matrices.");
122
123            position += delta;
124        }
125
126        {
127            osgText::Text* text = new  osgText::Text;
128            geode->addDrawable( text );
129
130            text->setFont(timesFont);
131            text->setPosition(position);
132            text->setText("And set the Camera's clear mask to just clear the depth buffer.");
133
134            position += delta;
135        }   
136
137        {
138            osgText::Text* text = new  osgText::Text;
139            geode->addDrawable( text );
140
141            text->setFont(timesFont);
142            text->setPosition(position);
143            text->setText("And finally set the Camera's RenderOrder to POST_RENDER\n"
144                          "to make sure its drawn last.");
145
146            position += delta;
147        }   
148
149
150        {
151            osg::BoundingBox bb;
152            for(unsigned int i=0;i<geode->getNumDrawables();++i)
153            {
154                bb.expandBy(geode->getDrawable(i)->getBound());
155            }
156
157            osg::Geometry* geom = new osg::Geometry;
158
159            osg::Vec3Array* vertices = new osg::Vec3Array;
160            float depth = bb.zMin()-0.1;
161            vertices->push_back(osg::Vec3(bb.xMin(),bb.yMax(),depth));
162            vertices->push_back(osg::Vec3(bb.xMin(),bb.yMin(),depth));
163            vertices->push_back(osg::Vec3(bb.xMax(),bb.yMin(),depth));
164            vertices->push_back(osg::Vec3(bb.xMax(),bb.yMax(),depth));
165            geom->setVertexArray(vertices);
166
167            osg::Vec3Array* normals = new osg::Vec3Array;
168            normals->push_back(osg::Vec3(0.0f,0.0f,1.0f));
169            geom->setNormalArray(normals);
170            geom->setNormalBinding(osg::Geometry::BIND_OVERALL);
171
172            osg::Vec4Array* colors = new osg::Vec4Array;
173            colors->push_back(osg::Vec4(1.0f,1.0,0.8f,0.2f));
174            geom->setColorArray(colors);
175            geom->setColorBinding(osg::Geometry::BIND_OVERALL);
176
177            geom->addPrimitiveSet(new osg::DrawArrays(GL_QUADS,0,4));
178
179            osg::StateSet* stateset = geom->getOrCreateStateSet();
180            stateset->setMode(GL_BLEND,osg::StateAttribute::ON);
181            //stateset->setAttribute(new osg::PolygonOffset(1.0f,1.0f),osg::StateAttribute::ON);
182            stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
183
184            geode->addDrawable(geom);
185        }
186
187        camera->addChild(geode);
188    }
189
190    return camera;
191}
192
193struct SnapImage : public osg::Camera::DrawCallback
194{
195    SnapImage(const std::string& filename):
196        _filename(filename),
197        _snapImage(false)
198    {
199        _image = new osg::Image;       
200    }
201
202    virtual void operator () (osg::RenderInfo& renderInfo) const
203    {
204
205        if (!_snapImage) return;
206   
207        osg::notify(osg::NOTICE)<<"Camera callback"<<std::endl;
208
209        osg::Camera* camera = renderInfo.getCurrentCamera();
210        osg::Viewport* viewport = camera ? camera->getViewport() : 0;
211
212        osg::notify(osg::NOTICE)<<"Camera callback "<<camera<<" "<<viewport<<std::endl;
213
214        if (viewport && _image.valid())
215        {
216            _image->readPixels(int(viewport->x()),int(viewport->y()),int(viewport->width()),int(viewport->height()),
217                               GL_RGBA,
218                               GL_UNSIGNED_BYTE);
219            osgDB::writeImageFile(*_image, _filename);
220           
221            osg::notify(osg::NOTICE)<<"Taken screenshot, and written to '"<<_filename<<"'"<<std::endl;             
222        }
223       
224        _snapImage = false;
225    }
226
227    std::string                         _filename;
228    mutable bool                        _snapImage;
229    mutable osg::ref_ptr<osg::Image>    _image;
230};
231
232struct SnapeImageHandler : public osgGA::GUIEventHandler
233{
234
235    SnapeImageHandler(int key,SnapImage* si):
236        _key(key),
237        _snapImage(si) {}
238
239    bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter&)
240    {
241        if (ea.getHandled()) return false;
242
243        switch(ea.getEventType())
244        {
245            case(osgGA::GUIEventAdapter::KEYUP):
246            {
247                if (ea.getKey() == _key)
248                {
249                    osg::notify(osg::NOTICE)<<"event handler"<<std::endl;
250                    _snapImage->_snapImage = true;
251                    return true;
252                }
253
254                break;
255            }
256        default:
257            break;
258        }
259
260        return false;
261    }
262   
263    int                     _key;
264    osg::ref_ptr<SnapImage> _snapImage;
265};
266
267
268int main( int argc, char **argv )
269{
270    // use an ArgumentParser object to manage the program arguments.
271    osg::ArgumentParser arguments(&argc,argv);
272
273
274    // read the scene from the list of file specified commandline args.
275    osg::ref_ptr<osg::Node> scene = osgDB::readNodeFiles(arguments);
276   
277    // if not loaded assume no arguments passed in, try use default mode instead.
278    if (!scene) scene = osgDB::readNodeFile("dumptruck.osg");
279   
280   
281    if (!scene)
282    {
283        osg::notify(osg::NOTICE)<<"No model loaded"<<std::endl;
284        return 1;
285    }
286
287
288    if (arguments.read("--Viewer"))
289    {
290        // construct the viewer.
291        osgViewer::Viewer viewer;
292
293        // create a HUD as slave camera attached to the master view.
294       
295        viewer.setUpViewAcrossAllScreens();
296
297        osgViewer::Viewer::Windows windows;
298        viewer.getWindows(windows);
299       
300        if (windows.empty()) return 1;
301       
302        osg::Camera* hudCamera = createHUD();
303       
304        // set up cameras to rendering on the first window available.
305        hudCamera->setGraphicsContext(windows[0]);
306        hudCamera->setViewport(0,0,windows[0]->getTraits()->width, windows[0]->getTraits()->height);
307
308        viewer.addSlave(hudCamera, false);
309
310        // set the scene to render
311        viewer.setSceneData(scene.get());
312
313        return viewer.run();
314
315    }
316    if (arguments.read("--CompositeViewer"))
317    {
318        // construct the viewer.
319        osgViewer::CompositeViewer viewer;
320
321        // create the main 3D view
322        osgViewer::View* view = new osgViewer::View;
323        viewer.addView(view);
324
325        view->setSceneData(scene.get());
326        view->setUpViewAcrossAllScreens();;
327        view->setCameraManipulator(new osgGA::TrackballManipulator);
328
329        // now create the HUD camera's view
330       
331        osgViewer::Viewer::Windows windows;
332        viewer.getWindows(windows);
333       
334        if (windows.empty()) return 1;
335       
336        osg::Camera* hudCamera = createHUD();
337       
338        // set up cameras to rendering on the first window available.
339        hudCamera->setGraphicsContext(windows[0]);
340        hudCamera->setViewport(0,0,windows[0]->getTraits()->width, windows[0]->getTraits()->height);
341       
342        osgViewer::View* hudView = new osgViewer::View;
343        hudView->setCamera(hudCamera);
344       
345        viewer.addView(hudView);
346
347        return viewer.run();
348
349    }
350    else
351    {
352        // construct the viewer.
353        osgViewer::Viewer viewer;
354       
355        SnapImage* postDrawCallback = new SnapImage("PostDrawCallback.png");
356        viewer.getCamera()->setPostDrawCallback(postDrawCallback);       
357        viewer.addEventHandler(new SnapeImageHandler('p',postDrawCallback));
358       
359        SnapImage* finalDrawCallback = new SnapImage("FinalDrawCallback.png");
360        viewer.getCamera()->setFinalDrawCallback(finalDrawCallback);       
361        viewer.addEventHandler(new SnapeImageHandler('f',finalDrawCallback));
362
363        osg::ref_ptr<osg::Group> group  = new osg::Group;
364
365        // add the HUD subgraph.   
366        if (scene.valid()) group->addChild(scene.get());
367        group->addChild(createHUD());
368
369        // set the scene to render
370        viewer.setSceneData(group.get());
371
372        return viewer.run();
373    }
374   
375}
Note: See TracBrowser for help on using the browser.