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