Well at long last I have met my self assigned milestone of basic Ogre3D and Qt integration! I first wrote about my intentions months ago but as it turns out I got side tracked by writing my own build system, which I did because neither premake or cmake could satisfy my requirements. I may elaborate on this project in another post but I won't do so here because of how much detail would be necessary to cover it properly. Instead I will describe the process I had to go through to finally get the integration working correctly (I suspect developing on linux made this harder than it might have been).
If you're an impatient person you can grab my final QOgreWidget source code here
The final app that I have produced is modest to say the least, but as they say; from small things big things grow :). All it does is embed an ogre renderer into a Qt widget and allow the colour of a rendered spinning cube to be changed via a Qt interface button. Though this is extremely basic, getting it to work correctly wasn't an easy process, mainly due to decayed documentation and example code that didn't work on linux.
The most pedagogical tutorial I could find for embedding Ogre inside a Qt GUI was located on the Ogre wiki here. On this page you will find source code for a fully implemented OgreWidget and links to forum topics where Linux and Mac integrations have been investigated. Sounds pretty good eh? Well unfortunately the widget didn't work for me and the other links provided have all decayed i.e. they are out of date and the source code links are all broken. The frustrating thing for me at this stage was that I had a garbled window displaying; the provided widget sort of worked but not quite. Now identifying what exactly was broken was intimidating; was it some sort of Qt widget setting? Perhaps some OpenGL buffer refresh problem? It felt like it could have been pretty much anything and I almost gave up after fruitless hours of reading documentation and twiddling values.
After much perseverance and research I came across this forum post which used a different implementation of an OgreWidget. The original example from the Ogre wiki does all of it's work in three methods inherited from QGLWidget.
virtual void initializeGL(); virtual void resizeGL(int width, int height); virtual void paintGL();
The new example dismissed these in favour of QWidget based methods
virtual void paintEvent(QPaintEvent* pEvent); virtual void resizeEvent(QResizeEvent* rEvent); virtual void update();
The implementations used inside those methods were quite similar but I suspected that perhaps my problems lay in when and how they were being called. As it turns out the crux of the problem was that Ogre wasn't being triggered to render often enough along with forcing repositioning of the Ogre window, huzzah! From there things got a lot easier and I now have a tested and working implementation of a QOgreWidget for linux (and most likely for windows too but I haven't tested it).
After getting beyond the proof of concept phase I looked at ways of improving the design of my QOgreWidget. The implementation provided on the Ogre wiki is very much prototype code, it works but it's not really flexible enough to fit into a larger application. So I shaved off excess bits and redesigned it to be decoupled from the Ogre initialisation sequence so that it could be used generically. The basic idea is that you initialise it with your pre initialised Ogre::Root object and you can then extract a pointer to the render window that is created and do whatever you want from there. For an example of what I mean by this please check out the example application code.
Anyway I would encourage you to try my code out for yourself and let me know what you think. If you have issues with it I will do my best to help you out
As requested by Xelfe I have added some framework code around the QOgreWidget to make it easier to get to grips with. The final result is the simplest initialisation of Qt and Ogre together as a GUI app that I could manage. The code should amply demonstrate how to use the QOgreWidget and as a side effect it demonstrates the simplest possible way to do your Ogre initialisation too.
Notes for building:
The detail of setting up a Qt and Ogre build environment; include paths, libraries is beyond the scope of this page, however you will need to be aware of:
* Linking both OgreMain and RenderSystem_GL from Ogre
* Doing Qt Moc'ing for QOgreWidget.hpp and QtOgreApplication.hpp