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

Revision 9442, 7.8 kB (checked in by robert, 6 years ago)

From Paul Martz, added --points option for forcing points rendering of polygonal models

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* OpenSceneGraph example, osgpoints.
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 <osgDB/ReadFile>
20#include <osgUtil/Optimizer>
21#include <osgViewer/Viewer>
22
23#include <osg/Point>
24#include <osg/BlendFunc>
25#include <osg/Texture2D>
26#include <osg/PointSprite>
27#include <osg/PolygonMode>
28
29#include <iostream>
30
31class KeyboardEventHandler : public osgGA::GUIEventHandler
32{
33public:
34   
35        KeyboardEventHandler(osg::StateSet* stateset):
36            _stateset(stateset)
37        {
38            _point = new osg::Point;
39            _point->setDistanceAttenuation(osg::Vec3(0.0,0.0000,0.05f));
40            _stateset->setAttribute(_point.get());
41        }
42   
43        virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&)
44        {
45            switch(ea.getEventType())
46            {
47                case(osgGA::GUIEventAdapter::KEYDOWN):
48                {
49                    if (ea.getKey()=='+' || ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Add)
50                    {
51                       changePointSize(1.0f);
52                       return true;
53                    }
54                    else if (ea.getKey()=='-' || ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Subtract)
55                    {
56                       changePointSize(-1.0f);
57                       return true;
58                    }
59                    else if (ea.getKey()=='<')
60                    {
61                       changePointAttenuation(1.1f);
62                       return true;
63                    }
64                    else if (ea.getKey()=='>')
65                    {
66                       changePointAttenuation(1.0f/1.1f);
67                       return true;
68                    }
69                    break;
70                }
71                default:
72                    break;
73            }
74            return false;
75        }
76       
77       
78        float getPointSize() const
79        {
80            return _point->getSize();
81        }
82       
83        void setPointSize(float psize)
84        {
85            if (psize>0.0)
86            {
87                _point->setSize(psize);
88            }
89            std::cout<<"Point size "<<psize<<std::endl;
90        }
91
92        void changePointSize(float delta)
93        {
94            setPointSize(getPointSize()+delta);
95        }
96
97        void changePointAttenuation(float scale)
98        {
99            _point->setDistanceAttenuation(_point->getDistanceAttenuation()*scale);
100        }
101       
102        osg::ref_ptr<osg::StateSet> _stateset;
103        osg::ref_ptr<osg::Point>    _point;
104       
105};
106
107int main( int argc, char **argv )
108{
109
110    // use an ArgumentParser object to manage the program arguments.
111    osg::ArgumentParser arguments(&argc,argv);
112   
113    // set up the usage document, in case we need to print out how to use this program.
114    arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName());
115    arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" example provides an interactive viewer for visualising point clouds..");
116    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ...");
117    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
118    arguments.getApplicationUsage()->addCommandLineOption("--sprites","Point sprites.");
119    arguments.getApplicationUsage()->addCommandLineOption("--points","Sets the polygon mode to GL_POINT for front and back faces.");
120
121
122    // construct the viewer.
123    osgViewer::Viewer viewer;
124
125    bool shader = false;
126    while (arguments.read("--shader")) shader = true;
127
128    // if user request help write it out to cout.
129    if (arguments.read("-h") || arguments.read("--help"))
130    {
131        arguments.getApplicationUsage()->write(std::cout);
132        return 1;
133    }
134   
135    bool usePointSprites = false;
136    while (arguments.read("--sprites")) { usePointSprites = true; };
137
138    bool forcePointMode = false;
139    while (arguments.read("--points")) { forcePointMode = true; };
140
141    if (arguments.argc()<=1)
142    {
143        arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION);
144        return 1;
145    }
146
147    // read the scene from the list of file specified commandline args.
148    osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFiles(arguments);
149
150    // if no model has been successfully loaded report failure.
151    if (!loadedModel)
152    {
153        std::cout << arguments.getApplicationName() <<": No data loaded" << std::endl;
154        return 1;
155    }
156
157    // optimize the scene graph, remove redundant nodes and state etc.
158    osgUtil::Optimizer optimizer;
159    optimizer.optimize(loadedModel.get());
160
161
162    // set the scene to render
163    viewer.setSceneData(loadedModel.get());
164   
165
166    osg::StateSet* stateset = loadedModel->getOrCreateStateSet();
167    if (usePointSprites)   
168    {
169        /// Setup cool blending
170        osg::BlendFunc *fn = new osg::BlendFunc();
171        stateset->setAttributeAndModes(fn, osg::StateAttribute::ON);
172
173        /// Setup the point sprites
174        osg::PointSprite *sprite = new osg::PointSprite();
175        stateset->setTextureAttributeAndModes(0, sprite, osg::StateAttribute::ON);
176
177        /// The texture for the sprites
178        osg::Texture2D *tex = new osg::Texture2D();
179        tex->setImage(osgDB::readImageFile("Images/particle.rgb"));
180        stateset->setTextureAttributeAndModes(0, tex, osg::StateAttribute::ON);
181    }
182
183    if( forcePointMode )
184    {
185        /// Set polygon mode to GL_POINT
186        osg::PolygonMode *pm = new osg::PolygonMode(
187            osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::POINT );
188        stateset->setAttributeAndModes( pm, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
189    }
190   
191
192    // register the handler for modifying the point size
193    viewer.addEventHandler(new KeyboardEventHandler(viewer.getCamera()->getOrCreateStateSet()));
194
195
196    if (shader)
197    {
198        osg::StateSet* stateset = loadedModel->getOrCreateStateSet();
199   
200        ///////////////////////////////////////////////////////////////////
201        // vertex shader using just Vec4 coefficients
202        char vertexShaderSource[] =
203            "void main(void) \n"
204            "{ \n"
205            "\n"
206            "    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
207            "}\n";
208
209
210
211        osg::Program* program = new osg::Program;
212        stateset->setAttribute(program);
213
214        osg::Shader* vertex_shader = new osg::Shader(osg::Shader::VERTEX, vertexShaderSource);
215        program->addShader(vertex_shader);
216
217#if 0
218        //////////////////////////////////////////////////////////////////
219        // fragment shader
220        //
221        char fragmentShaderSource[] =
222            "void main(void) \n"
223            "{ \n"
224            "    gl_FragColor = gl_Color; \n"
225            "}\n";
226
227        osg::Shader* fragment_shader = new osg::Shader(osg::Shader::FRAGMENT, fragmentShaderSource);
228        program->addShader(fragment_shader);
229#endif
230    }
231
232    return viewer.run();
233}
Note: See TracBrowser for help on using the browser.