root/OpenSceneGraph/trunk/examples/osgmovie/osgmovie.cpp @ 2810

Revision 2810, 8.3 kB (checked in by robert, 11 years ago)

Added some basic event handler.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1// -*-c++-*-
2
3#include <osgProducer/Viewer>
4
5#include <osgDB/ReadFile>
6
7#include <osg/Geode>
8#include <osg/Geometry>
9#include <osg/StateSet>
10#include <osg/Material>
11#include <osg/Texture2D>
12#include <osg/TextureRectangle>
13#include <osg/TexMat>
14#include <osg/CullFace>
15#include <osg/ImageStream>
16
17#include <osgGA/TrackballManipulator>
18
19class MovieEventHandler : public osgGA::GUIEventHandler
20{
21public:
22
23    MovieEventHandler() {}
24   
25    void set(osg::Node* node);
26
27    virtual void accept(osgGA::GUIEventHandlerVisitor& v) { v.visit(*this); }
28
29    virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&);
30   
31    virtual void getUsage(osg::ApplicationUsage& usage) const;
32
33    typedef std::vector< osg::ref_ptr<osg::ImageStream> > ImageStreamList;
34
35protected:
36
37    virtual ~MovieEventHandler() {}
38
39    class FindImageStreamsVisitor : public osg::NodeVisitor
40    {
41    public:
42        FindImageStreamsVisitor(ImageStreamList& imageStreamList):
43            _imageStreamList(imageStreamList) {}
44           
45        virtual void apply(osg::Geode& geode)
46        {
47            apply(geode.getStateSet());
48
49            for(unsigned int i=0;i<geode.getNumDrawables();++i)
50            {
51                apply(geode.getDrawable(i)->getStateSet());
52            }
53       
54            traverse(geode);
55        }
56
57        virtual void apply(osg::Node& node)
58        {
59            apply(node.getStateSet());
60            traverse(node);
61        }
62       
63        inline void apply(osg::StateSet* stateset)
64        {
65            if (!stateset) return;
66           
67            osg::StateAttribute* attr = stateset->getTextureAttribute(0,osg::StateAttribute::TEXTURE);
68            if (attr)
69            {
70                osg::Texture2D* texture2D = dynamic_cast<osg::Texture2D*>(attr);
71                if (texture2D) apply(dynamic_cast<osg::ImageStream*>(texture2D->getImage()));
72
73                osg::TextureRectangle* textureRec = dynamic_cast<osg::TextureRectangle*>(attr);
74                if (textureRec) apply(dynamic_cast<osg::ImageStream*>(textureRec->getImage()));
75            }
76        }
77       
78        inline void apply(osg::ImageStream* imagestream)
79        {
80            if (imagestream) _imageStreamList.push_back(imagestream);
81        }
82       
83        ImageStreamList& _imageStreamList;
84    };
85
86
87    ImageStreamList _imageStreamList;
88   
89};
90
91
92
93void MovieEventHandler::set(osg::Node* node)
94{
95    _imageStreamList.clear();
96    if (node)
97    {
98        FindImageStreamsVisitor fisv(_imageStreamList);
99        node->accept(fisv);
100    }
101}
102
103
104bool MovieEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&)
105{
106    switch(ea.getEventType())
107    {
108        case(osgGA::GUIEventAdapter::KEYDOWN):
109        {
110            if (ea.getKey()=='s')
111            {
112                for(ImageStreamList::iterator itr=_imageStreamList.begin();
113                    itr!=_imageStreamList.end();
114                    ++itr)
115                {
116                    std::cout<<"Play"<<std::endl;
117                     (*itr)->play();
118                }
119                return true;
120            }
121            else if (ea.getKey()=='p')
122            {
123                for(ImageStreamList::iterator itr=_imageStreamList.begin();
124                    itr!=_imageStreamList.end();
125                    ++itr)
126                {
127                    std::cout<<"Pause"<<std::endl;
128                    (*itr)->pause();
129                }
130                return true;
131            }
132            else if (ea.getKey()=='r')
133            {
134                return true;
135            }
136            else if (ea.getKey()=='l')
137            {
138                return true;
139            }
140            return false;
141        }
142
143        default:
144            return false;
145    }
146}
147
148void MovieEventHandler::getUsage(osg::ApplicationUsage& usage) const
149{
150    usage.addKeyboardMouseBinding("p","Pause movie");
151    usage.addKeyboardMouseBinding("s","Play movie");
152    usage.addKeyboardMouseBinding("r","Start movie");
153    usage.addKeyboardMouseBinding("l","Toggle looping of movie");
154}
155
156
157osg::Geometry* createTexturedQuadGeometry(const osg::Vec3& pos,float width,float height, osg::Image* image)
158{
159    bool useTextureRectangle = true;
160    if (useTextureRectangle)
161    {
162        osg::Geometry* pictureQuad = osg::createTexturedQuadGeometry(pos,
163                                           osg::Vec3(width,0.0f,0.0f),
164                                           osg::Vec3(0.0f,0.0f,height),
165                                           image->s(),image->t());
166                                       
167        pictureQuad->getOrCreateStateSet()->setTextureAttributeAndModes(0,
168                    new osg::TextureRectangle(image),
169                    osg::StateAttribute::ON);
170                   
171        return pictureQuad;
172    }
173    else
174    {
175        osg::Geometry* pictureQuad = osg::createTexturedQuadGeometry(pos,
176                                           osg::Vec3(width,0.0f,0.0f),
177                                           osg::Vec3(0.0f,0.0f,height),
178                                           1.0f,1.0f);
179                                       
180        pictureQuad->getOrCreateStateSet()->setTextureAttributeAndModes(0,
181                    new osg::Texture2D(image),
182                    osg::StateAttribute::ON);
183
184        return pictureQuad;
185    }
186}
187
188int main(int argc, char** argv)
189{
190    // use an ArgumentParser object to manage the program arguments.
191    osg::ArgumentParser arguments(&argc,argv);
192   
193    // set up the usage document, in case we need to print out how to use this program.
194    arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName());
195    arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the standard OpenSceneGraph example which loads and visualises 3d models.");
196    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ...");
197    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
198   
199
200    // construct the viewer.
201    osgProducer::Viewer viewer(arguments);
202
203    // set up the value with sensible default event handlers.
204    viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS);
205
206    // register the handler to add keyboard and mosue handling.
207    MovieEventHandler* meh = new MovieEventHandler();
208    viewer.getEventHandlerList().push_front(meh);
209
210
211    // get details on keyboard and mouse bindings used by the viewer.
212    viewer.getUsage(*arguments.getApplicationUsage());
213
214    // if user request help write it out to cout.
215    if (arguments.read("-h") || arguments.read("--help"))
216    {
217        arguments.getApplicationUsage()->write(std::cout);
218        return 1;
219    }
220
221    osg::Geode* geode = new osg::Geode;
222    osg::Vec3 pos(0.0f,0.0f,0.0f);
223   
224    for(int i=1;i<arguments.argc();++i)
225    {
226        if (arguments.isString(i))
227        {
228            osg::Image* image = osgDB::readImageFile(arguments[i]);
229            geode->addDrawable(createTexturedQuadGeometry(pos,image->s(),image->t(),image));
230        }
231
232    }
233
234    // pass the model to the MovieEventHandler so it can pick out ImageStream's to manipulate.
235    meh->set(geode);
236
237    // report any errors if they have occured when parsing the program aguments.
238    if (arguments.errors())
239    {
240        arguments.writeErrorMessages(std::cout);
241        return 1;
242    }
243   
244    if (arguments.argc()<=1)
245    {
246        arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION);
247        return 1;
248    }
249
250
251    // any option left unread are converted into errors to write out later.
252    arguments.reportRemainingOptionsAsUnrecognized();
253
254    // report any errors if they have occured when parsing the program aguments.
255    if (arguments.errors())
256    {
257        arguments.writeErrorMessages(std::cout);
258    }
259
260    // set the scene to render
261    viewer.setSceneData(geode);
262
263    // create the windows and run the threads.
264    viewer.realize();
265
266    while( !viewer.done() )
267    {
268        // wait for all cull and draw threads to complete.
269        viewer.sync();
270       
271        // update the scene by traversing it with the the update visitor which will
272        // call all node update callbacks and animations.
273        viewer.update();
274         
275        // fire off the cull and draw traversals of the scene.
276        viewer.frame();
277       
278    }
279   
280    // wait for all cull and draw threads to complete before exit.
281    viewer.sync();
282
283    return 0;
284
285
286}
Note: See TracBrowser for help on using the browser.