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

Revision 6935, 24.9 kB (checked in by robert, 7 years ago)

Added screen number, and flip support into dome correction codes.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1// -*-c++-*-
2
3#include <osgViewer/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/TextureCubeMap>
14#include <osg/TexMat>
15#include <osg/CullFace>
16#include <osg/ImageStream>
17#include <osg/io_utils>
18
19#include <osgGA/TrackballManipulator>
20#include <osgGA/EventVisitor>
21
22#include <iostream>
23
24osg::ImageStream* s_imageStream = 0;
25class MovieEventHandler : public osgGA::GUIEventHandler
26{
27public:
28
29    MovieEventHandler():_trackMouse(false) {}
30   
31    void setMouseTracking(bool track) { _trackMouse = track; }
32    bool getMouseTracking() const { return _trackMouse; }
33   
34    void set(osg::Node* node);
35
36    virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa, osg::Object*, osg::NodeVisitor* nv);
37   
38    virtual void getUsage(osg::ApplicationUsage& usage) const;
39
40    typedef std::vector< osg::ref_ptr<osg::ImageStream> > ImageStreamList;
41
42protected:
43
44    virtual ~MovieEventHandler() {}
45
46    class FindImageStreamsVisitor : public osg::NodeVisitor
47    {
48    public:
49        FindImageStreamsVisitor(ImageStreamList& imageStreamList):
50            _imageStreamList(imageStreamList) {}
51           
52        virtual void apply(osg::Geode& geode)
53        {
54            apply(geode.getStateSet());
55
56            for(unsigned int i=0;i<geode.getNumDrawables();++i)
57            {
58                apply(geode.getDrawable(i)->getStateSet());
59            }
60       
61            traverse(geode);
62        }
63
64        virtual void apply(osg::Node& node)
65        {
66            apply(node.getStateSet());
67            traverse(node);
68        }
69       
70        inline void apply(osg::StateSet* stateset)
71        {
72            if (!stateset) return;
73           
74            osg::StateAttribute* attr = stateset->getTextureAttribute(0,osg::StateAttribute::TEXTURE);
75            if (attr)
76            {
77                osg::Texture2D* texture2D = dynamic_cast<osg::Texture2D*>(attr);
78                if (texture2D) apply(dynamic_cast<osg::ImageStream*>(texture2D->getImage()));
79
80                osg::TextureRectangle* textureRec = dynamic_cast<osg::TextureRectangle*>(attr);
81                if (textureRec) apply(dynamic_cast<osg::ImageStream*>(textureRec->getImage()));
82            }
83        }
84       
85        inline void apply(osg::ImageStream* imagestream)
86        {
87            if (imagestream)
88            {
89                _imageStreamList.push_back(imagestream);
90                s_imageStream = imagestream;
91            }
92        }
93       
94        ImageStreamList& _imageStreamList;
95    };
96
97
98    bool            _trackMouse;
99    ImageStreamList _imageStreamList;
100   
101};
102
103
104
105void MovieEventHandler::set(osg::Node* node)
106{
107    _imageStreamList.clear();
108    if (node)
109    {
110        FindImageStreamsVisitor fisv(_imageStreamList);
111        node->accept(fisv);
112    }
113}
114
115
116bool MovieEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa, osg::Object*, osg::NodeVisitor* nv)
117{
118    switch(ea.getEventType())
119    {
120        case(osgGA::GUIEventAdapter::MOVE):
121        case(osgGA::GUIEventAdapter::PUSH):
122        case(osgGA::GUIEventAdapter::RELEASE):
123        {
124            if (_trackMouse)
125            {
126                osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);
127                osgUtil::LineSegmentIntersector::Intersections intersections;
128                if (view && view->computeIntersections(ea.getX(), ea.getY(), nv->getNodePath(), intersections))
129                {
130
131                    // use the nearest intersection                 
132                    const osgUtil::LineSegmentIntersector::Intersection& intersection = *(intersections.begin());
133                    osg::Drawable* drawable = intersection.drawable.get();
134                    osg::Geometry* geometry = drawable ? drawable->asGeometry() : 0;
135                    osg::Vec3Array* vertices = geometry ? dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray()) : 0;
136                    if (vertices)
137                    {
138                        // get the vertex indices.
139                        const osgUtil::LineSegmentIntersector::Intersection::IndexList& indices = intersection.indexList;
140                        const osgUtil::LineSegmentIntersector::Intersection::RatioList& ratios = intersection.ratioList;
141
142                        if (indices.size()==3 && ratios.size()==3)
143                        {
144                            unsigned int i1 = indices[0];
145                            unsigned int i2 = indices[1];
146                            unsigned int i3 = indices[2];
147
148                            float r1 = ratios[0];
149                            float r2 = ratios[1];
150                            float r3 = ratios[2];
151
152                            osg::Array* texcoords = (geometry->getNumTexCoordArrays()>0) ? geometry->getTexCoordArray(0) : 0;
153                            osg::Vec2Array* texcoords_Vec2Array = dynamic_cast<osg::Vec2Array*>(texcoords);
154                            if (texcoords_Vec2Array)
155                            {
156                                // we have tex coord array so now we can compute the final tex coord at the point of intersection.                               
157                                osg::Vec2 tc1 = (*texcoords_Vec2Array)[i1];
158                                osg::Vec2 tc2 = (*texcoords_Vec2Array)[i2];
159                                osg::Vec2 tc3 = (*texcoords_Vec2Array)[i3];
160                                osg::Vec2 tc = tc1*r1 + tc2*r2 + tc3*r3;
161
162                                osg::notify(osg::NOTICE)<<"We hit tex coords "<<tc<<std::endl;
163
164                            }
165                        }
166                        else
167                        {
168                            osg::notify(osg::NOTICE)<<"Intersection has insufficient indices to work with";
169                        }
170
171                    }
172                }
173                else
174                {
175                    osg::notify(osg::NOTICE)<<"No intersection"<<std::endl;
176                }
177            }
178            break;
179        }
180        case(osgGA::GUIEventAdapter::KEYDOWN):
181        {
182            if (ea.getKey()=='s')
183            {
184                for(ImageStreamList::iterator itr=_imageStreamList.begin();
185                    itr!=_imageStreamList.end();
186                    ++itr)
187                {
188                    std::cout<<"Play"<<std::endl;
189                     (*itr)->play();
190                }
191                return true;
192            }
193            else if (ea.getKey()=='p')
194            {
195                for(ImageStreamList::iterator itr=_imageStreamList.begin();
196                    itr!=_imageStreamList.end();
197                    ++itr)
198                {
199                    std::cout<<"Pause"<<std::endl;
200                    (*itr)->pause();
201                }
202                return true;
203            }
204            else if (ea.getKey()=='r')
205            {
206                for(ImageStreamList::iterator itr=_imageStreamList.begin();
207                    itr!=_imageStreamList.end();
208                    ++itr)
209                {
210                    std::cout<<"Restart"<<std::endl;
211                    (*itr)->rewind();
212                    (*itr)->play();
213                }
214                return true;
215            }
216            else if (ea.getKey()=='l')
217            {
218                for(ImageStreamList::iterator itr=_imageStreamList.begin();
219                    itr!=_imageStreamList.end();
220                    ++itr)
221                {
222                    if ( (*itr)->getLoopingMode() == osg::ImageStream::LOOPING)
223                    {
224                        std::cout<<"Toggle Looping Off"<<std::endl;
225                        (*itr)->setLoopingMode( osg::ImageStream::NO_LOOPING );
226                    }
227                    else
228                    {
229                        std::cout<<"Toggle Looping On"<<std::endl;
230                        (*itr)->setLoopingMode( osg::ImageStream::LOOPING );
231                    }
232                }
233                return true;
234            }
235            return false;
236        }
237
238        default:
239            return false;
240    }
241    return false;
242}
243
244void MovieEventHandler::getUsage(osg::ApplicationUsage& usage) const
245{
246    usage.addKeyboardMouseBinding("p","Pause movie");
247    usage.addKeyboardMouseBinding("s","Play movie");
248    usage.addKeyboardMouseBinding("r","Restart movie");
249    usage.addKeyboardMouseBinding("l","Toggle looping of movie");
250}
251
252
253osg::Geometry* myCreateTexturedQuadGeometry(const osg::Vec3& pos,float width,float height, osg::Image* image, bool useTextureRectangle)
254{
255    if (useTextureRectangle)
256    {
257        osg::Geometry* pictureQuad = osg::createTexturedQuadGeometry(pos,
258                                           osg::Vec3(width,0.0f,0.0f),
259                                           osg::Vec3(0.0f,0.0f,height),
260                                           0.0f,image->t(), image->s(),0.0f);
261
262        pictureQuad->getOrCreateStateSet()->setTextureAttributeAndModes(0,
263                    new osg::TextureRectangle(image),
264                    osg::StateAttribute::ON);
265                   
266        return pictureQuad;
267    }
268    else
269    {
270        osg::Geometry* pictureQuad = osg::createTexturedQuadGeometry(pos,
271                                           osg::Vec3(width,0.0f,0.0f),
272                                           osg::Vec3(0.0f,0.0f,height),
273                                           0.0f,1.0f, 1.0f,0.0f);
274                                   
275        osg::Texture2D* texture = new osg::Texture2D(image);
276        texture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR); 
277                                       
278        pictureQuad->getOrCreateStateSet()->setTextureAttributeAndModes(0,
279                    texture,
280                    osg::StateAttribute::ON);
281
282        return pictureQuad;
283    }
284}
285
286osg::Geometry* createDomeDistortionMesh(const osg::Vec3& origin, const osg::Vec3& widthVector, const osg::Vec3& heightVector,
287                                        osg::ArgumentParser& arguments)
288{
289    double sphere_radius = 1.0;
290    if (arguments.read("--radius", sphere_radius)) {}
291
292    double collar_radius = 0.45;
293    if (arguments.read("--collar", collar_radius)) {}
294
295    double rotationDegrees = 180.0;
296    if (arguments.read("--rotation", rotationDegrees)) {}
297
298    osg::Vec3d center(0.0,0.0,0.0);
299    osg::Vec3d eye(0.0,0.0,0.0);
300   
301    double distance = sqrt(sphere_radius*sphere_radius - collar_radius*collar_radius);
302    if (arguments.read("--distance", distance)) {}
303   
304    bool centerProjection = false;
305
306    osg::Vec3d projector = eye - osg::Vec3d(0.0,0.0, distance);
307   
308   
309    osg::notify(osg::NOTICE)<<"Projector position = "<<projector<<std::endl;
310    osg::notify(osg::NOTICE)<<"distance = "<<distance<<std::endl;
311
312
313    // create the quad to visualize.
314    osg::Geometry* geometry = new osg::Geometry();
315
316    geometry->setSupportsDisplayList(false);
317
318    osg::Vec3 xAxis(widthVector);
319    float width = widthVector.length();
320    xAxis /= width;
321
322    osg::Vec3 yAxis(heightVector);
323    float height = heightVector.length();
324    yAxis /= height;
325   
326    int noSteps = 160;
327
328    osg::Vec3Array* vertices = new osg::Vec3Array;
329    osg::Vec2Array* texcoords = new osg::Vec2Array;
330    osg::Vec4Array* colors = new osg::Vec4Array;
331
332    osg::Vec3 bottom = origin;
333    osg::Vec3 dx = xAxis*(width/((float)(noSteps-2)));
334    osg::Vec3 dy = yAxis*(height/((float)(noSteps-1)));
335   
336    osg::Vec3 top = origin + yAxis*height;
337
338    osg::Vec3d screenCenter = origin + widthVector*0.5f + heightVector*0.5f;
339    float screenRadius = heightVector.length() * 0.5f;
340
341    double rotation = osg::DegreesToRadians(rotationDegrees);
342
343    osg::Vec3 cursor = bottom;
344    int i,j;
345   
346    int midSteps = noSteps/2;
347   
348    bool flip = false;
349    if (arguments.read("--flip")) { flip = true; }
350   
351    for(i=0;i<midSteps;++i)
352    {
353        osg::Vec3 cursor = bottom+dy*(float)i;
354        for(j=0;j<midSteps;++j)
355        {
356            osg::Vec2 delta(cursor.x() - screenCenter.x(), cursor.y() - screenCenter.y());
357            double theta = atan2(delta.x(), -delta.y());
358            theta += 2*osg::PI;
359
360            double phi = osg::PI_2 * delta.length() / screenRadius;
361            if (phi > osg::PI_2) phi = osg::PI_2;
362
363            double f = distance * sin(phi);
364            double e = distance * cos(phi) + sqrt( sphere_radius*sphere_radius - f*f);
365            double l = e * cos(phi);
366            double h = e * sin(phi);
367            double gamma = atan2(h, l-distance);
368
369            osg::Vec2 texcoord(theta/(2.0*osg::PI), 1.0-gamma/osg::PI);
370
371            // osg::notify(osg::NOTICE)<<"cursor = "<<cursor<< " theta = "<<theta<< "phi="<<phi<<" gamma = "<<gamma<<" texcoord="<<texcoord<<std::endl;
372
373            if (flip)
374                vertices->push_back(osg::Vec3(cursor.x(), top.y()-(cursor.y()-origin.y()),cursor.z()));
375            else
376                vertices->push_back(cursor);
377           
378            colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
379            texcoords->push_back(texcoord);
380
381            if (j+1<midSteps) cursor += dx;
382        }
383
384        for(;j<noSteps;++j)
385        {
386            osg::Vec2 delta(cursor.x() - screenCenter.x(), cursor.y() - screenCenter.y());
387            double theta = atan2(delta.x(), -delta.y());
388            double phi = osg::PI_2 * delta.length() / screenRadius;
389            if (phi > osg::PI_2) phi = osg::PI_2;
390
391            double f = distance * sin(phi);
392            double e = distance * cos(phi) + sqrt( sphere_radius*sphere_radius - f*f);
393            double l = e * cos(phi);
394            double h = e * sin(phi);
395            double gamma = atan2(h, l-distance);
396
397            osg::Vec2 texcoord(theta/(2.0*osg::PI), 1.0-gamma/osg::PI);
398
399            // osg::notify(osg::NOTICE)<<"cursor = "<<cursor<< " theta = "<<theta<< "phi="<<phi<<" gamma = "<<gamma<<" texcoord="<<texcoord<<std::endl;
400
401            if (flip)
402                vertices->push_back(osg::Vec3(cursor.x(), top.y()-(cursor.y()-origin.y()),cursor.z()));
403            else
404                vertices->push_back(cursor);
405
406            colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
407            texcoords->push_back(texcoord);
408
409            cursor += dx;
410        }
411        // osg::notify(osg::NOTICE)<<std::endl;
412    }
413   
414    for(;i<noSteps;++i)
415    {
416        osg::Vec3 cursor = bottom+dy*(float)i;
417        for(j=0;j<noSteps;++j)
418        {
419            osg::Vec2 delta(cursor.x() - screenCenter.x(), cursor.y() - screenCenter.y());
420            double theta = atan2(delta.x(), -delta.y());
421            if (theta<0.0) theta += 2*osg::PI;
422            double phi = osg::PI_2 * delta.length() / screenRadius;
423            if (phi > osg::PI_2) phi = osg::PI_2;
424
425            double f = distance * sin(phi);
426            double e = distance * cos(phi) + sqrt( sphere_radius*sphere_radius - f*f);
427            double l = e * cos(phi);
428            double h = e * sin(phi);
429            double gamma = atan2(h, l-distance);
430
431            osg::Vec2 texcoord(theta/(2.0*osg::PI), 1.0-gamma/osg::PI);
432
433            // osg::notify(osg::NOTICE)<<"cursor = "<<cursor<< " theta = "<<theta<< "phi="<<phi<<" gamma = "<<gamma<<" texcoord="<<texcoord<<std::endl;
434
435            if (flip)
436                vertices->push_back(osg::Vec3(cursor.x(), top.y()-(cursor.y()-origin.y()),cursor.z()));
437            else
438                vertices->push_back(cursor);
439
440            colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
441            texcoords->push_back(texcoord);
442
443            cursor += dx;
444        }
445
446        // osg::notify(osg::NOTICE)<<std::endl;
447    }
448
449    // pass the created vertex array to the points geometry object.
450    geometry->setVertexArray(vertices);
451
452    geometry->setColorArray(colors);
453    geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
454
455    geometry->setTexCoordArray(0,texcoords);
456
457    for(i=0;i<noSteps-1;++i)
458    {
459        osg::DrawElementsUShort* elements = new osg::DrawElementsUShort(osg::PrimitiveSet::QUAD_STRIP);
460        for(j=0;j<noSteps;++j)
461        {
462            elements->push_back(j+(i+1)*noSteps);
463            elements->push_back(j+(i)*noSteps);
464        }
465        geometry->addPrimitiveSet(elements);
466    }
467   
468    return geometry;
469}
470
471
472void setDomeCorrection(osgViewer::Viewer& viewer, osg::ArgumentParser& arguments)
473{
474    // enforce single threading right now to avoid double buffering of RTT texture
475    viewer.setThreadingModel(osgViewer::Viewer::SingleThreaded);
476 
477    osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface();
478    if (!wsi)
479    {
480        osg::notify(osg::NOTICE)<<"Error, no WindowSystemInterface available, cannot create windows."<<std::endl;
481        return;
482    }
483
484    unsigned int screenNum = 0;
485    while (arguments.read("--screen",screenNum)) {}
486
487
488    unsigned int width, height;
489    wsi->getScreenResolution(osg::GraphicsContext::ScreenIdentifier(screenNum), width, height);
490
491    while (arguments.read("--width",width)) {}
492    while (arguments.read("--height",height)) {}
493
494    osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
495    traits->screenNum = screenNum;
496    traits->x = 0;
497    traits->y = 0;
498    traits->width = width;
499    traits->height = height;
500    traits->windowDecoration = false;
501    traits->doubleBuffer = true;
502    traits->sharedContext = 0;
503   
504   
505
506    osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());
507    if (!gc)
508    {
509        osg::notify(osg::NOTICE)<<"GraphicsWindow has not been created successfully."<<std::endl;
510        return;
511    }
512
513    osg::ref_ptr<osg::Drawable> distortionCorrectionMash = createDomeDistortionMesh(osg::Vec3(0.0f,0.0f,0.0f), osg::Vec3(width,0.0f,0.0f), osg::Vec3(0.0f,height,0.0f), arguments);
514
515    osg::Texture* texture = 0;
516    for(int i=1;i<arguments.argc() && !texture;++i)
517    {
518        if (arguments.isString(i))
519        {
520            osg::Image* image = osgDB::readImageFile(arguments[i]);
521            osg::ImageStream* imagestream = dynamic_cast<osg::ImageStream*>(image);
522            if (imagestream) imagestream->play();
523
524            if (image)
525            {
526#if 1           
527                texture = new osg::TextureRectangle(image);
528#else
529                texture = new osg::Texture2D(image);
530#endif
531            }
532        }
533    }
534   
535    if (!texture)
536    {
537        return;
538    }
539
540    // distortion correction set up.
541    {
542        osg::Geode* geode = new osg::Geode();
543        geode->addDrawable(distortionCorrectionMash.get());
544
545        // new we need to add the texture to the mesh, we do so by creating a
546        // StateSet to contain the Texture StateAttribute.
547        osg::StateSet* stateset = geode->getOrCreateStateSet();
548        stateset->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
549        texture->setMaxAnisotropy(16.0f);
550        stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
551#if 1       
552        osg::TexMat* texmat = new osg::TexMat;
553        texmat->setScaleByTextureRectangleSize(true);
554        stateset->setTextureAttributeAndModes(0, texmat, osg::StateAttribute::ON);
555#endif
556        osg::ref_ptr<osg::Camera> camera = new osg::Camera;
557        camera->setGraphicsContext(gc.get());
558        camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT );
559        camera->setClearColor( osg::Vec4(0.1,0.1,1.0,1.0) );
560        camera->setViewport(new osg::Viewport(0, 0, width, height));
561        GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT;
562        camera->setDrawBuffer(buffer);
563        camera->setReadBuffer(buffer);
564        camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF);
565        camera->setAllowEventFocus(false);
566        //camera->setInheritanceMask(camera->getInheritanceMask() & ~osg::CullSettings::CLEAR_COLOR & ~osg::CullSettings::COMPUTE_NEAR_FAR_MODE);
567        //camera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
568       
569        camera->setProjectionMatrixAsOrtho2D(0,width,0,height);
570        camera->setViewMatrix(osg::Matrix::identity());
571
572        // add subgraph to render
573        // camera->addChild(geode);
574       
575        camera->setName("DistortionCorrectionCamera");
576
577        viewer.addSlave(camera.get(), osg::Matrixd(), osg::Matrixd(), true);
578
579        viewer.setSceneData(geode);
580    }
581   
582   
583    viewer.getCamera()->setNearFarRatio(0.0001f);
584}
585
586int main(int argc, char** argv)
587{
588    // use an ArgumentParser object to manage the program arguments.
589    osg::ArgumentParser arguments(&argc,argv);
590   
591    // set up the usage document, in case we need to print out how to use this program.
592    arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName());
593    arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" example demonstrates the use of ImageStream for rendering movies as textures.");
594    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ...");
595    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
596    arguments.getApplicationUsage()->addCommandLineOption("--texture2D","Use Texture2D rather than TextureRectangle.");
597    arguments.getApplicationUsage()->addCommandLineOption("--shader","Use shaders to post process the video.");
598    arguments.getApplicationUsage()->addCommandLineOption("--dome","Use full dome distortion correction.");
599   
600    bool useTextureRectangle = true;
601    bool useShader = false;
602
603    // construct the viewer.
604    osgViewer::Viewer viewer;
605   
606    if (arguments.argc()<=1)
607    {
608        arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION);
609        return 1;
610    }
611
612    while (arguments.read("--texture2D")) useTextureRectangle=false;
613    while (arguments.read("--shader")) useShader=true;
614
615    // if user request help write it out to cout.
616    if (arguments.read("-h") || arguments.read("--help"))
617    {
618        arguments.getApplicationUsage()->write(std::cout);
619        return 1;
620    }
621
622
623
624    if (arguments.read("--dome") || arguments.read("--puffer") )
625    {   
626        setDomeCorrection(viewer, arguments);
627    }
628    else
629    {
630        osg::ref_ptr<osg::Geode> geode = new osg::Geode;
631        osg::Vec3 pos(0.0f,0.0f,0.0f);
632
633        osg::StateSet* stateset = geode->getOrCreateStateSet();
634        stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
635
636        if (useShader)
637        {
638            //useTextureRectangle = false;
639
640            static const char *shaderSourceTextureRec = {
641                "uniform vec4 cutoff_color;\n"
642                "uniform samplerRect movie_texture;\n"
643                "void main(void)\n"
644                "{\n"
645                "    vec4 texture_color = textureRect(movie_texture, gl_TexCoord[0]); \n"
646                "    if (all(lessThanEqual(texture_color,cutoff_color))) discard; \n"
647                "    gl_FragColor = texture_color;\n"
648                "}\n"
649            };
650
651            static const char *shaderSourceTexture2D = {
652                "uniform vec4 cutoff_color;\n"
653                "uniform sampler2D movie_texture;\n"
654                "void main(void)\n"
655                "{\n"
656                "    vec4 texture_color = texture2D(movie_texture, gl_TexCoord[0]); \n"
657                "    if (all(lessThanEqual(texture_color,cutoff_color))) discard; \n"
658                "    gl_FragColor = texture_color;\n"
659                "}\n"
660            };
661
662            osg::Program* program = new osg::Program;
663
664            program->addShader(new osg::Shader(osg::Shader::FRAGMENT,
665                                               useTextureRectangle ? shaderSourceTextureRec : shaderSourceTexture2D));
666
667            stateset->addUniform(new osg::Uniform("cutoff_color",osg::Vec4(0.1f,0.1f,0.1f,1.0f)));
668            stateset->addUniform(new osg::Uniform("movie_texture",0));
669
670            stateset->setAttribute(program);
671
672        }
673
674        for(int i=1;i<arguments.argc();++i)
675        {
676            if (arguments.isString(i))
677            {
678                osg::Image* image = osgDB::readImageFile(arguments[i]);
679                osg::ImageStream* imagestream = dynamic_cast<osg::ImageStream*>(image);
680                if (imagestream) imagestream->play();
681
682                if (image)
683                {
684                    geode->addDrawable(myCreateTexturedQuadGeometry(pos,image->s(),image->t(),image, useTextureRectangle));
685
686                    pos.z() += image->t()*1.5f;
687                }
688                else
689                {
690                    std::cout<<"Unable to read file "<<arguments[i]<<std::endl;
691                }           
692            }
693        }
694
695        // set the scene to render
696        viewer.setSceneData(geode.get());
697
698        if (viewer.getSceneData()==0)
699        {
700            arguments.getApplicationUsage()->write(std::cout);
701            return 1;
702        }
703    }
704   
705
706    // pass the model to the MovieEventHandler so it can pick out ImageStream's to manipulate.
707    MovieEventHandler* meh = new MovieEventHandler();
708    meh->set(viewer.getSceneData());
709    viewer.addEventHandler(meh);
710
711    // report any errors if they have occured when parsing the program aguments.
712    if (arguments.errors())
713    {
714        arguments.writeErrorMessages(std::cout);
715        return 1;
716    }
717
718
719
720    // create the windows and run the threads.
721    return viewer.run();
722
723
724}
Note: See TracBrowser for help on using the browser.