1 /* OpenSceneGraph example, osgmotionblur.
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
20 #include <osgDB/ReadFile>
21 #include <osgUtil/Optimizer>
22 #include <osgViewer/Viewer>
23 #include <iostream>
24
25 class MotionBlurOperation: public osg::Operation
26 {
27 public:
MotionBlurOperation(double persistence)28 MotionBlurOperation(double persistence):
29 osg::Referenced(true),
30 osg::Operation("MotionBlur",true),
31 cleared_(false),
32 persistence_(persistence)
33 {
34 }
35
operator ()(osg::Object * object)36 virtual void operator () (osg::Object* object)
37 {
38 osg::GraphicsContext* gc = dynamic_cast<osg::GraphicsContext*>(object);
39 if (!gc) return;
40
41 double t = gc->getState()->getFrameStamp()->getSimulationTime();
42
43 if (!cleared_)
44 {
45 // clear the accumulation buffer
46 glClearColor(0, 0, 0, 0);
47 glClear(GL_ACCUM_BUFFER_BIT);
48 cleared_ = true;
49 t0_ = t;
50 }
51
52 double dt = fabs(t - t0_);
53 t0_ = t;
54
55 // compute the blur factor
56 double s = powf(0.2, dt / persistence_);
57
58 // scale, accumulate and return
59 glAccum(GL_MULT, s);
60 glAccum(GL_ACCUM, 1 - s);
61 glAccum(GL_RETURN, 1.0f);
62 }
63
64 private:
65 bool cleared_;
66 double t0_;
67 double persistence_;
68 };
69
70
main(int argc,char ** argv)71 int main( int argc, char **argv )
72 {
73
74 // use an ArgumentParser object to manage the program arguments.
75 osg::ArgumentParser arguments(&argc,argv);
76
77 // set up the usage document, in case we need to print out how to use this program.
78 arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName());
79 arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is an OpenSceneGraph example that shows how to use the accumulation buffer to achieve a simple motion blur effect.");
80 arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ...");
81 arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
82 arguments.getApplicationUsage()->addCommandLineOption("-P or --persistence","Set the motion blur persistence time");
83
84
85 // construct the viewer.
86 osgViewer::Viewer viewer;
87
88 // if user request help write it out to cout.
89 if (arguments.read("-h") || arguments.read("--help"))
90 {
91 arguments.getApplicationUsage()->write(std::cout);
92 return 1;
93 }
94
95 double persistence = 0.25;
96 arguments.read("-P", persistence) || arguments.read("--persistence", persistence);
97
98 // read the scene from the list of file specified commandline args.
99 osg::ref_ptr<osg::Node> loadedModel = osgDB::readRefNodeFiles(arguments);
100
101 // if not loaded assume no arguments passed in, try use default mode instead.
102 if (!loadedModel) loadedModel = osgDB::readRefNodeFile("cow.osgt");
103
104 // if no model has been successfully loaded report failure.
105 if (!loadedModel)
106 {
107 std::cout << arguments.getApplicationName() <<": No data loaded" << std::endl;
108 return 1;
109 }
110
111
112 // set the display settings we can to request, OsgCameraGroup will read this.
113 osg::DisplaySettings::instance()->setMinimumNumAccumBits(8,8,8,8);
114
115 // pass the loaded scene graph to the viewer.
116 viewer.setSceneData(loadedModel.get());
117
118 // create the windows and run the threads.
119 viewer.realize();
120
121 osgViewer::Viewer::Windows windows;
122 viewer.getWindows(windows);
123 for(osgViewer::Viewer::Windows::iterator itr = windows.begin();
124 itr != windows.end();
125 ++itr)
126 {
127 (*itr)->add(new MotionBlurOperation(persistence));
128 }
129
130 return viewer.run();
131 }
132