Ryan McDougall wrote:
> On Mon, Oct 19, 2009 at 3:14 PM, Thiago Macieira
> <[email protected]> wrote:
>> Em Segunda-feira 19 Outubro 2009, às 13:12:19, você escreveu:
>>> Thank you for such a detailed answer! However, one of the selling
>>> points of using a rendering engine instead of raw OpenGL is that your
>>> game is written entirely in high-level terms, and as such never
>>> depends on the underlying libraries such as OpenGL and D3D.
>>>
>>> So on windows, Ogre would be using the D3D layer to draw, and one
>>> Linux it'd be OGL.
>> You need to find the highest common denominator between Qt and Ogre3D to
>> integrate. Unless Ogre integrates with Qt or Qt integrates with Ogre, you 
>> need
>> to find something that both have in common in order to coordinate.
>>
>> OpenGL is a good way, because it's cross-platform. Qt does not use D3D, so 
>> you
>> can't get a D3D context out of a Qt widget.
>>
>> If Ogre is using D3D and Qt is not, you probably need to go even one layer
>> down, to Win32 HWND handles or something similar.
>>
> 
> The way the code that I attached works is:
> 
> 1. Ogre steals a window at the win32/X11 level, and draws itself on
> request whenever GraphicsScene::drawBackground is called
> 2. Qt draws itself via a GraphicsView all other times
> 
> It works well except for flickering.
> 
> If the only means of removing flicker is via OpenGL (or win32 --
> nooo!) then so be it...

What kind of flickering are you seeing? I'm quite surprised that this 
works without going the QGLWidget route actually.

The problem is that Qt doesn't expect anyone else to paint to its 
windows. First of all Qt is double buffered, so whatever Qt paints will 
first go to an offscreen buffer, and then it will be flushed to the 
window when the window has been updated or when the window manager 
requests an update. Thus, if Ogre renders directly to the window Qt will 
probably just overwrite it (at least the parts of the window that have 
been updated through Qt).

The robust ways to solve this would be:

a) Make Ogre render into an offscreen OpenGL or Direct3D surface and 
then somehow blit the surface onto Qt's offscreen buffer in 
QGraphicsView::drawBackground(), either using QPainter::drawImage() 
(which would require transferring the surface to system memory which 
will probably be very costly).

b) Make Ogre render into an offscreen OpenGL surface, use a QGLWidget 
viewport on the graphicsview (somehow making the QGLWidget shared with 
the context that Ogre uses, this requires that Ogre exposes its OpenGL 
context, or that you first create the QGLWidget and make Ogre be shared 
with its context), and then rendering the texture to the QGLWidget back 
buffer by drawing a texture in QGraphicsView::drawBackground(), 
surrounded by QPainter::beginNativePainting() and 
QPainter::endNativePainting().

c) Make Ogre render directly into the QGLWidget's back buffer in 
QGraphicsView::drawBackground().

d) Make Qt render the graphicsview into a semi-transparent QImage, 
disabling Qt from trying to update the window by using the 
Qt::WA_UpdatesDisabled window flag and possibly Qt::WA_PaintOnScreen to 
disable Qt's double buffering completely. Upload the QImage as a texture 
to OpenGL or Direct3D, and render it as a semi-translucent 
screen-covering texture as the final step in Ogre's rendering. This is 
also potentially slow as it requires rendering to an image and uploading 
it as a texture the size of the window every frame. You might be able to 
limit the repaint / upload to a sub-rectangle by overriding 
QGraphicsView::drawBackground() and keeping track of which rectangles 
need repainting (the second argument to drawBackground() is the exposed 
rectangle).

Since Direct3D is only possibly using a) and d), which seem to be the 
least attractive from the performance perspective, forcing Ogre to use 
OpenGL looks like the best option.

--
Samuel
_______________________________________________
Qt4-preview-feedback mailing list
[email protected]
http://lists.trolltech.com/mailman/listinfo/qt4-preview-feedback

Reply via email to