Hi Matthieu,

Try using --SingleThreded mode with your viewer. I once tried to do similar 
thing. Although in my case I was dumping color buffer.But very often I was  
reading wrong portion of the whole range. It turned out that default 
multithreading of OSG was runnig two frames concurently and one snapshot was 
overrriding the other. 

Attached you will find an code excerpt from my app. It was used to dump pseudo 
aerial photographs for some airport objects. We used these images later for 
paged terrain.

Code may not compile because I removed few specific parts. But main rendering 
loops are untouched you may use them as template for your code. 

Cheers,
Wojtek

. 
----- Original Message ----- 
  From: Matthieu DIRRENBERGER 
  To: [email protected] 
  Sent: Tuesday, September 30, 2008 3:57 PM
  Subject: [osg-users] frame control and callback


  Hello OSG users,

   

  I am a new on OSG and I have some difficulties to finish an application.

  I am trying to do an application which computes pre-calculated height-maps 
from a scene.

  Simply, I make a "draughtboard" from the scene; and a camera takes shots from 
Z-buffer for each square looking downward.

  I have done a callback function to get z-buffer and convert it to my 
convenience, but I can't control the execution of that callback function.

   

  struct MyCameraPostDrawCallback : public osg::Camera::DrawCallback

  {

        MyCameraPostDrawCallback(osg::Image* image, osg::Image* cimage, 
osg::Texture2D* t): _image(image), _cimage(cimage), _cTex(t)

      {

      }

      virtual void operator () (const osg::Camera& /*camera*/) const

      {

  .code.

   

  I use this function to init the callback in the camera settings: 
camera->setPostDrawCallback(new MyCameraPostDrawCallback(test.get(), 
zImage.get(), tex.get()));

   

  After that, I use loops to modify camera positions and take my shots (I make 
a code based on the example from OSG user guide using viewer->frame(). 

   

  for(x=0;x<nb_x;x++)

        {

              yd=-TEXT_SIZE/2;

              yf = yd+TEXT_SIZE;

   

              for(y=0;y<nb_y;y++)

              {     

                    
camera->setClearColor(osg::Vec4(0.1f,0.3f,0.3f,1.0f));//init buffer de couleur

                    camera->setClearMask(GL_COLOR_BUFFER_BIT | 
GL_DEPTH_BUFFER_BIT);//init Z-buffer

                    
camera->setProjectionMatrixAsOrtho(xd,xf,yd,yf,0.1,TEXT_SIZE);

   

                    viewer->frame();

                    

                    if(y<nb_y)

                    {

                          yd=yf;

                          yf=yf+TEXT_SIZE;

                    }

              }     

              if(x<nb_x)

              {

                    xd=xf;

                    xf=xf+TEXT_SIZE;

              }

        }     

   

  The problem is to takes a shot using the callback function for each frame 
with the new camera position.

  I thought that draw a frame should calls the Camera::DrawCallBack function, 
but it doesn't.

  I always get the last square from the loops in my images buffer (at each 
position). 

  In fact the callback function is called after the loops in spite of 
viewer->frame().

   

  Can you help me? I am not sure to use the right method.

   

  Thanks

   

  Matthieu DIRRENBERGER



------------------------------------------------------------------------------


  _______________________________________________
  osg-users mailing list
  [email protected]
  http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
#include <windows.h>
#include <osgDB/ReadFile>
#include <osgDB/WriteFile>
#include <osgUtil/Optimizer>
#include <osg/CoordinateSystemNode>
#include <osg/Geometry>
#include <osg/Geode>
#include <osg/Depth>

#include <osg/Switch>
#include <osgText/Text>
#include <osg/MatrixTransform>

#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>

#include <osgGA/TrackballManipulator>
#include <osgGA/FlightManipulator>
#include <osgGA/DriveManipulator>
#include <osgGA/KeySwitchMatrixManipulator>
#include <osgGA/StateSetManipulator>
#include <osgGA/AnimationPathManipulator>
#include <osgGA/TerrainManipulator>

#include <iostream>
#include <osg/ComputeBoundsVisitor>

osg::Vec2s winSize( 512, 512 );
osg::Vec2s winOrigin( 16, 16 );
osg::Vec2  resolution( 1, 1 );

std::string filename( "airport" );
std::string format( "tif" );

osg::ref_ptr< osg::EllipsoidModel > em = new osg::EllipsoidModel();
osg::Matrix matrix;

////////////////////////////////////////////////////////////////////////////////
struct CameraPostDrawCallback : public osg::Camera::DrawCallback
{
    CameraPostDrawCallback(osg::Image* imageTile, osg::Image* imageTotal ): 
                        _imageTile(imageTile), _imageTotal(imageTotal)
    {

    }

    virtual void operator () (const osg::Camera& camera ) const
    {
                _imageTile->readPixels( 0,
                                                                0,
                                                                
_imageTile->s(), 
                                                                _imageTile->t(),
                                                                
_imageTile->getPixelFormat(), 
                                                                
_imageTile->getDataType() );

    }
    
    osg::Image* _imageTile, *_imageTotal;
};
////////////////////////////////////////////////////////////////////////////////
int main(int argc, char** argv)
{
    // use an ArgumentParser object to manage the program arguments.
    osg::ArgumentParser arguments(&argc,argv);

    
arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName());
    
arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+"
 dumps satelite like image of 3d models.");
    
arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+"
 [options] filename ...");

        arguments.getApplicationUsage()->addCommandLineOption("-ext 
format","Set format of output image");
        arguments.getApplicationUsage()->addCommandLineOption("-name 
filename","Set the prefix to be used as output image filename");
        arguments.getApplicationUsage()->addCommandLineOption("-density 
metersPerPixel","Set the resolutiof of output image");

    arguments.getApplicationUsage()->addCommandLineOption("-h or 
--help","Display command line parameters");
    arguments.getApplicationUsage()->addCommandLineOption("--help-env","Display 
environmental variables available");
    
arguments.getApplicationUsage()->addCommandLineOption("--help-keys","Display 
keyboard & mouse bindings available");
    arguments.getApplicationUsage()->addCommandLineOption("--help-all","Display 
all command line, env vars and keyboard & mouse bindings.");

    // if user request help write it out to cout.
    bool helpAll = arguments.read("--help-all");
    unsigned int helpType = ((helpAll || arguments.read("-h") || 
arguments.read("--help"))? osg::ApplicationUsage::COMMAND_LINE_OPTION : 0 ) |
                            ((helpAll ||  arguments.read("--help-env"))? 
osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE : 0 ) |
                            ((helpAll ||  arguments.read("--help-keys"))? 
osg::ApplicationUsage::KEYBOARD_MOUSE_BINDING : 0 );
    if (helpType)
    {
        arguments.getApplicationUsage()->write(std::cout, helpType);
        return 1;
    }

    osgViewer::Viewer viewer(arguments);
    
    // report any errors if they have occurred when parsing the program 
arguments.
    if (arguments.errors())
    {
        arguments.writeErrorMessages(std::cout);
        return 1;
    }

    if (arguments.argc()<=1)
    {
        
arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION);
        return 1;
    }

        float density = 1.;
        while (arguments.read("-density",density) && density > 0 && density < 
1024 )
        {
                resolution.set( density, density );
        }

        std::string extension;
        while ( arguments.read("-ext",extension) && !extension.empty() )
        {
                if( extension[0] == '.' )
                        extension.erase( extension.begin() );

                format = extension;
        }

        std::string name;
        while ( arguments.read("-name",name) && !name.empty() )
        {
                filename = name;
        }

    // set up the camera manipulators.
    {
        osg::ref_ptr<osgGA::KeySwitchMatrixManipulator> keyswitchManipulator = 
new osgGA::KeySwitchMatrixManipulator;

        keyswitchManipulator->addMatrixManipulator( '1', "Trackball", new 
osgGA::TrackballManipulator() );
        keyswitchManipulator->addMatrixManipulator( '2', "Flight", new 
osgGA::FlightManipulator() );
        keyswitchManipulator->addMatrixManipulator( '3', "Drive", new 
osgGA::DriveManipulator() );
        keyswitchManipulator->addMatrixManipulator( '4', "Terrain", new 
osgGA::TerrainManipulator() );

        std::string pathfile;
        char keyForAnimationPath = '5';
        while (arguments.read("-p",pathfile))
        {
            osgGA::AnimationPathManipulator* apm = new 
osgGA::AnimationPathManipulator(pathfile);
            if (apm || !apm->valid()) 
            {
                unsigned int num = 
keyswitchManipulator->getNumMatrixManipulators();
                keyswitchManipulator->addMatrixManipulator( 
keyForAnimationPath, "Path", apm );
                keyswitchManipulator->selectMatrixManipulator(num);
                ++keyForAnimationPath;
            }
        }

        viewer.setCameraManipulator( keyswitchManipulator.get() );
    }

    // add the state manipulator
    viewer.addEventHandler( new 
osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) );
    
    // add the thread model handler
    viewer.addEventHandler(new osgViewer::ThreadingHandler);

    // add the window size toggle handler
    viewer.addEventHandler(new osgViewer::WindowSizeHandler);
        
    // add the stats handler
    viewer.addEventHandler(new osgViewer::StatsHandler);

    // add the help handler
    viewer.addEventHandler(new 
osgViewer::HelpHandler(arguments.getApplicationUsage()));

    // add the record camera path handler
    viewer.addEventHandler(new osgViewer::RecordCameraPathHandler);    

    // load the data
        
    osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFiles(arguments);
    if (!loadedModel) 
    {
        std::cout << arguments.getApplicationName() <<": No data loaded" << 
std::endl;
        return 1;
    }

    // any option left unread are converted into errors to write out later.
    arguments.reportRemainingOptionsAsUnrecognized();

    // report any errors if they have occurred when parsing the program 
arguments.
    if (arguments.errors())
    {
        arguments.writeErrorMessages(std::cout);
        return 1;
    }


        osg::ref_ptr< osg::DisplaySettings > ds = new osg::DisplaySettings();
    ds->setMinimumNumStencilBits( 8 );
        ds->setMinimumNumAlphaBits( 8 );
    viewer.setDisplaySettings( ds.get() );

        viewer.setThreadingModel( osgViewer::Viewer::SingleThreaded );

    // optimize the scene graph, remove redundant nodes and state etc.
//    osgUtil::Optimizer optimizer;
//    optimizer.optimize(loadedModel.get());

        loadedModel->getOrCreateStateSet()->setMode
                ( GL_LIGHTING, osg::StateAttribute::OFF | 
osg::StateAttribute::OVERRIDE );

        loadedModel->getOrCreateStateSet()->setAttributeAndModes
                ( new osg::Depth( osg::Depth::ALWAYS, 0, 1, true ) );

        loadedModel->getOrCreateStateSet()->setMode
                ( GL_CULL_FACE, osg::StateAttribute::OFF | 
osg::StateAttribute::OVERRIDE );

        loadedModel->getOrCreateStateSet()->setMode
                ( GL_CULL_FACE, osg::StateAttribute::OFF | 
osg::StateAttribute::OVERRIDE );

        viewer.setUpViewInWindow( winOrigin[0], winOrigin[1], winSize[0], 
winSize[1] );

    viewer.setLightingMode( osg::View::SKY_LIGHT );
    osg::Light * light = viewer.getLight();
    light->setAmbient( osg::Vec4( 0.6, 0.6, 0.6, 0.5f ) );

    viewer.setSceneData( loadedModel.get() );
        viewer.getCamera()->setClearColor( osg::Vec4( 0, 0, 0, 0 ) );
        
    osg::ComputeBoundsVisitor cbbv(osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN);
    cbbv.setTraversalMask(0xFFFFFFFF);
        loadedModel->accept( cbbv );

        osg::BoundingBox bb = cbbv.getBoundingBox();

        osg::Vec2 unit( winSize[0] * resolution[0], winSize[1] * resolution[1] 
);

        for( int i = 0; i < 2; i++ ) { // align to units

                bb._min[i] /= unit[i];
                bb._max[i] /= unit[i];

                if( 0.0 != modf( bb._min[i], &( bb._min[i] ) ) ) bb._min[i] -= 
1.0;
                if( 0.0 != modf( bb._max[i], &( bb._max[i] ) ) ) bb._max[i] += 
1.0;
        }

        osg::ref_ptr< osg::Image > imageTile = new osg::Image;
    imageTile->allocateImage( winSize[0],winSize[1],
                                      1, GL_RGBA, GL_UNSIGNED_BYTE );

        osg::ref_ptr< osg::Image > imageTotal = new osg::Image;
        imageTotal->allocateImage( winSize[0] * int( 0.5 + bb._max[0] - 
bb._min[0] ),
                                       winSize[1] * int( 0.5 + bb._max[1] - 
bb._min[1] ),
                                                           1, GL_RGBA, 
GL_UNSIGNED_BYTE );

//      viewer.getCamera()->setPostDrawCallback
//                      ( new CameraPostDrawCallback( imageTile.get(), 
imageTotal.get() ) );

    viewer.realize();

        osg::Matrix projection = viewer.getCamera()->getProjectionMatrix();
        osg::Matrix view = viewer.getCamera()->getViewMatrix();

        ds = viewer.getDisplaySettings();
        if( !ds->getAlphaBuffer() ) 
        {
                std::cout << "Kaszana! brak alphy w pixel formacie 
framebuffera" << std::endl;
        }

        for( float y = bb._min[1]; y < bb._max[1]; y += 1.f ) {
                if( viewer.done() ) break;

                for( float x = bb._min[0]; x < bb._max[0]; x += 1.f ) {
                        if( viewer.done() ) break;

                        viewer.advance();

                        viewer.eventTraversal();
                        viewer.updateTraversal();
                
                        viewer.getCamera()->setViewMatrixAsLookAt
                                ( osg::Vec3( x * unit[0], y * unit[1], 1000 ),  
                                  osg::Vec3( x * unit[0], y * unit[1], 0 ), 
                                  osg::Vec3( 0, 1, 0 ) );

                        viewer.getCamera()->setProjectionMatrixAsOrtho
                                ( 0, unit[0], 0, unit[1], 10, 2000 );

                        viewer.renderingTraversals();

/*
                        char ac[ 256 ];
                        sprintf( ac, "%s_x_%d_%d_y_%d_%d.png", filename, 
                                        int( x * unit[0] ), int( (x+1) * 
unit[0] ),
                                        int( y * unit[1] ), int( (y+1) * 
unit[1] ) );

                        osgDB::writeImageFile( *imageTile, ac );
*/
                        // copy tile image
                        int column = winSize[0] * int( x - bb._min[0] + 0.5 );
                        int row = winSize[1] *  int( y - bb._min[1]  + 0.5 );
        
                        imageTile->readPixels( 0,
                                        0,
                                        imageTile->s(), 
                                        imageTile->t(),
                                        imageTile->getPixelFormat(), 
imageTile->getDataType() );

                        for( int j = 0; j < winSize[1]; j ++ )
                                memcpy( imageTotal->data( column, row + j ),
                                            imageTile->data( 0, j ), 
imageTile->getRowSizeInBytes() );
                
                }
        }

//      viewer.setDone( true );

        char ac[ 256 ];
        sprintf( ac, "%s_x_%d_%d_y_%d_%d.%s", filename.c_str(), 
                int( bb._min[0] * unit[0] ), int( bb._max[0] * unit[0] ),
                int( bb._min[1] * unit[1] ), int( bb._max[1] * unit[1] ),
                format.c_str() );

        osgDB::writeImageFile( *imageTotal, ac );

        viewer.getCamera()->setProjectionMatrix( projection );
        viewer.getCamera()->setViewMatrix( view );
        viewer.run();

#ifdef _DEBUG
    TerminateProcess( GetCurrentProcess(), 0);
#endif
}
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to