root/OpenSceneGraph/trunk/examples/osgstereoimage/osgstereoimage.cpp @ 12529

Revision 12529, 23.0 kB (checked in by robert, 3 years ago)

Replaced .osg with .osgt file usage

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* OpenSceneGraph example, osgstereoimage.
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 <osgViewer/Viewer>
20#include <osgDB/fstream>
21#include <osgDB/ReadFile>
22#include <osgDB/WriteFile>
23#include <osgUtil/Optimizer>
24
25#include <osg/ImageStream>
26#include <osg/Geode>
27#include <osg/Notify>
28#include <osg/MatrixTransform>
29#include <osg/Switch>
30#include <osg/TexMat>
31#include <osg/Texture2D>
32
33#include <iostream>
34
35typedef std::vector<std::string> FileList;
36
37#include <osg/Program>
38#include <osg/Shader>
39
40osg::StateSet* createColorToGreyscaleStateSet()
41{
42    osg::StateSet* stateset = new osg::StateSet;
43   
44    osg::Program* program = new osg::Program;
45    stateset->setAttribute(program);
46   
47    const char* fragSource =
48    {
49        "uniform sampler2D baseTexture;\n"
50        "uniform mat4 colorMatrix;\n"
51        "void main(void)\n"
52        "{\n"
53        "    vec4 color = texture2D( baseTexture, gl_TexCoord[0].st );\n"
54        "    gl_FragColor = colorMatrix * color;\n"
55        "}\n"
56    };
57    program->addShader(new osg::Shader(osg::Shader::FRAGMENT, fragSource));
58   
59    stateset->addUniform(new osg::Uniform("baseTexture",0));
60
61    osg::Matrixf colorMatrix(
62        0.3f, 0.3f, 0.3f, 0.0f,
63        0.59f, 0.59f, 0.59f, 0.0f,
64        0.11f, 0.11f, 0.11f, 0.0f,
65        0.0f, 0.0f, 0.0f, 1.0f
66    );   
67   
68    stateset->addUniform(new osg::Uniform("colorMatrix",colorMatrix));
69
70    return stateset;
71}
72
73
74osg::Geode* createSectorForImage(osg::Image* image, osg::TexMat* texmat, float s,float t, float radius, float height, float length)
75{
76    bool flip = image->getOrigin()==osg::Image::TOP_LEFT;
77
78    int numSegments = 20;
79    float Theta = length/radius;
80    float dTheta = Theta/(float)(numSegments-1);
81   
82    float ThetaZero = height*s/(t*radius);
83   
84    // set up the texture.
85    osg::Texture2D* texture = new osg::Texture2D;
86    texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR);
87    texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
88    texture->setWrap(osg::Texture2D::WRAP_S,osg::Texture2D::CLAMP_TO_BORDER);
89    texture->setWrap(osg::Texture2D::WRAP_T,osg::Texture2D::CLAMP_TO_BORDER);
90    texture->setResizeNonPowerOfTwoHint(false);
91    texture->setImage(image);
92
93    // set up the drawstate.
94    osg::StateSet* dstate = new osg::StateSet;
95    dstate->setMode(GL_CULL_FACE,osg::StateAttribute::OFF);
96    dstate->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
97    dstate->setTextureAttributeAndModes(0, texture,osg::StateAttribute::ON);
98    dstate->setTextureAttribute(0, texmat);
99
100    // set up the geoset.
101    osg::Geometry* geom = new osg::Geometry;
102    geom->setStateSet(dstate);
103
104    osg::Vec3Array* coords = new osg::Vec3Array();
105    osg::Vec2Array* tcoords = new osg::Vec2Array();
106   
107    int i;
108    float angle = -Theta/2.0f;
109    for(i=0;
110        i<numSegments;
111        ++i, angle+=dTheta)
112    {
113        coords->push_back(osg::Vec3(sinf(angle)*radius,cosf(angle)*radius,height*0.5f)); // top
114        coords->push_back(osg::Vec3(sinf(angle)*radius,cosf(angle)*radius,-height*0.5f)); // bottom.
115       
116        tcoords->push_back(osg::Vec2(angle/ThetaZero+0.5f, flip ? 0.0f : 1.0f)); // top
117        tcoords->push_back(osg::Vec2(angle/ThetaZero+0.5f, flip ? 1.0f : 0.0f)); // bottom.
118
119    }
120
121    osg::Vec4Array* colors = new osg::Vec4Array();
122    colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
123
124    osg::DrawArrays* elements = new osg::DrawArrays(osg::PrimitiveSet::QUAD_STRIP,0,coords->size());
125
126   
127
128    geom->setVertexArray(coords);
129    geom->setTexCoordArray(0,tcoords);
130    geom->setColorArray(colors);
131    geom->setColorBinding(osg::Geometry::BIND_OVERALL);
132
133    geom->addPrimitiveSet(elements);
134
135    // set up the geode.
136    osg::Geode* geode = new osg::Geode;
137    geode->addDrawable(geom);
138
139    return geode;
140
141}
142
143osg::Group * loadImages(std::string image1, std::string image2, osg::TexMat* texmatLeft, osg::TexMat* texmatRight, float radius, float height, float length)
144{
145    osg::ref_ptr<osg::Image> imageLeft = osgDB::readImageFile(image1);
146    osg::ref_ptr<osg::Image> imageRight = osgDB::readImageFile(image2);
147    if (imageLeft.valid() && imageRight.valid())
148    {
149        osg::ImageStream* streamLeft = dynamic_cast<osg::ImageStream*>(imageLeft.get());
150        if (streamLeft) streamLeft->play();
151
152        osg::ImageStream* streamRight = dynamic_cast<osg::ImageStream*>(imageRight.get());
153        if (streamRight) streamRight->play();
154
155
156        float average_s = (imageLeft->s()+imageRight->s())*0.5f;
157        float average_t = (imageLeft->t()+imageRight->t())*0.5f;
158        osg::Geode* geodeLeft = createSectorForImage(imageLeft.get(),texmatLeft,average_s,average_t, radius, height, length);
159        geodeLeft->setNodeMask(0x01);
160
161        osg::Geode* geodeRight = createSectorForImage(imageRight.get(),texmatRight,average_s,average_t, radius, height, length);
162        geodeRight->setNodeMask(0x02);
163
164        osg::Group * imageGroup = new osg::Group;
165
166        imageGroup->addChild(geodeLeft);
167        imageGroup->addChild(geodeRight);
168        return imageGroup;
169    }
170    else
171    {
172        std::cout << "Warning: Unable to load both image files, '"<<image1<<"' & '"<<image2<<"', required for stereo imaging."<<std::endl;
173        return 0;
174    }
175}
176
177// create a switch containing a set of child each containing a
178// stereo image pair.
179osg::Switch* createScene(FileList fileList, osg::TexMat* texmatLeft, osg::TexMat* texmatRight, float radius, float height, float length)
180{
181    osg::Switch* sw = new osg::Switch;
182
183    // load the images.
184    for(unsigned int i=0;i+1<fileList.size();i+=2)
185    {
186        osg::Group * imageGroup = loadImages(fileList[i],fileList[i+1],texmatLeft,texmatRight, radius,  height, length);
187        if (imageGroup) sw->addChild(imageGroup);
188    }
189
190
191    if (sw->getNumChildren()>0)
192    {
193        // select first child.
194        sw->setSingleChildOn(0);
195    }
196
197    return sw;
198}
199
200class SlideEventHandler : public osgGA::GUIEventHandler
201{
202public:
203
204    SlideEventHandler();
205   
206    META_Object(osgStereImageApp,SlideEventHandler);
207
208
209    void set(osg::Switch* sw, float offsetX, float offsetY, osg::TexMat* texmatLeft, osg::TexMat* texmatRight, float timePerSlide, bool autoSteppingActive);
210
211    void set(FileList fileList, osg::Switch* sw, float offsetX, float offsetY, osg::TexMat* texmatLeft, osg::TexMat* texmatRight, float radius, float height, float length, float timePerSlide, bool autoSteppingActive);
212
213
214    virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&);
215   
216    virtual void getUsage(osg::ApplicationUsage& usage) const;
217
218    virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
219   
220    void nextSlide();
221   
222    void previousSlide();
223   
224    void scaleImage(float s);
225   
226    void offsetImage(float ds,float dt);
227
228    void rotateImage(float rx,float ry);
229
230    void initTexMatrices();
231
232protected:
233
234    ~SlideEventHandler() {}
235    SlideEventHandler(const SlideEventHandler&,const osg::CopyOp&) {}
236
237    osg::ref_ptr<osg::Switch>   _switch;
238    osg::ref_ptr<osg::TexMat>   _texmatLeft;
239    osg::ref_ptr<osg::TexMat>   _texmatRight;
240    float                        _radius;
241    float                        _height;
242    float                        _length;
243    bool                        _firstTraversal;
244    unsigned int                _activeSlide;
245    double                      _previousTime;
246    double                      _timePerSlide;
247    bool                        _autoSteppingActive;
248    float                       _initSeperationX;
249    float                       _currentSeperationX;
250    float                       _initSeperationY;
251    float                       _currentSeperationY;
252    FileList                     _fileList;
253       
254};
255
256SlideEventHandler::SlideEventHandler():
257    _switch(0),
258    _texmatLeft(0),
259    _texmatRight(0),
260    _firstTraversal(true),
261    _activeSlide(0),
262    _previousTime(-1.0f),
263    _timePerSlide(5.0),
264    _autoSteppingActive(false)
265{
266}
267
268void SlideEventHandler::set(osg::Switch* sw, float offsetX, float offsetY, osg::TexMat* texmatLeft, osg::TexMat* texmatRight, float timePerSlide, bool autoSteppingActive)
269{
270    _switch = sw;
271    _switch->setUpdateCallback(this);
272
273    _texmatLeft = texmatLeft;
274    _texmatRight = texmatRight;
275
276    _timePerSlide = timePerSlide;
277    _autoSteppingActive = autoSteppingActive;   
278   
279    _initSeperationX = offsetX;
280    _currentSeperationX = _initSeperationX;
281
282    _initSeperationY = offsetY;
283    _currentSeperationY = _initSeperationY;
284
285    initTexMatrices();
286
287}
288
289void SlideEventHandler::set(FileList fileList, osg::Switch* sw, float offsetX, float offsetY, osg::TexMat* texmatLeft, osg::TexMat* texmatRight, float radius, float height, float length, float timePerSlide, bool autoSteppingActive)
290{
291    _switch = sw;
292    _switch->setUpdateCallback(this);
293    _fileList=FileList(fileList);
294
295    osg::ref_ptr<osg::Group> imageGroup = loadImages(fileList[0],fileList[1],texmatLeft,texmatRight, radius,  height, length);
296    if (imageGroup.get())_switch->addChild(imageGroup.get());
297
298    _texmatLeft = texmatLeft;
299    _texmatRight = texmatRight;
300
301    _radius=radius;
302    _height=height;
303    _length=length;
304
305    _timePerSlide = timePerSlide;
306    _autoSteppingActive = autoSteppingActive;   
307   
308    _initSeperationX = offsetX;
309    _currentSeperationX = _initSeperationX;
310
311    _initSeperationY = offsetY;
312    _currentSeperationY = _initSeperationY;
313
314    initTexMatrices();
315}
316
317
318bool SlideEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&)
319{
320    switch(ea.getEventType())
321    {
322        case(osgGA::GUIEventAdapter::KEYDOWN):
323        {
324            if (ea.getKey()=='a')
325            {
326                _autoSteppingActive = !_autoSteppingActive;
327                _previousTime = ea.getTime();
328                return true;
329            }
330            else if ((ea.getKey()=='n') || (ea.getKey()==osgGA::GUIEventAdapter::KEY_Right))
331            {
332                nextSlide();
333                return true;
334            }
335            else if ((ea.getKey()=='p') || (ea.getKey()==osgGA::GUIEventAdapter::KEY_Left))
336            {
337                previousSlide();
338                return true;
339            }
340            else if ((ea.getKey()=='w') || (ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Add))
341            {
342                scaleImage(0.99f);
343                return true;
344            }
345            else if ((ea.getKey()=='s') || (ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Subtract))
346            {
347                scaleImage(1.01f);
348                return true;
349            }
350            else if (ea.getKey()=='j')
351            {
352                offsetImage(-0.001f,0.0f);
353                return true;
354            }
355            else if (ea.getKey()=='k')
356            {
357                offsetImage(0.001f,0.0f);
358                return true;
359            }
360            else if (ea.getKey()=='i')
361            {
362                offsetImage(0.0f,-0.001f);
363                return true;
364            }
365            else if (ea.getKey()=='m')
366            {
367                offsetImage(0.0f,0.001f);
368                return true;
369            }
370            else if (ea.getKey()==' ')
371            {
372                initTexMatrices();
373                return true;
374            }
375            return false;
376        }
377        case(osgGA::GUIEventAdapter::DRAG):
378        case(osgGA::GUIEventAdapter::MOVE):
379        {
380            static float px = ea.getXnormalized();
381            static float py = ea.getYnormalized();
382           
383            float dx = ea.getXnormalized()-px;
384            float dy = ea.getYnormalized()-py;
385           
386            px = ea.getXnormalized();
387            py = ea.getYnormalized();
388           
389            rotateImage(dx,dy);
390           
391            return true;
392        }
393
394        default:
395            return false;
396    }
397}
398
399void SlideEventHandler::getUsage(osg::ApplicationUsage& usage) const
400{
401    usage.addKeyboardMouseBinding("Space","Reset the image position to center");
402    usage.addKeyboardMouseBinding("a","Toggle on/off the automatic advancement for image to image");
403    usage.addKeyboardMouseBinding("n","Advance to next image");
404    usage.addKeyboardMouseBinding("p","Move to previous image");
405    usage.addKeyboardMouseBinding("q","Zoom into the image");
406    usage.addKeyboardMouseBinding("a","Zoom out of the image");
407    usage.addKeyboardMouseBinding("j","Reduce horizontal offset");
408    usage.addKeyboardMouseBinding("k","Increase horizontal offset");
409    usage.addKeyboardMouseBinding("m","Reduce vertical offset");
410    usage.addKeyboardMouseBinding("i","Increase vertical offset");
411}
412
413void SlideEventHandler::operator()(osg::Node* node, osg::NodeVisitor* nv)
414{
415    if (_autoSteppingActive && nv->getFrameStamp())
416    {
417        double time = nv->getFrameStamp()->getSimulationTime();
418       
419        if (_firstTraversal)
420        {
421            _firstTraversal = false;
422            _previousTime = time;
423        }
424        else if (time-_previousTime>_timePerSlide)
425        {
426            _previousTime = time;
427           
428            nextSlide();
429        }
430       
431    }
432
433    traverse(node,nv);
434}
435
436void SlideEventHandler::nextSlide()
437{
438
439    if (_switch->getNumChildren()==0) return;
440
441    ++_activeSlide;
442
443    if (_fileList.size()>0) {
444        if (_activeSlide>= _fileList.size()/2 ) _activeSlide = 0;
445        osg::ref_ptr<osg::Group> images = loadImages(_fileList[2*_activeSlide],_fileList[2*_activeSlide+1],_texmatLeft.get(),_texmatRight.get(),_radius,_height,_length);
446        if (images.valid()) _switch->replaceChild(_switch->getChild(0),images.get());
447
448    } else {
449        if (_activeSlide>=_switch->getNumChildren()) _activeSlide = 0;
450
451        _switch->setSingleChildOn(_activeSlide);
452    }
453}
454
455void SlideEventHandler::previousSlide()
456{
457    if (_switch->getNumChildren()==0) return;
458
459    if (_fileList.size()>0) {
460        if (_activeSlide==0) _activeSlide = _fileList.size()/2-1;
461        else --_activeSlide;
462        osg::ref_ptr<osg::Group> images = loadImages(_fileList[2*_activeSlide],_fileList[2*_activeSlide+1],_texmatLeft.get(),_texmatRight.get(),_radius,_height,_length);
463        if (images.valid()) _switch->replaceChild(_switch->getChild(0),images.get());
464    } else {   
465        if (_activeSlide==0) _activeSlide = _switch->getNumChildren()-1;
466        else --_activeSlide;
467
468        _switch->setSingleChildOn(_activeSlide);
469    }
470}
471
472void SlideEventHandler::scaleImage(float s)
473{
474    _texmatLeft->setMatrix(_texmatLeft->getMatrix()*osg::Matrix::translate(-0.5f,-0.5f,0.0f)*osg::Matrix::scale(s,s,1.0f)*osg::Matrix::translate(0.5f,0.5f,0.0f));
475    _texmatRight->setMatrix(_texmatRight->getMatrix()*osg::Matrix::translate(-0.5f,-0.5f,0.0f)*osg::Matrix::scale(s,s,1.0f)*osg::Matrix::translate(0.5f,0.5f,0.0f));
476}
477
478void SlideEventHandler::offsetImage(float ds,float dt)
479{
480    _currentSeperationX+=ds;
481    _currentSeperationY+=dt;
482    osg::notify(osg::NOTICE)<<"image offset x = "<<_currentSeperationX<<"  y ="<<_currentSeperationY<<std::endl;
483    _texmatLeft->setMatrix(_texmatLeft->getMatrix()*osg::Matrix::translate(ds,dt,0.0f));
484    _texmatRight->setMatrix(_texmatRight->getMatrix()*osg::Matrix::translate(-ds,-dt,0.0f));
485}
486
487void SlideEventHandler::rotateImage(float rx,float ry)
488{
489    const float scale = 0.5f;
490    _texmatLeft->setMatrix(_texmatLeft->getMatrix()*osg::Matrix::translate(-rx*scale,-ry*scale,0.0f));
491    _texmatRight->setMatrix(_texmatRight->getMatrix()*osg::Matrix::translate(-rx*scale,-ry*scale,0.0f));
492}
493
494void SlideEventHandler::initTexMatrices()
495{
496    _texmatLeft->setMatrix(osg::Matrix::translate(_initSeperationX,_initSeperationY,0.0f));
497    _texmatRight->setMatrix(osg::Matrix::translate(-_initSeperationX,-_initSeperationY,0.0f));
498}
499
500
501
502int main( int argc, char **argv )
503{
504    // use an ArgumentParser object to manage the program arguments.
505    osg::ArgumentParser arguments(&argc,argv);
506   
507    // set up the usage document, in case we need to print out how to use this program.
508    arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the example which demonstrates use node masks to create stereo images.");
509    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] image_file_left_eye image_file_right_eye");
510    arguments.getApplicationUsage()->addCommandLineOption("-d <float>","Time delay in seconds between the display of successive image pairs when in auto advance mode.");
511    arguments.getApplicationUsage()->addCommandLineOption("-a","Enter auto advance of image pairs on start up.");
512    arguments.getApplicationUsage()->addCommandLineOption("-x <float>","Horizontal offset of left and right images.");
513    arguments.getApplicationUsage()->addCommandLineOption("-y <float>","Vertical offset of left and right images.");
514    arguments.getApplicationUsage()->addCommandLineOption("--disk","Keep images on disk");
515    arguments.getApplicationUsage()->addCommandLineOption("-files <filename>","Load filenames from a file");
516    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
517    arguments.getApplicationUsage()->addCommandLineOption("--SingleThreaded","Select SingleThreaded threading model for viewer.");
518    arguments.getApplicationUsage()->addCommandLineOption("--CullDrawThreadPerContext","Select CullDrawThreadPerContext threading model for viewer.");
519    arguments.getApplicationUsage()->addCommandLineOption("--DrawThreadPerContext","Select DrawThreadPerContext threading model for viewer.");
520    arguments.getApplicationUsage()->addCommandLineOption("--CullThreadPerCameraDrawThreadPerContext","Select CullThreadPerCameraDrawThreadPerContext threading model for viewer.");
521   
522
523    // construct the viewer.
524    osgViewer::Viewer viewer(arguments);
525
526    // register the handler to add keyboard and mouse handling.
527    SlideEventHandler* seh = new SlideEventHandler();
528    viewer.addEventHandler(seh);
529
530    // read any time delay argument.
531    float timeDelayBetweenSlides = 5.0f;
532    while (arguments.read("-d",timeDelayBetweenSlides)) {}
533
534    bool autoSteppingActive = false;
535    while (arguments.read("-a")) autoSteppingActive = true;
536
537    float offsetX=0.0f;
538    while (arguments.read("-x",offsetX)) {}
539
540    float offsetY=0.0f;
541    while (arguments.read("-y",offsetY)) {}
542
543    bool onDisk=false;
544    while (arguments.read("--disk")) { onDisk=true;}
545
546    std::string filename="";
547    FileList fileList;
548    // extract the filenames from the a file, one filename per line.
549    while (arguments.read("-files",filename)) {
550        osgDB::ifstream is(filename.c_str());
551        if (is) {
552                std::string line;
553                while (std::getline(is,line,'\n')) fileList.push_back(line);
554                is.close();
555            }
556   
557    }
558
559    // if user request help write it out to cout.
560    if (arguments.read("-h") || arguments.read("--help"))
561    {
562        arguments.getApplicationUsage()->write(std::cout);
563        return 1;
564    }
565
566    osgViewer::Viewer::ThreadingModel threading = osgViewer::Viewer::SingleThreaded;
567    while (arguments.read("--SingleThreaded")) threading = osgViewer::Viewer::SingleThreaded;
568    while (arguments.read("--CullDrawThreadPerContext")) threading = osgViewer::Viewer::CullDrawThreadPerContext;
569    while (arguments.read("--DrawThreadPerContext")) threading = osgViewer::Viewer::DrawThreadPerContext;
570    while (arguments.read("--CullThreadPerCameraDrawThreadPerContext")) threading = osgViewer::Viewer::CullThreadPerCameraDrawThreadPerContext;
571
572    viewer.setThreadingModel(threading);
573
574    // any option left unread are converted into errors to write out later.
575    arguments.reportRemainingOptionsAsUnrecognized();
576
577    // report any errors if they have occurred when parsing the program arguments.
578    if (arguments.errors())
579    {
580        arguments.writeErrorMessages(std::cout);
581        return 1;
582    }
583   
584    // extract the filenames from the arguments list.
585    for(int pos=1;pos<arguments.argc();++pos)
586    {
587        if (arguments.isString(pos)) fileList.push_back(arguments[pos]);
588    }
589
590    if (fileList.empty())
591    {
592        fileList.push_back("Images/dog_left_eye.jpg");
593         fileList.push_back("Images/dog_right_eye.jpg");
594    }
595    else if (fileList.size()<2)
596    {
597        arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION);
598        return 1;
599    }
600
601    // now the windows have been realized we switch off the cursor to prevent it
602    // distracting the people seeing the stereo images.
603    double fovy, aspectRatio, zNear, zFar;
604    viewer.getCamera()->getProjectionMatrixAsPerspective(fovy, aspectRatio, zNear, zFar);
605
606    float radius = 1.0f;
607    float height = 2*radius*tan(osg::DegreesToRadians(fovy)*0.5f);
608    float length = osg::PI*radius;  // half a cylinder.
609
610    // use a texture matrix to control the placement of the image.
611    osg::TexMat* texmatLeft = new osg::TexMat;
612    osg::TexMat* texmatRight = new osg::TexMat;
613
614    // creat the scene from the file list.
615    osg::ref_ptr<osg::Switch> rootNode;
616    if (!onDisk)  rootNode = createScene(fileList,texmatLeft,texmatRight,radius,height,length);
617    else rootNode=new osg::Switch();
618
619    //osgDB::writeNodeFile(*rootNode,"test.osgt");
620
621
622
623    viewer.getCamera()->setCullMask(0xffffffff);
624    viewer.getCamera()->setCullMaskLeft(0x00000001);
625    viewer.getCamera()->setCullMaskRight(0x00000002);
626
627    // set up the use of stereo by default.
628    osg::DisplaySettings::instance()->setStereo(true);
629
630    if (osg::DisplaySettings::instance()->getStereoMode()==osg::DisplaySettings::ANAGLYPHIC)
631    {
632        rootNode->setStateSet(createColorToGreyscaleStateSet());
633    }
634   
635   
636    // set the scene to render
637    viewer.setSceneData(rootNode.get());
638
639
640    // create the windows and run the threads.
641    viewer.realize();
642
643
644    // switch off the cursor
645    osgViewer::Viewer::Windows windows;
646    viewer.getWindows(windows);
647    for(osgViewer::Viewer::Windows::iterator itr = windows.begin();
648        itr != windows.end();
649        ++itr)
650    {
651        (*itr)->useCursor(false);
652    }
653
654    viewer.setFusionDistance(osgUtil::SceneView::USE_FUSION_DISTANCE_VALUE,radius);
655
656    // set up the SlideEventHandler.
657    if (onDisk) seh->set(fileList,rootNode.get(),offsetX,offsetY,texmatLeft,texmatRight,radius,height,length,timeDelayBetweenSlides,autoSteppingActive);
658    else seh->set(rootNode.get(),offsetX,offsetY,texmatLeft,texmatRight,timeDelayBetweenSlides,autoSteppingActive);
659   
660    osg::Matrix homePosition;
661    homePosition.makeLookAt(osg::Vec3(0.0f,0.0f,0.0f),osg::Vec3(0.0f,1.0f,0.0f),osg::Vec3(0.0f,0.0f,1.0f));
662       
663    while( !viewer.done() )
664    {
665        viewer.getCamera()->setViewMatrix(homePosition);
666
667        // fire off the cull and draw traversals of the scene.
668        viewer.frame();
669       
670    }
671   
672    return 0;
673}
Note: See TracBrowser for help on using the browser.