root/OpenSceneGraph/trunk/examples/osgpoints/osgpoints.cpp @ 4368

Revision 4368, 7.0 kB (checked in by robert, 9 years ago)

Added support for point sprites

  • 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 <osgUtil/Optimizer>
14#include <osgProducer/Viewer>
15
16#include <osg/Point>
17#include <osg/BlendFunc>
18#include <osg/Texture2D>
19#include <osg/PointSprite>
20
21class KeyboardEventHandler : public osgGA::GUIEventHandler
22{
23public:
24   
25        KeyboardEventHandler(osg::StateSet* stateset):
26            _stateset(stateset)
27        {
28            _point = new osg::Point;
29            _point->setDistanceAttenuation(osg::Vec3(0.0,0.0000,0.05f));
30            _stateset->setAttribute(_point.get());
31        }
32   
33        virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&)
34        {
35            switch(ea.getEventType())
36            {
37                case(osgGA::GUIEventAdapter::KEYDOWN):
38                {
39                    if (ea.getKey()=='+' || ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Add)
40                    {
41                       changePointSize(1.0f);
42                       return true;
43                    }
44                    else if (ea.getKey()=='-' || ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Subtract)
45                    {
46                       changePointSize(-1.0f);
47                       return true;
48                    }
49                    else if (ea.getKey()=='<')
50                    {
51                       changePointAttenuation(1.1f);
52                       return true;
53                    }
54                    else if (ea.getKey()=='>')
55                    {
56                       changePointAttenuation(1.0f/1.1f);
57                       return true;
58                    }
59                    break;
60                }
61                default:
62                    break;
63            }
64            return false;
65        }
66
67        virtual void accept(osgGA::GUIEventHandlerVisitor& v)
68        {
69            v.visit(*this);
70        }
71       
72       
73        float getPointSize() const
74        {
75            return _point->getSize();
76        }
77       
78        void setPointSize(float psize)
79        {
80            if (psize>0.0)
81            {
82                _point->setSize(psize);
83            }
84            std::cout<<"Point size "<<psize<<std::endl;
85        }
86
87        void changePointSize(float delta)
88        {
89            setPointSize(getPointSize()+delta);
90        }
91
92        void changePointAttenuation(float scale)
93        {
94            _point->setDistanceAttenuation(_point->getDistanceAttenuation()*scale);
95        }
96       
97        osg::ref_ptr<osg::StateSet> _stateset;
98        osg::ref_ptr<osg::Point>    _point;
99       
100};
101
102int main( int argc, char **argv )
103{
104
105    // use an ArgumentParser object to manage the program arguments.
106    osg::ArgumentParser arguments(&argc,argv);
107   
108    // set up the usage document, in case we need to print out how to use this program.
109    arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName());
110    arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the standard OpenSceneGraph example which loads and visualises 3d models.");
111    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ...");
112    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
113    arguments.getApplicationUsage()->addCommandLineOption("--sprites","Point sprites.");
114   
115
116    // construct the viewer.
117    osgProducer::Viewer viewer(arguments);
118
119    // set up the value with sensible default event handlers.
120    viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS);
121
122    // get details on keyboard and mouse bindings used by the viewer.
123    viewer.getUsage(*arguments.getApplicationUsage());
124
125    // if user request help write it out to cout.
126    if (arguments.read("-h") || arguments.read("--help"))
127    {
128        arguments.getApplicationUsage()->write(std::cout);
129        return 1;
130    }
131   
132    bool usePointSprites = false;
133    while (arguments.read("--sprites")) { usePointSprites = true; };
134
135    // any option left unread are converted into errors to write out later.
136    arguments.reportRemainingOptionsAsUnrecognized();
137
138    // report any errors if they have occured when parsing the program aguments.
139    if (arguments.errors())
140    {
141        arguments.writeErrorMessages(std::cout);
142        return 1;
143    }
144   
145    if (arguments.argc()<=1)
146    {
147        arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION);
148        return 1;
149    }
150
151    osg::Timer timer;
152    osg::Timer_t start_tick = timer.tick();
153
154    // read the scene from the list of file specified commandline args.
155    osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFiles(arguments);
156
157    // if no model has been successfully loaded report failure.
158    if (!loadedModel)
159    {
160        std::cout << arguments.getApplicationName() <<": No data loaded" << std::endl;
161        return 1;
162    }
163
164    osg::Timer_t end_tick = timer.tick();
165
166    std::cout << "Time to load = "<<timer.delta_s(start_tick,end_tick)<<std::endl;
167
168    // optimize the scene graph, remove rendundent nodes and state etc.
169    osgUtil::Optimizer optimizer;
170    optimizer.optimize(loadedModel.get());
171
172
173    // set the scene to render
174    viewer.setSceneData(loadedModel.get());
175   
176
177    if (usePointSprites)   
178    {
179        osg::StateSet* stateset = loadedModel->getOrCreateStateSet();
180
181        /// Setup cool blending
182        osg::BlendFunc *fn = new osg::BlendFunc();
183        stateset->setAttributeAndModes(fn, osg::StateAttribute::ON);
184
185        /// Setup the point sprites
186        osg::PointSprite *sprite = new osg::PointSprite();
187        stateset->setTextureAttributeAndModes(0, sprite, osg::StateAttribute::ON);
188
189        /// The texture for the sprites
190        osg::Texture2D *tex = new osg::Texture2D();
191        tex->setImage(osgDB::readImageFile("Images/particle.rgb"));
192        stateset->setTextureAttributeAndModes(0, tex, osg::StateAttribute::ON);
193    }
194   
195
196    // register the handler for modifying the point size
197    viewer.getEventHandlerList().push_front(new KeyboardEventHandler(viewer.getGlobalStateSet()));
198
199    // create the windows and run the threads.
200    viewer.realize();
201
202    while( !viewer.done() )
203    {
204        // wait for all cull and draw threads to complete.
205        viewer.sync();
206
207        // update the scene by traversing it with the the update visitor which will
208        // call all node update callbacks and animations.
209        viewer.update();
210         
211        // fire off the cull and draw traversals of the scene.
212        viewer.frame();
213       
214    }
215   
216    // wait for all cull and draw threads to complete before exit.
217    viewer.sync();
218
219    return 0;
220}
Note: See TracBrowser for help on using the browser.