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

Revision 3819, 9.6 kB (checked in by robert, 10 years ago)

Added osg::BufferObject? and a made a number associated to accomodate this
new class. osg::BufferObject? wraps up OpenGL pixel and array buffer objects.
Currently implementation is work in progress.

  • 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 = osg::createTexturedQuadGeometry(pos,
187                                           osg::Vec3(width,0.0f,0.0f),
188                                           osg::Vec3(0.0f,0.0f,height),
189                                           image->s(),image->t());
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 = osg::createTexturedQuadGeometry(pos,
200                                           osg::Vec3(width,0.0f,0.0f),
201                                           osg::Vec3(0.0f,0.0f,height),
202                                           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            geode->addDrawable(createTexturedQuadGeometry(pos,image->s(),image->t(),image));
254            geode->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
255        }
256
257    }
258
259    // pass the model to the MovieEventHandler so it can pick out ImageStream's to manipulate.
260    meh->set(geode);
261
262    // report any errors if they have occured when parsing the program aguments.
263    if (arguments.errors())
264    {
265        arguments.writeErrorMessages(std::cout);
266        return 1;
267    }
268   
269    if (arguments.argc()<=1)
270    {
271        arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION);
272        return 1;
273    }
274
275
276    // any option left unread are converted into errors to write out later.
277    arguments.reportRemainingOptionsAsUnrecognized();
278
279    // report any errors if they have occured when parsing the program aguments.
280    if (arguments.errors())
281    {
282        arguments.writeErrorMessages(std::cout);
283    }
284
285    // set up a post swap callback to flush deleted GL objects and compile new GL objects           
286    for(unsigned int cameraNum=0;cameraNum<viewer.getNumberOfCameras();++cameraNum)
287    {
288        Producer::Camera* camera=viewer.getCamera(cameraNum);
289        camera->addPostSwapCallback(new PostSwapFinishCallback());
290    }
291
292    // set the scene to render
293    viewer.setSceneData(geode);
294
295    // create the windows and run the threads.
296    viewer.realize();
297
298    while( !viewer.done() )
299    {
300        // wait for all cull and draw threads to complete.
301        viewer.sync();
302       
303        // update the scene by traversing it with the the update visitor which will
304        // call all node update callbacks and animations.
305        viewer.update();
306         
307        // fire off the cull and draw traversals of the scene.
308        viewer.frame();
309       
310    }
311   
312    // wait for all cull and draw threads to complete before exit.
313    viewer.sync();
314
315    return 0;
316
317
318}
Note: See TracBrowser for help on using the browser.