root/OpenSceneGraph/trunk/examples/osgprecipitation/osgprecipitation.cpp @ 5076

Revision 5076, 9.4 kB (checked in by robert, 8 years ago)

Added beginings osgprecipitation example.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
2 *
3 * This application is open source and may be redistributed and/or modified   
4 * freely and without restriction, both in commericial and non commericial applications,
5 * as long as this copyright notice is maintained.
6 *
7 * This application is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10*/
11
12#include <osgDB/ReadFile>
13#include <osgDB/FileUtils>
14#include <osgUtil/Optimizer>
15#include <osgProducer/Viewer>
16
17#include <osg/Point>
18#include <osg/BlendFunc>
19#include <osg/Texture2D>
20#include <osg/PointSprite>
21#include <osg/Program>
22
23float random(float min,float max) { return min + (max-min)*(float)rand()/(float)RAND_MAX; }
24
25osg::Node* createRainEffect(const osg::BoundingBox& bb, const osg::Vec3& velocity, unsigned int numParticles, bool useShaders)
26{
27    osg::Geometry* geometry = new osg::Geometry;
28
29    osg::StateSet* stateset = geometry->getOrCreateStateSet();
30
31    // set up geometry.
32    {
33   
34        // per vertex properties
35        osg::Vec3Array* vertices = new osg::Vec3Array(numParticles*2);
36        osg::FloatArray* offsets = new osg::FloatArray(numParticles*2);
37       
38        osg::Vec3 frameDelta = velocity*(2.0f/60.0f);
39       
40        for(unsigned int i=0; i< numParticles; ++i)
41        {
42            (*vertices)[i*2].set(random(bb.xMin(), bb.xMax()), random(bb.yMin(),bb.yMax()), bb.zMax());
43            (*vertices)[i*2+1] = (*vertices)[i*2] + frameDelta;
44            (*offsets)[i*2] = random(0.0, 1.0);
45            (*offsets)[i*2+1] = (*offsets)[i*2];
46        }
47
48        geometry->setVertexArray(vertices);
49        geometry->setTexCoordArray(0, offsets);
50
51        // overall attributes
52        osg::Vec4Array* colours = new osg::Vec4Array(1);
53        (*colours)[0].set(0.5f,0.5f,0.5f,0.5f);
54        geometry->setColorArray(colours);
55        geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
56       
57        geometry->addPrimitiveSet(new osg::DrawArrays(GL_LINES, 0, numParticles));
58    }
59
60    // set up state.
61    {
62        // time taken to get from start to the end of cycle
63        float period = fabs((bb.zMax()-bb.zMin()) / velocity.z());
64
65        // distance between start point and end of cyclce
66        osg::Vec3 delta = velocity * period;
67
68        // set up uniforms
69        osg::Uniform* deltaUniform = new osg::Uniform("delta",delta);
70        osg::Uniform* inversePeriodUniform = new osg::Uniform("inversePeriod",1.0f/period);
71        osg::Uniform* startTime = new osg::Uniform("startTime",0.0f);
72
73        osg::Program* program = new osg::Program;
74        stateset->setAttribute(program);
75
76        // get shaders from source
77        program->addShader(osg::Shader::readShaderFile(osg::Shader::VERTEX, osgDB::findDataFile("rain.vert")));
78        program->addShader(osg::Shader::readShaderFile(osg::Shader::FRAGMENT, osgDB::findDataFile("rain.frag")));
79
80        stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
81        stateset->setMode(GL_BLEND, osg::StateAttribute::ON);
82       
83        stateset->addUniform(deltaUniform);
84        stateset->addUniform(inversePeriodUniform);
85        stateset->addUniform(startTime);
86    }
87   
88    geometry->setUseVertexBufferObjects(true);
89    geometry->setInitialBound(bb);
90
91
92    osg::Geode* geode = new osg::Geode;
93    geode->addDrawable(geometry);
94
95    return geode;
96}
97/*
98osg::Node* createSnowEffect(const osg::BoundingBox& bb, const osg::Vec3& velocity, unsigned int numParticles, bool useShaders)
99{
100    osg::Geometry* geometry = new osg::Geometry;
101
102    osg::StateSet* stateset = geometry->getOrCreateStateSet();
103
104    // set up geometry.
105    {
106   
107        // per vertex properties
108        osg::Vec3Array* vertices = new osg::Vec3Array(numParticles);
109        osg::FloatArray* offsets = new osg::FloatArray(numParticles);
110       
111        for(unsigned int i=0; i< numParticles; ++i)
112        {
113            (*vertices)[i].set(random(bb.xMin(), bb.xMax()), random(bb.yMin(),bb.yMax()), bb.zMax());
114            (*offsets)[i] = random(0.0, 1.0);
115        }
116
117        geometry->setVertexArray(vertices);
118        geometry->setTexCoordArray(0, offsets);
119
120        // overall attributes
121        osg::Vec4Array* colours = new osg::Vec4Array(1);
122        (*colours)[0].set(1.0f,1.0f,1.0f,1.0f);
123        geometry->setColorArray(colours);
124        geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
125       
126        geometry->addPrimitiveSet(new osg::DrawArrays(GL_POINTS, 0, numParticles));
127    }
128
129    // set up state.
130    {
131        // time taken to get from start to the end of cycle
132        float period = fabs((bb.zMax()-bb.zMin()) / velocity.z());
133
134        // distance between start point and end of cyclce
135        osg::Vec3 delta = velocity * period;
136
137        // set up uniforms
138        osg::Uniform* deltaUniform = new osg::Uniform("delta",delta);
139        osg::Uniform* inversePeriodUniform = new osg::Uniform("inversePeriod",1.0f/period);
140        osg::Uniform* startTime = new osg::Uniform("startTime",0.0f);
141
142        osg::Program* program = new osg::Program;
143        stateset->setAttribute(program);
144
145        // get shaders from source
146        program->addShader(osg::Shader::readShaderFile(osg::Shader::VERTEX, osgDB::findDataFile("snow.vert")));
147        program->addShader(osg::Shader::readShaderFile(osg::Shader::FRAGMENT, osgDB::findDataFile("snow.frag")));
148
149        stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
150       
151        stateset->addUniform(deltaUniform);
152        stateset->addUniform(inversePeriodUniform);
153        stateset->addUniform(startTime);
154    }
155   
156    geometry->setInitialBound(bb);
157
158
159    osg::Geode* geode = new osg::Geode;
160    geode->addDrawable(geometry);
161
162    return geode;
163}
164*/
165osg::Node* createModel(osg::Node* loadedModel, bool useShaders)
166{
167    osg::Group* group = new osg::Group;
168
169    osg::BoundingBox bb(0.0, 0.0, 0.0, 100.0, 100.0, 100.0);
170    osg::Vec3 velocity(0.0,0.0,-2.0);
171    unsigned int numParticles = 100000;
172   
173    if (loadedModel)
174    {
175        group->addChild(loadedModel);
176       
177        osg::BoundingSphere bs = loadedModel->getBound();
178        bs.radius() *= 0.75;
179        bb.init();
180        bb.expandBy(bs);
181    }
182
183    group->addChild(createRainEffect(bb, velocity, numParticles, useShaders));
184
185    return group;   
186}
187
188int main( int argc, char **argv )
189{
190
191    // use an ArgumentParser object to manage the program arguments.
192    osg::ArgumentParser arguments(&argc,argv);
193   
194    // set up the usage document, in case we need to print out how to use this program.
195    arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName());
196    arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" example provides an interactive viewer for visualising point clouds..");
197    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ...");
198    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
199    arguments.getApplicationUsage()->addCommandLineOption("--shader","Use GLSL shaders.");
200    arguments.getApplicationUsage()->addCommandLineOption("--fixed","Use fixed function pipeline.");
201   
202
203    // construct the viewer.
204    osgProducer::Viewer viewer(arguments);
205
206    // set up the value with sensible default event handlers.
207    viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS);
208
209    // get details on keyboard and mouse bindings used by the viewer.
210    viewer.getUsage(*arguments.getApplicationUsage());
211
212    bool shader = true;
213    while (arguments.read("--shader")) shader = true;
214    while (arguments.read("--fixed")) shader = false;
215
216    // if user request help write it out to cout.
217    if (arguments.read("-h") || arguments.read("--help"))
218    {
219        arguments.getApplicationUsage()->write(std::cout);
220        return 1;
221    }
222
223    // any option left unread are converted into errors to write out later.
224    arguments.reportRemainingOptionsAsUnrecognized();
225
226    // report any errors if they have occured when parsing the program aguments.
227    if (arguments.errors())
228    {
229        arguments.writeErrorMessages(std::cout);
230        return 1;
231    }
232   
233    osg::Timer timer;
234    osg::Timer_t start_tick = timer.tick();
235
236    // read the scene from the list of file specified commandline args.
237    osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFiles(arguments);
238   
239    loadedModel = createModel(loadedModel.get(), shader);
240
241    // if no model has been successfully loaded report failure.
242    if (!loadedModel)
243    {
244        std::cout << arguments.getApplicationName() <<": No data loaded" << std::endl;
245        return 1;
246    }
247
248    osg::Timer_t end_tick = timer.tick();
249
250    std::cout << "Time to load = "<<timer.delta_s(start_tick,end_tick)<<std::endl;
251
252    // optimize the scene graph, remove rendundent nodes and state etc.
253    osgUtil::Optimizer optimizer;
254    optimizer.optimize(loadedModel.get());
255
256    // set the scene to render
257    viewer.setSceneData(loadedModel.get());
258
259    // create the windows and run the threads.
260    viewer.realize();
261
262    while( !viewer.done() )
263    {
264        // wait for all cull and draw threads to complete.
265        viewer.sync();
266
267        // update the scene by traversing it with the the update visitor which will
268        // call all node update callbacks and animations.
269        viewer.update();
270         
271        // fire off the cull and draw traversals of the scene.
272        viewer.frame();
273       
274    }
275   
276    // wait for all cull and draw threads to complete before exit.
277    viewer.sync();
278
279    return 0;
280}
Note: See TracBrowser for help on using the browser.