[osg-users] Introducing osgViewer::Renderer
Robert Osfield
robert.osfield at gmail.com
Thu Aug 2 04:38:03 PDT 2007
Hi All,
Over the last six months I've hinted occasionally at refactoring the
way that rendering is managed in osgViewer to allow better access and
control over things like the internal SceneViews used to do rendering.
I didn't know exactly how it should pan out, but yesterday rolled my
sleeves up and coded up an implementation which is now checked into
osgViewer.
For the most part I expect users to be able to just svn update rebuild
and have app just run as they did before, with just the internal
implementation details changing. A few users that dig a little deeper
into the implementation details will find a few changes. Some parts
aren't complete yet - for instance the
CullThreadPerCameraDrawThreadPerContext currently hangs on a lock,
something I'm looking into. However, save for a few glitches things
should work just as before.
The real value in the new osgViewer::Renderer is that it provides a
public interface for the rendering implementation that the Viewer's
Camera's use to render there scenes. When you add a Camera to a
View(er) a Renderer is automatically assigned to it, and then when
each GraphicsContext is drawn each Camera assigned to context will
have their Renderer called. You can get the Renderer assigned to a
Camera via:
osgViewer::Renderer* renderer =
dynamic_cast<osgViewer::Renderer*>(camera->getRenderer());
Note the dynamic_cast is required as Camera::s/getRender() has a
generic osg::GraphicsOperation reference, and doesn't actually know
about the Renderer subclass that is provided by osgViewer - it can't
because osgViewer is above core osg in the dependency chain.
Once you have the Renderer you can get the SceneView from it. Note
there is present two SceneView in each Renderer to enable it support
double buffering of the rendering backend. Only the first SceneView
is used when in SingleThreaded or CullDrawThreadPerContext.
We'll be able to add further public interfaces into Renderer as time
goes on, something that wasn't possible with the previous approach as
all the GraphicsOperation implementations doing the rendering were
hidden inside the Viewer.cpp and CompositeViewer.cpp. Another benefit
is that both Viewer and CompositeViewer now shared exactly the same
Renderer class, and thereby reduces the code footprint, and opens the
door for adding more of Viewer's stats and threading models into
CompositeViewer - this work isn't complete yet, but the door is now
open.
Another side affect of these changes are that Viewer/CompositeViewer
no longer need to set up the rendering operations for you via the
setUpRenderingSupport() methods, as the Renderer can now be
automatically cloned by osgView::View when you add new Camera, and in
your own code you can also directly assign the Renderer to the Camera
you want to add directly to a GraphicsContext. The later approach is
what the StatsHandler and HelpHandler do - they now add the Renderer
in rather than call setUpRenderingSupport().
The Viewer/CompositeViewer::setUpRenderingSupport() method has also
been removed as it no longer has a role in managing the viewers, as
more is now done automatically - if you used it before such as when
removing views or adding cameras you should be able to simple delete
this line now.
One thing you do still need to be mindful of when adding and removing
views and cameras is the threading side - you still need to
stopThreading before adding/removing Views/Camera as barriers still
need to be managed appropriately. Longer term I may be add some
controls in the the View class to handle this for you, but right now
you'll need to mindful.
Robert.
More information about the osg-users
mailing list