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

Revision 13574, 11.1 kB (checked in by robert, 42 hours ago)

Added shaders to support experimental shader based displacement mapping technique osgTerrain::ShaderTerrain?.

  • 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.