Show
Ignore:
Timestamp:
08/13/07 12:31:33 (7 years ago)
Author:
robert
Message:

From Luc Frauciel, "I've done 2 main modifications :
1) added texture->setResizeNonPowerOfTwoHint(false); when loading an
image. It speeds up by 10 the loading of large images.
2) added a --disk option : only a filelist is read, images are only
loaded when needed. It allows to handle very large set of very large
images that would not fit in memory. Nothing change when the option is
not set."

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/examples/osgstereoimage/osgstereoimage.cpp

    r6941 r7228  
    3333typedef std::vector<std::string> FileList; 
    3434 
     35osg::Geode* createSectorForImage(osg::Image* image, osg::TexMat* texmat, float s,float t, float radius, float height, float length) 
     36{ 
     37 
     38    int numSegments = 20; 
     39    float Theta = length/radius; 
     40    float dTheta = Theta/(float)(numSegments-1); 
     41     
     42    float ThetaZero = height*s/(t*radius); 
     43     
     44    // set up the texture. 
     45    osg::Texture2D* texture = new osg::Texture2D; 
     46    texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR); 
     47    texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR); 
     48    texture->setResizeNonPowerOfTwoHint(false); 
     49    texture->setImage(image); 
     50 
     51    // set up the drawstate. 
     52    osg::StateSet* dstate = new osg::StateSet; 
     53    dstate->setMode(GL_CULL_FACE,osg::StateAttribute::OFF); 
     54    dstate->setMode(GL_LIGHTING,osg::StateAttribute::OFF); 
     55    dstate->setTextureAttributeAndModes(0, texture,osg::StateAttribute::ON); 
     56    dstate->setTextureAttribute(0, texmat); 
     57 
     58    // set up the geoset. 
     59    osg::Geometry* geom = new osg::Geometry; 
     60    geom->setStateSet(dstate); 
     61 
     62    osg::Vec3Array* coords = new osg::Vec3Array(); 
     63    osg::Vec2Array* tcoords = new osg::Vec2Array(); 
     64    
     65    int i; 
     66    float angle = -Theta/2.0f; 
     67    for(i=0; 
     68        i<numSegments; 
     69        ++i, angle+=dTheta) 
     70    { 
     71        coords->push_back(osg::Vec3(sinf(angle)*radius,cosf(angle)*radius,height*0.5f)); // top 
     72        coords->push_back(osg::Vec3(sinf(angle)*radius,cosf(angle)*radius,-height*0.5f)); // bottom. 
     73         
     74        tcoords->push_back(osg::Vec2(angle/ThetaZero+0.5f,1.0f)); // top 
     75        tcoords->push_back(osg::Vec2(angle/ThetaZero+0.5f,0.0f)); // bottom. 
     76 
     77    } 
     78 
     79    osg::Vec4Array* colors = new osg::Vec4Array(); 
     80    colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f)); 
     81 
     82    osg::DrawArrays* elements = new osg::DrawArrays(osg::PrimitiveSet::QUAD_STRIP,0,coords->size()); 
     83 
     84     
     85 
     86    geom->setVertexArray(coords); 
     87    geom->setTexCoordArray(0,tcoords); 
     88    geom->setColorArray(colors); 
     89    geom->setColorBinding(osg::Geometry::BIND_OVERALL); 
     90 
     91    geom->addPrimitiveSet(elements); 
     92 
     93    // set up the geode. 
     94    osg::Geode* geode = new osg::Geode; 
     95    geode->addDrawable(geom); 
     96 
     97    return geode; 
     98 
     99} 
     100 
     101osg::Group * loadImages(std::string image1, std::string image2, osg::TexMat* texmatLeft, osg::TexMat* texmatRight, float radius, float height, float length) { 
     102        osg::ref_ptr<osg::Image> imageLeft = osgDB::readImageFile(image1); 
     103        osg::ref_ptr<osg::Image> imageRight = osgDB::readImageFile(image2); 
     104        if (imageLeft.valid() && imageRight.valid()) 
     105        { 
     106            float average_s = (imageLeft->s()+imageRight->s())*0.5f; 
     107            float average_t = (imageLeft->t()+imageRight->t())*0.5f; 
     108            osg::Geode* geodeLeft = createSectorForImage(imageLeft.get(),texmatLeft,average_s,average_t, radius, height, length); 
     109            geodeLeft->setNodeMask(0x01); 
     110 
     111            osg::Geode* geodeRight = createSectorForImage(imageRight.get(),texmatRight,average_s,average_t, radius, height, length); 
     112            geodeRight->setNodeMask(0x02); 
     113 
     114            osg::Group * imageGroup = new osg::Group; 
     115             
     116            imageGroup->addChild(geodeLeft); 
     117            imageGroup->addChild(geodeRight); 
     118            return imageGroup; 
     119        } 
     120        else 
     121        { 
     122            std::cout << "Warning: Unable to load both image files, '"<<image1<<"' & '"<<image2<<"', required for stereo imaging."<<std::endl; 
     123            return 0; 
     124        } 
     125} 
     126 
     127// create a switch containing a set of child each containing a  
     128// stereo image pair. 
     129osg::Switch* createScene(FileList fileList, osg::TexMat* texmatLeft, osg::TexMat* texmatRight, float radius, float height, float length) 
     130{ 
     131    osg::Switch* sw = new osg::Switch; 
     132 
     133    // load the images. 
     134    for(unsigned int i=0;i+1<fileList.size();i+=2) 
     135    { 
     136        osg::Group * imageGroup = loadImages(fileList[i],fileList[i+1],texmatLeft,texmatRight, radius,  height, length); 
     137        if (imageGroup) sw->addChild(imageGroup); 
     138    } 
     139 
     140 
     141    if (sw->getNumChildren()>0) 
     142    { 
     143        // select first child. 
     144        sw->setSingleChildOn(0); 
     145    } 
     146 
     147    return sw; 
     148} 
     149 
    35150class SlideEventHandler : public osgGA::GUIEventHandler 
    36151{ 
     
    43158 
    44159    void set(osg::Switch* sw, float offsetX, float offsetY, osg::TexMat* texmatLeft, osg::TexMat* texmatRight, float timePerSlide, bool autoSteppingActive); 
     160 
     161    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); 
     162 
    45163 
    46164    virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&); 
     
    70188    osg::ref_ptr<osg::TexMat>   _texmatLeft; 
    71189    osg::ref_ptr<osg::TexMat>   _texmatRight; 
     190    float                        _radius; 
     191    float                        _height; 
     192    float                        _length; 
    72193    bool                        _firstTraversal; 
    73194    unsigned int                _activeSlide; 
     
    79200    float                       _initSeperationY; 
    80201    float                       _currentSeperationY; 
     202    FileList                     _fileList; 
    81203         
    82204}; 
     
    114236 
    115237} 
     238 
     239void 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) 
     240{ 
     241    _switch = sw; 
     242    _switch->setUpdateCallback(this); 
     243    _fileList=FileList(fileList); 
     244 
     245    osg::ref_ptr<osg::Group> imageGroup = loadImages(fileList[0],fileList[1],texmatLeft,texmatRight, radius,  height, length); 
     246    if (imageGroup.get())_switch->addChild(imageGroup.get()); 
     247 
     248    _texmatLeft = texmatLeft; 
     249    _texmatRight = texmatRight; 
     250 
     251    _radius=radius; 
     252    _height=height; 
     253    _length=length; 
     254 
     255    _timePerSlide = timePerSlide; 
     256    _autoSteppingActive = autoSteppingActive;     
     257     
     258    _initSeperationX = offsetX; 
     259    _currentSeperationX = _initSeperationX; 
     260 
     261    _initSeperationY = offsetY; 
     262    _currentSeperationY = _initSeperationY; 
     263 
     264    initTexMatrices(); 
     265} 
     266 
    116267 
    117268bool SlideEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&) 
     
    235386void SlideEventHandler::nextSlide() 
    236387{ 
     388 
    237389    if (_switch->getNumChildren()==0) return; 
    238390 
    239391    ++_activeSlide; 
    240     if (_activeSlide>=_switch->getNumChildren()) _activeSlide = 0; 
    241  
    242     _switch->setSingleChildOn(_activeSlide); 
     392 
     393    if (_fileList.size()>0) { 
     394        if (_activeSlide>= _fileList.size()/2 ) _activeSlide = 0; 
     395        osg::ref_ptr<osg::Group> images = loadImages(_fileList[2*_activeSlide],_fileList[2*_activeSlide+1],_texmatLeft.get(),_texmatRight.get(),_radius,_height,_length); 
     396        if (images.valid()) _switch->replaceChild(_switch->getChild(0),images.get()); 
     397 
     398    } else { 
     399        if (_activeSlide>=_switch->getNumChildren()) _activeSlide = 0; 
     400 
     401        _switch->setSingleChildOn(_activeSlide); 
     402    } 
    243403} 
    244404 
     
    247407    if (_switch->getNumChildren()==0) return; 
    248408 
    249     if (_activeSlide==0) _activeSlide = _switch->getNumChildren()-1; 
    250     else --_activeSlide; 
    251  
    252     _switch->setSingleChildOn(_activeSlide); 
     409    if (_fileList.size()>0) { 
     410        if (_activeSlide==0) _activeSlide = _fileList.size()/2-1; 
     411        else --_activeSlide; 
     412        osg::ref_ptr<osg::Group> images = loadImages(_fileList[2*_activeSlide],_fileList[2*_activeSlide+1],_texmatLeft.get(),_texmatRight.get(),_radius,_height,_length); 
     413        if (images.valid()) _switch->replaceChild(_switch->getChild(0),images.get()); 
     414    } else {     
     415        if (_activeSlide==0) _activeSlide = _switch->getNumChildren()-1; 
     416        else --_activeSlide; 
     417 
     418        _switch->setSingleChildOn(_activeSlide); 
     419    } 
    253420} 
    254421 
     
    282449 
    283450 
    284 osg::Geode* createSectorForImage(osg::Image* image, osg::TexMat* texmat, float s,float t, float radius, float height, float length) 
    285 { 
    286  
    287     int numSegments = 20; 
    288     float Theta = length/radius; 
    289     float dTheta = Theta/(float)(numSegments-1); 
    290      
    291     float ThetaZero = height*s/(t*radius); 
    292      
    293     // set up the texture. 
    294     osg::Texture2D* texture = new osg::Texture2D; 
    295     texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR); 
    296     texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR); 
    297     texture->setImage(image); 
    298  
    299     // set up the drawstate. 
    300     osg::StateSet* dstate = new osg::StateSet; 
    301     dstate->setMode(GL_CULL_FACE,osg::StateAttribute::OFF); 
    302     dstate->setMode(GL_LIGHTING,osg::StateAttribute::OFF); 
    303     dstate->setTextureAttributeAndModes(0, texture,osg::StateAttribute::ON); 
    304     dstate->setTextureAttribute(0, texmat); 
    305  
    306     // set up the geoset. 
    307     osg::Geometry* geom = new osg::Geometry; 
    308     geom->setStateSet(dstate); 
    309  
    310     osg::Vec3Array* coords = new osg::Vec3Array(); 
    311     osg::Vec2Array* tcoords = new osg::Vec2Array(); 
    312     
    313     int i; 
    314     float angle = -Theta/2.0f; 
    315     for(i=0; 
    316         i<numSegments; 
    317         ++i, angle+=dTheta) 
    318     { 
    319         coords->push_back(osg::Vec3(sinf(angle)*radius,cosf(angle)*radius,height*0.5f)); // top 
    320         coords->push_back(osg::Vec3(sinf(angle)*radius,cosf(angle)*radius,-height*0.5f)); // bottom. 
    321          
    322         tcoords->push_back(osg::Vec2(angle/ThetaZero+0.5f,1.0f)); // top 
    323         tcoords->push_back(osg::Vec2(angle/ThetaZero+0.5f,0.0f)); // bottom. 
    324  
    325     } 
    326  
    327     osg::Vec4Array* colors = new osg::Vec4Array(); 
    328     colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f)); 
    329  
    330     osg::DrawArrays* elements = new osg::DrawArrays(osg::PrimitiveSet::QUAD_STRIP,0,coords->size()); 
    331  
    332      
    333  
    334     geom->setVertexArray(coords); 
    335     geom->setTexCoordArray(0,tcoords); 
    336     geom->setColorArray(colors); 
    337     geom->setColorBinding(osg::Geometry::BIND_OVERALL); 
    338  
    339     geom->addPrimitiveSet(elements); 
    340  
    341     // set up the geode. 
    342     osg::Geode* geode = new osg::Geode; 
    343     geode->addDrawable(geom); 
    344  
    345     return geode; 
    346  
    347 } 
    348  
    349 // create a switch containing a set of child each containing a  
    350 // stereo image pair. 
    351 osg::Switch* createScene(const FileList& fileList, osg::TexMat* texmatLeft, osg::TexMat* texmatRight, float radius, float height, float length) 
    352 { 
    353     osg::Switch* sw = new osg::Switch; 
    354  
    355     // load the images. 
    356     for(unsigned int i=0;i+1<fileList.size();i+=2) 
    357     { 
    358         osg::ref_ptr<osg::Image> imageLeft = osgDB::readImageFile(fileList[i]); 
    359         osg::ref_ptr<osg::Image> imageRight = osgDB::readImageFile(fileList[i+1]); 
    360         if (imageLeft.valid() && imageRight.valid()) 
    361         { 
    362             float average_s = (imageLeft->s()+imageRight->s())*0.5f; 
    363             float average_t = (imageLeft->t()+imageRight->t())*0.5f; 
    364  
    365             osg::Geode* geodeLeft = createSectorForImage(imageLeft.get(),texmatLeft,average_s,average_t, radius, height, length); 
    366             geodeLeft->setNodeMask(0x01); 
    367  
    368             osg::Geode* geodeRight = createSectorForImage(imageRight.get(),texmatRight,average_s,average_t, radius, height, length); 
    369             geodeRight->setNodeMask(0x02); 
    370  
    371             osg::ref_ptr<osg::Group> imageGroup = new osg::Group; 
    372              
    373             imageGroup->addChild(geodeLeft); 
    374             imageGroup->addChild(geodeRight); 
    375              
    376             sw->addChild(imageGroup.get()); 
    377         } 
    378         else 
    379         { 
    380             std::cout << "Warning: Unable to load both image files, '"<<fileList[i]<<"' & '"<<fileList[i+1]<<"', required for stereo imaging."<<std::endl; 
    381         } 
    382     } 
    383  
    384  
    385     if (sw->getNumChildren()>0) 
    386     { 
    387         // select first child. 
    388         sw->setSingleChildOn(0); 
    389     } 
    390  
    391     return sw; 
    392 } 
    393451 
    394452int main( int argc, char **argv ) 
     
    404462    arguments.getApplicationUsage()->addCommandLineOption("-x <float>","Horizontal offset of left and right images."); 
    405463    arguments.getApplicationUsage()->addCommandLineOption("-y <float>","Vertical offset of left and right images."); 
     464    arguments.getApplicationUsage()->addCommandLineOption("--disk","Keep images on disk"); 
    406465    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information"); 
    407466    arguments.getApplicationUsage()->addCommandLineOption("--SingleThreaded","Select SingleThreaded threading model for viewer."); 
     
    431490    while (arguments.read("-y",offsetY)) {} 
    432491 
     492    bool onDisk=false; 
     493    while (arguments.read("--disk")) { onDisk=true;} 
     494 
    433495    // if user request help write it out to cout. 
    434496    if (arguments.read("-h") || arguments.read("--help")) 
     
    488550 
    489551    // creat the scene from the file list. 
    490     osg::ref_ptr<osg::Switch> rootNode = createScene(fileList,texmatLeft,texmatRight,radius,height,length); 
    491  
     552    osg::ref_ptr<osg::Switch> rootNode; 
     553    if (!onDisk)  rootNode = createScene(fileList,texmatLeft,texmatRight,radius,height,length); 
     554    else rootNode=new osg::Switch(); 
    492555 
    493556    //osgDB::writeNodeFile(*rootNode,"test.osg"); 
     
    522585 
    523586    // set up the SlideEventHandler. 
    524     seh->set(rootNode.get(),offsetX,offsetY,texmatLeft,texmatRight,timeDelayBetweenSlides,autoSteppingActive); 
     587    if (onDisk) seh->set(fileList,rootNode.get(),offsetX,offsetY,texmatLeft,texmatRight,radius,height,length,timeDelayBetweenSlides,autoSteppingActive); 
     588    else seh->set(rootNode.get(),offsetX,offsetY,texmatLeft,texmatRight,timeDelayBetweenSlides,autoSteppingActive); 
    525589     
    526590    osg::Matrix homePosition;