Hi Martin,
The direction you're taking in the Delta3D forum thread seems to be more
of a dead end to me, since it forces Qt and OSG to run single threaded.
I haven't yet managed to get OSG and Qt running in different threads.
The osgQtBrowser example does this already (if you don't pass the
--no-frame-thread command line argument). Qt's event loop runs in the
main thread, and osgViewer runs in another (and will most likely spawn
other threads for rendering as needed since it's not hard-coded to run
single threaded in the example).
The whole interplay of windows and GL contexts and so on is new to me and
pretty confusing. Are there any running examples where a Qt widget contains an
OSG window that runs in a different thread?
Yes, osgViewerQt, osgViewerQtContext and osgViewerQtWidget. But that's a
different issue than what QWidgetImage and QGraphicsViewAdapter try to
solve...
I think the following should be documented somewhere:
----------------------------------------------
There are two angles to consider.
1. If someone wants a widget in their Qt app to be an OSG-rendered
scene, they need GraphicsWindowQt (in the osgViewerQtContext example) or
QOSGWidget (in the osgViewerQt example). These two allow both OSG and Qt
to manage their threads in a way which is optimal to them. We've used
QOSGWidget in the past and had trouble when Qt tried to overlay other
widgets over the QOSGWidget (since OSG did its rendering independently
of Qt, it would overwrite what Qt had drawn). I haven't tried
GraphicsWindowQt yet, but I expect since it uses QGLWidget, it will
result in Qt knowing when OSG has drawn and be able to do overlays at
the right time. Eventually GraphicsWindowQt can be brought into
osgViewer I imagine...
2. If someone wants to bring Qt widgets inside their OSG scene (to do
HUDs or an interface on a computer screen which is inside the 3D scene,
or even floating Qt widgets, for example). That's where
QGraphicsViewAdapter + QWidgetImage will be useful.
----------------------------------------------
As I said above, we've used QOSGWidget in the past and it works well in
some cases but not all. But our current solution based on that works
well enough for us. Now I'm focusing on the inverse problem, which I
think is actually less complicated.
I like the approach QGraphicsViewAdapter takes, since it's putting Qt's
rendering in an image and using that in the OSG scene. Since the most
performance-hungry aspect of most apps is the 3D rendering and not the
GUI rendering, it makes sense to give the most control possible to OSG.
The difficulty becomes mapping events from OSG to Qt when needed, which
was partially solved by osgViewer::InteractiveImageHandler but which I'm
also working to improve.
Next I will look at combining osg and qt with the use of frame buffers. I think
it would be less complicated to render OSG output to a frame buffer and display
that in the Qt thread. This way we can use the Qt event loop and be sure that
the mouse and keyboard events are correctly handled. Any thoughts?
This is also a dead-end, we've tried before. The problem with this
approach is that you're effectively gating all OSG rendering and forcing
it to end at some defined time, so that Qt can use the result and paint
it somewhere. This slows down OSG since it's not free to manage its
threads as it sees fit. In effect you're reversing the situation
compared to QGraphicsViewAdapter. You're letting Qt be the master and
OSG is the slave, which is the wrong approach I think, given what I said
above - the most performance-hungry aspect of most apps is the 3D
rendering and not the GUI rendering.
What is the most efficient way to get the OpenGL output of one thread into the
OpenGL scene of another thread?
I think GraphicsWindowQt solves this but I haven't checked.
Can I somehow reuse the frame buffer of one gl context in another context?
No. OpenGL resources are tied to one specific context. But you could
share a single context, but then you'd need to make sure everyone
renders at the right time (can't makeCurrent while some other thread has
the context current and is rendering), which is what I hope
GraphicsWindowQt does.
Or do I have to download the frame buffer to main mem and then re-upload it to
the graphics mem?
That would be really slow. Apart from the transfer time, which can be
pretty fast if everything is in the same format and uses DMA transfers,
it forces OpenGL to flush all its operations and your rendering thread
to wait until it's done rendering before you can grab the contents of
the frame buffer. In our testing this took about 4ms per frame
independently of the size of the scene you're rendering, so effectively
the GPU is stalled 25% of the time (if you aim for 60 fps, which we do).
Anyways, as I told Robert I'm working on the QGraphicsViewAdapter +
QWidgetImage approach currently. I'll submit the results soon I hope.
J-S
--
______________________________________________________
Jean-Sebastien Guay [email protected]
http://www.cm-labs.com/
http://whitestar02.webhop.org/
_______________________________________________
osg-submissions mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org