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
