root/OpenSceneGraph/trunk/examples/osgdepthpeeling/osgdepthpeeling.cpp @ 7648

Revision 7648, 8.0 kB (checked in by robert, 6 years ago)

From Roland Smeenk, "Attached you will find a large set of small typo fixes (mainly in the comments)."

Line 
1/*
2  Steffen Frey
3  Fachpraktikum Graphik-Programmierung 2007
4  Institut fuer Visualisierung und Interaktive Systeme
5  Universitaet Stuttgart
6 */
7
8#include <osg/GLExtensions>
9#include <osg/Node>
10#include <osg/Geometry>
11#include <osg/Notify>
12#include <osg/MatrixTransform>
13#include <osg/AnimationPath>
14
15#include <osgDB/ReadFile>
16#include <osgViewer/Viewer>
17#include <osgGA/TrackballManipulator>
18
19#include <iostream>
20
21#include "DePee.h"   
22
23/*!
24  Handles keyboard events.
25  Maintains a copy of the DePee object and part of its internal state
26  Used for example to set sketchiness, color, add or remove a depth peeling pass
27 */
28class KeyboardEventHandler : public osgGA::GUIEventHandler
29{
30public:
31 
32  KeyboardEventHandler(DePee* dePee)
33  {
34    _apc = 0;
35    _dePee = dePee;
36    _sketchy = false;
37    _sketchiness = 1.0;
38    _colored = false;
39    _edgy = true;
40    _crayon = false;
41    _dePee->setSketchy(_sketchy);
42    _dePee->setColored(_colored);
43  }
44 
45  virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&)
46  {
47    switch(ea.getEventType())
48      {
49       
50      case(osgGA::GUIEventAdapter::KEYDOWN):
51        {
52          if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Space)
53            {
54              if(_apc)
55                _apc->setPause(!_apc->getPause());
56              return true;
57            }
58          else if (ea.getKey() == 'a')
59            {
60              _dePee->addDePeePass();
61              return true;
62            }
63          else if (ea.getKey() == 'r')
64            {
65              _dePee->remDePeePass();
66              return true;
67            }
68          else if (ea.getKey() == 'c')
69            {
70              _colored = !_colored;
71              _dePee->setColored(_colored);
72              return true;
73            }
74          else if (ea.getKey() == 's')
75            {
76              _sketchy = !_sketchy;
77              _dePee->setSketchy(_sketchy);
78              return true;
79            }
80         
81          else if (ea.getKey() == 'e')
82            {
83              _edgy = !_edgy;
84              _dePee->setEdgy(_edgy);
85              return true;
86            }
87          else if (ea.getKey() == 'f')
88            {
89              return true;
90            }
91          else if (ea.getKey() == '+')
92            {
93              _sketchiness += 0.5;
94              _dePee->setSketchiness(_sketchiness);
95            }
96          else if (ea.getKey() == '-')
97            {
98              _sketchiness -= 0.5;
99              if(_sketchiness < 0.0)
100                _sketchiness = 0.0;
101              _dePee->setSketchiness(_sketchiness);
102            }
103
104          else if (ea.getKey() == 'y')
105            {
106              _crayon = !_crayon;
107              _dePee->setCrayon(_crayon);
108            }
109         
110          break;
111        }
112         
113      default:
114        break;
115       
116      }
117    return false;
118  }
119  void registerAnimationPathCallback(osg::AnimationPathCallback* apc)
120  {
121    _apc = apc;
122  }
123private:
124  DePee* _dePee;
125  bool _sketchy;
126  bool _colored;
127  bool _edgy;
128  bool _crayon;
129  double _sketchiness;
130  osg::AnimationPathCallback* _apc;
131};
132
133
134/*!
135  Handles mouse events.
136  Maintains a copy of the DePee object and part of its internal state
137  Used to rotate the object
138 */
139class MouseEventHandler : public osgGA::GUIEventHandler
140{
141public:
142 
143  MouseEventHandler(DePee* dePee)
144  {
145    _dePee = dePee;
146  }
147 
148  virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&)
149  {
150    switch(ea.getEventType())
151      {
152        //mouse
153      case(osgGA::GUIEventAdapter::DRAG):
154        {
155          rotate(ea.getXnormalized(), ea.getYnormalized());
156          break;
157        }
158      case(osgGA::GUIEventAdapter::MOVE):
159        _prevX = ea.getXnormalized();
160        _prevY = ea.getYnormalized();
161        break;
162       
163      default:
164        break;
165       
166      }
167    return false;
168  }
169  void registerModelGroupTransform(osg::MatrixTransform* modelGroupTransform)
170  {
171    _modelGroupTransform = modelGroupTransform;
172    _rotCenter = modelGroupTransform->getBound().center();
173  }
174private:
175  void rotate(float x, float y)
176  {
177    osg::Matrixd baseMatrix = _modelGroupTransform->getMatrix();
178   
179    osg::Matrixd preTransMatrix;
180    osg::Matrixd postTransMatrix;
181    osg::Matrixd rotMatrixX;
182    osg::Matrixd rotMatrixZ;
183   
184    preTransMatrix.makeTranslate(_rotCenter);
185    postTransMatrix.makeTranslate(-_rotCenter);
186
187    rotMatrixZ.makeRotate((x - _prevX) * 3., osg::Vec3d(0.0, 0.0,1.0));
188   
189    baseMatrix.preMult(preTransMatrix);
190    baseMatrix.preMult(rotMatrixZ);
191    baseMatrix.preMult(postTransMatrix);
192
193    rotMatrixX.makeRotate(-(y - _prevY) * 3., (baseMatrix * osg::Vec3d(1.0, 0.0,0.0)));
194   
195    baseMatrix.preMult(preTransMatrix);
196    baseMatrix.preMult(rotMatrixX);
197    baseMatrix.preMult(postTransMatrix);
198   
199    _modelGroupTransform->setMatrix(baseMatrix);
200
201    _prevX = x;
202    _prevY = y;
203  };
204 
205  DePee* _dePee;
206 
207  float _prevX;
208  float _prevY;
209 
210  osg::Vec3 _rotCenter;
211  osg::MatrixTransform* _modelGroupTransform;
212};
213
214
215
216int main( int argc, char **argv )
217{
218  // use an ArgumentParser object to manage the program arguments.
219  osg::ArgumentParser arguments(&argc,argv);
220 
221  // set up the usage document, in case we need to print out how to use this program.
222  arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the example which demonstrates Depth Peeling");
223  arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" filename");
224 
225 
226  // construct the viewer
227  osgViewer::Viewer viewer(arguments);
228   
229  // any option left unread are converted into errors to write out later.
230  arguments.reportRemainingOptionsAsUnrecognized();
231 
232  // report any errors if they have occurred when parsing the program arguments.
233  if (arguments.errors())
234  {
235      arguments.writeErrorMessages(std::cout);
236      return 1;
237  }
238 
239  if (arguments.argc()<=1 || arguments.argc() > 3)
240  {
241        arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION);
242        return 1;
243  }
244
245
246  //only displays a textured quad
247  viewer.getCamera()->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
248
249  // read the model to do depth peeling with
250  osg::Node* loadedModel = osgDB::readNodeFile(arguments.argv()[1]);
251 
252  if (!loadedModel)
253    return 1;
254   
255  // create a transform to spin the model.
256  osg::MatrixTransform* modelGroupTransform = new osg::MatrixTransform;
257  osg::Group* modelGroup = new osg::Group;
258  modelGroupTransform->addChild(modelGroup);
259  modelGroup->addChild(loadedModel);
260 
261  osg::Group* rootNode = new osg::Group();
262 
263  // add model to the viewer.
264  viewer.setSceneData(rootNode);
265 
266  // Depth peel example only works on a single graphics context right now
267  // so open up viewer on single screen to prevent problems
268  viewer.setUpViewOnSingleScreen(0);
269 
270  // create the windows and run the threads.
271  viewer.realize();
272 
273  unsigned int width = 1280;
274  unsigned int height = 1280;
275  osgViewer::Viewer::Windows windows;
276  viewer.getWindows(windows);
277  if (!windows.empty())
278  {
279    width = windows.front()->getTraits()->width;
280    height = windows.front()->getTraits()->height;
281  }
282
283
284  osg::ref_ptr<DePee> dePee = new DePee(rootNode,
285                                modelGroupTransform,
286                                width,
287                                height);
288 
289  //create event handlers
290  KeyboardEventHandler* keyboardEventHandler = new KeyboardEventHandler(dePee.get());
291  MouseEventHandler* mouseEventHandler = new MouseEventHandler(dePee.get());
292  viewer.addEventHandler(keyboardEventHandler);
293  viewer.addEventHandler(mouseEventHandler);
294
295  //viewer.setCameraManipulator(new osgGA::TrackballManipulator);
296   
297  osg::StateSet* stateset = modelGroupTransform->getOrCreateStateSet();
298
299  stateset->setMode(GL_BLEND, osg::StateAttribute::OFF);
300
301  //create new animation callback for autmatic object rotation
302  osg::AnimationPathCallback* apc = new osg::AnimationPathCallback(modelGroupTransform->getBound().center(),osg::Vec3(0.0f,0.0f,1.0f),osg::inDegrees(45.0f));
303  apc->setPause(true);
304  modelGroupTransform->setUpdateCallback(apc);
305 
306  keyboardEventHandler->registerAnimationPathCallback(apc);
307  mouseEventHandler->registerModelGroupTransform(modelGroupTransform);
308   
309  //setup stuff that is necessary for measuring fps
310  osg::Timer_t current_tick, previous_tick = 1;
311  double* fps = new double;
312  dePee->setFPS(fps);
313 
314  while(!viewer.done())
315  {
316    current_tick = osg::Timer::instance()->tick();
317
318    *fps = 1.0/osg::Timer::instance()->delta_s(previous_tick,current_tick);
319    dePee->updateHUDText();
320
321    previous_tick = current_tick;
322
323    // fire off the cull and draw traversals of the scene.
324    viewer.frame();
325  }
326
327  return 0;
328}
Note: See TracBrowser for help on using the browser.