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

Revision 13574, 11.1 kB (checked in by robert, 40 minutes ago)

From Mattias Helsing, "Seems I was only half right given what you asked for. CMP0017 only
says that modules that are found and ran from cmake modules dir should
prefer cmake-provided modules. find_package() and include() still look
in CMAKE_MODULE_PATH first.

After some investigating I've come up with a proposal examplified in
the attached FindGDAL.cmake script. It simply calls the cmake provided
FindGDAL.cmake if it exists and returns if it succeeds in finding GDAL
using that, otherwise continue with our local cmake code.
Pro: Wont clutter our root CMakeLists.txt
Con: If we begin to write more advanced Findxxx modules (using
COMPONENTS, REQUIRED etc.) we may have to revise this scheme.
"

  • 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 draw 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 it's 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 it's 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, osg::Array::BIND_OVERALL);
170
171            osg::Vec4Array* colors = new osg::Vec4Array;
172            colors->push_back(osg::Vec4(1.0f,1.0,0.8f,0.2f));
173            geom->setColorArray(colors, osg::Array::BIND_OVERALL);
174
175            geom->addPrimitiveSet(new osg::DrawArrays(GL_QUADS,0,4));
176
177            osg::StateSet* stateset = geom->getOrCreateStateSet();
178            stateset->setMode(GL_BLEND,osg::StateAttribute::ON);
179            //stateset->setAttribute(new osg::PolygonOffset(1.0f,1.0f),osg::StateAttribute::ON);
180            stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
181
182            geode->addDrawable(geom);
183        }
184
185        camera->addChild(geode);
186    }
187
188    return camera;
189}
190
191struct SnapImage : public osg::Camera::DrawCallback
192{
193    SnapImage(const std::string& filename):
194        _filename(filename),
195        _snapImage(false)
196    {
197        _image = new osg::Image;
198    }
199
200    virtual void operator () (osg::RenderInfo& renderInfo) const
201    {
202
203        if (!_snapImage) return;
204
205        osg::notify(osg::NOTICE)<<"Camera callback"<<std::endl;
206
207        osg::Camera* camera = renderInfo.getCurrentCamera();
208        osg::Viewport* viewport = camera ? camera->getViewport() : 0;
209
210        osg::notify(osg::NOTICE)<<"Camera callback "<<camera<<" "<<viewport<<std::endl;
211
212        if (viewport && _image.valid())
213        {
214            _image->readPixels(int(viewport->x()),int(viewport->y()),int(viewport->width()),int(viewport->height()),
215                               GL_RGBA,
216                               GL_UNSIGNED_BYTE);
217            osgDB::writeImageFile(*_image, _filename);
218
219            osg::notify(osg::NOTICE)<<"Taken screenshot, and written to '"<<_filename<<"'"<<std::endl;
220        }
221
222        _snapImage = false;
223    }
224
225    std::string                         _filename;
226    mutable bool                        _snapImage;
227    mutable osg::ref_ptr<osg::Image>    _image;
228};
229
230struct SnapeImageHandler : public osgGA::GUIEventHandler
231{
232
233    SnapeImageHandler(int key,SnapImage* si):
234        _key(key),
235        _snapImage(si) {}
236
237    bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter&)
238    {
239        if (ea.getHandled()) return false;
240
241        switch(ea.getEventType())
242        {
243            case(osgGA::GUIEventAdapter::KEYUP):
244            {
245                if (ea.getKey() == _key)
246                {
247                    osg::notify(osg::NOTICE)<<"event handler"<<std::endl;
248                    _snapImage->_snapImage = true;
249                    return true;
250                }
251
252                break;
253            }
254        default:
255            break;
256        }
257
258        return false;
259    }
260
261    int                     _key;
262    osg::ref_ptr<SnapImage> _snapImage;
263};
264
265
266int main( int argc, char **argv )
267{
268    // use an ArgumentParser object to manage the program arguments.
269    osg::ArgumentParser arguments(&argc,argv);
270
271
272    // read the scene from the list of file specified commandline args.
273    osg::ref_ptr<osg::Node> scene = osgDB::readNodeFiles(arguments);
274
275    // if not loaded assume no arguments passed in, try use default model instead.
276    if (!scene) scene = osgDB::readNodeFile("dumptruck.osgt");
277
278
279    if (!scene)
280    {
281        osg::notify(osg::NOTICE)<<"No model loaded"<<std::endl;
282        return 1;
283    }
284
285
286    if (arguments.read("--Viewer"))
287    {
288        // construct the viewer.
289        osgViewer::Viewer viewer;
290
291        // create a HUD as slave camera attached to the master view.
292
293        viewer.setUpViewAcrossAllScreens();
294
295        osgViewer::Viewer::Windows windows;
296        viewer.getWindows(windows);
297
298        if (windows.empty()) return 1;
299
300        osg::Camera* hudCamera = createHUD();
301
302        // set up cameras to render on the first window available.
303        hudCamera->setGraphicsContext(windows[0]);
304        hudCamera->setViewport(0,0,windows[0]->getTraits()->width, windows[0]->getTraits()->height);
305
306        viewer.addSlave(hudCamera, false);
307
308        // set the scene to render
309        viewer.setSceneData(scene.get());
310
311        return viewer.run();
312
313    }
314    if (arguments.read("--CompositeViewer"))
315    {
316        // construct the viewer.
317        osgViewer::CompositeViewer viewer;
318
319        // create the main 3D view
320        osgViewer::View* view = new osgViewer::View;
321        viewer.addView(view);
322
323        view->setSceneData(scene.get());
324        view->setUpViewAcrossAllScreens();;
325        view->setCameraManipulator(new osgGA::TrackballManipulator);
326
327        // now create the HUD camera's view
328
329        osgViewer::Viewer::Windows windows;
330        viewer.getWindows(windows);
331
332        if (windows.empty()) return 1;
333
334        osg::Camera* hudCamera = createHUD();
335
336        // set up cameras to render on the first window available.
337        hudCamera->setGraphicsContext(windows[0]);
338        hudCamera->setViewport(0,0,windows[0]->getTraits()->width, windows[0]->getTraits()->height);
339
340        osgViewer::View* hudView = new osgViewer::View;
341        hudView->setCamera(hudCamera);
342
343        viewer.addView(hudView);
344
345        return viewer.run();
346
347    }
348    else
349    {
350        // construct the viewer.
351        osgViewer::Viewer viewer;
352
353        SnapImage* postDrawCallback = new SnapImage("PostDrawCallback.png");
354        viewer.getCamera()->setPostDrawCallback(postDrawCallback);
355        viewer.addEventHandler(new SnapeImageHandler('p',postDrawCallback));
356
357        SnapImage* finalDrawCallback = new SnapImage("FinalDrawCallback.png");
358        viewer.getCamera()->setFinalDrawCallback(finalDrawCallback);
359        viewer.addEventHandler(new SnapeImageHandler('f',finalDrawCallback));
360
361        osg::ref_ptr<osg::Group> group  = new osg::Group;
362
363        // add the HUD subgraph.
364        if (scene.valid()) group->addChild(scene.get());
365        group->addChild(createHUD());
366
367        // set the scene to render
368        viewer.setSceneData(group.get());
369
370        return viewer.run();
371    }
372
373}
Note: See TracBrowser for help on using the browser.