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

Revision 3856, 9.8 kB (checked in by robert, 10 years ago)

Removed the default play() in the MPEG, QuickTime? and Xine plugins, moving
it into the osgmovie application, and into readNodeFile method where
--movie is now available for detecting movie code.

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