[osg-users] Frame delay when using setViewMatrix()

David Rubel derubel at gmail.com
Mon Jul 21 10:34:11 PDT 2008


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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openscenegraph.org/pipermail/osg-users-openscenegraph.org/attachments/20080721/ca46b71c/attachment-0002.htm>


More information about the osg-users mailing list