Hi,
I'm writing an OSG application which uses the Viewer class to setup/display
the SceneGraph. I'm manually updating the camera location each frame using
the setViewMatrix() function on my camera, and this seems to be introducing
a 1 frame delay into the loop (which is bad for my application). The first
time I call frame() on camera, the old camera pose is used; the second time
I call frame, it is correct again. I tried calling frame() twice in each
frame, and this solves the problem, but drawing the entire scene twice is
hardly an efficient solution. I have two osg::Image instances attached to
the camera (one reading color and the other reading the depth buffer, which
I need for my application).
I'm using OSG 2.4.0 and Visual C++ Express.
I've been searching online for this problem, but I can't find anything that
looks similar. Here is an example of the problem:
// setup viewer
viewer = new osgViewer::Viewer;
viewer->setUpViewInWindow(100,100,width,height);
viewer->setSceneData(osgModel);
viewer->getCamera()->setClearColor(osg::Vec4(1, 1, 1, 1));
viewer->getCamera()->setRenderOrder(osg::CameraNode::POST_RENDER);
viewer->getCamera()->setComputeNearFarMode(osgUtil::CullVisitor::DO_NOT_COMPUTE_NEAR_FAR);
// attach an image to the camera to be rendered each frame
osg::Image osg_image = new osg::Image;
osg_image->allocateImage(width, height, 1, GL_RGBA, GL_UNSIGNED_BYTE);
viewer->getCamera()->attach(osg::Camera::COLOR_BUFFER, osg_image);
// attach a depth image to the camera to be rendered each frame
osg::Image osg_depth = new osg::Image;
osg_depth->allocateImage(width, height, 1, GL_DEPTH_COMPONENT, GL_FLOAT);
viewer->getCamera()->attach(osg::Camera::DEPTH_BUFFER, osg_depth);
Main Loop
{
...
// update camera pose
osg::Matrixd mat = viewer->getCamera()->getViewMatrix();
mat.set(newMatrix.getArray());
viewer->getCamera()->setViewMatrix(mat);
// render the scene
viewer->frame();
// here the images are rendered using the old camera pose
viewer->frame();
// here they are correct
}
I've done some research into what the frame() function actually does, and I
divided it into separate functions and found out that renderingTraversals()
is the function that needs to be called twice. For example, this code works
as well:
...
// update camera pose
osg::Matrixd mat = viewer->getCamera()->getViewMatrix();
mat.set(newMatrix.getArray());
viewer->getCamera()->setViewMatrix(mat);
// render the scene
viewer->advance();
viewer->eventTraversal();
viewer->updateTraversal();
viewer->renderingTraversals();
// here the images are rendered using the old camera pose
viewer->renderingTraversals();
// here they are correct
}
Thanks in advance!
- David
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org