Successfully Integrating Qt and Ogre3D

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

integrated app displaying a green cube

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 Journey

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 :)

Update 04/07/2012:
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

FacebookTwitterGoogle+RedditDeliciousLinkedInEvernoteSlashdot

15 Responses to “Successfully Integrating Qt and Ogre3D”


  1. >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

    Actually you could achieve it without reinventing the wheel :)

    Premake is very easy to extend, and now supports building Qt projects: http://industriousone.com/topic/full-stack-qt-based-development-premake-available-download

    If you miss some features, don’t hesitate to show up on our forum or mailing list – we’ll consider implementing them.

    annulen
    January 27th, 2012
    • Hey Annulen, you are right that reinventing the wheel is not always the best idea, but in this case I feel I did my due diligence. I actually spent a couple of months with both premake and cmake trying to get them to do the things that I wanted. In the end I decided that trying to make a square peg fit in a round hole was too frustrating so I elected to write one myself that would do exactly what I wanted.

      With premake specifically I engaged through the forum (starkos was very helpful) and helped get a broken implementation of what I wanted into version 4.3 (I think). Check out the forum topic I raised if you want more detail.

      radman
      January 29th, 2012
  2. My environnment is all setting for Qt and Ogre but I dont figure out how to use your QOgreWidget. Any main.cpp to share ?

    Xelfe
    June 10th, 2012
    • Hi Xelfe, as requested I have updated the page and supplied a main.cpp and additional framework code to show the QOgreWidget used in the context of a wider application. Hope you find it helpful.

      radman
      July 4th, 2012
  3. well I tried to create a qt creator project file, but I wasn’t able to link it correctly:

    I created a link:
    sudo ln -s /usr/lib/x86_64-linux-gnu/OGRE-1.7.4/RenderSystem_GL.so /usr/lib/libRenderSystem_GL.so

    project file:

    QT += core opengl

    TARGET = CMD

    unix {

    INCLUDEPATH += /usr/include/OGRE \
    /usr/include/OIS

    LIBS += -L/usr/lib/ \
    -lRenderSystem_GL \
    -lOgreMain \
    -lOIS

    }

    TEMPLATE = app

    SOURCES += \
    QtOgreApplication.cpp \
    QOgreWidget.cpp \
    most_basic_main.cpp
    HEADERS += \
    QtOgreApplication.hpp \
    QOgreWidget.hpp

    resulting error:

    g++ -Wl,-O1 -Wl,-rpath,/home/stvo/QtSDK/Desktop/Qt/474/gcc/lib -o CMD QtOgreApplication.o QOgreWidget.o most_basic_main.o moc_QtOgreApplication.o moc_QOgreWidget.o -L/home/stvo/QtSDK/Desktop/Qt/474/gcc/lib -L/usr/X11R6/lib -L/usr/lib/ -lRenderSystem_GL -lOgreMain -lOIS -lQtOpenGL -lQtGui -lQtCore -lGLU -lGL -lpthread
    QtOgreApplication.o: In function `rad::QtOgreApplication::QtOgreApplication()’:
    QtOgreApplication.cpp:(.text+0xe0): undefined reference to `Ogre::GLPlugin::GLPlugin()’

    ivanhoe
    September 24th, 2012
    • Hi Ivanhoe,

      What you have there looks correct to me, link order is correct and your linking the correct libraries. Without additional info I can’t really speculate further. With that said the ‘ undefined reference to `Ogre::GLPlugin::GLPlugin()’ ‘ is referencing the constructor for GLPlugin and should be included in the RenderSystem_GL.so. Specifically the file “OGRE/RenderSystems/GL/OgreGLPlugin.h” and the corresponding cpp file. The only other difference I can see is that I am statically linking while you are going the dynamic route. Hope that helps.

      radman
      October 28th, 2012
  4. Greetings!

    Nice and very useful post. You saved a lot of my time. Deep googling in Ogre3D forum was not successful and your post made my day.

    I’m getting “invalid drawable” during Ogre::RenderWindow creation. Here is a snippet: http://pastebin.com/pGJ8Yepe

    Ievgen
    November 9th, 2012
    • Hi there Ievgen, I had a look at the code that you posted on pastebin and it doesn’t look like you are using my QOgreWidget at all. It looks like your having a Mac platform Ogre initialisation problem and you would be better off asking your question of an Ogre expert (which I am not). Glad you found the article useful and I hope you find a solution to your ‘Invalid Drawable’ problem.

      radman
      November 10th, 2012
  5. Wonderful!

    I got it all working.

    I was wondering how to put ogrewidget in the verticle layout? I tried the technique explained here (http://blog.lugru.com/2009/03/qtdesigner-and-qglwidget/) but then my screen just become transparent and does not draw anything.

    I haven’t seen the source code for the app you mentioned at the beginning of the post. I see you also managed to put the ogrewidget in layout or separate widget (other than central widget) and nice button on right side.

    Is it possible to share that code or can you give me some hint? on how to position the ogrewidget on layout

    Thanks

    rony s
    December 6th, 2012
    • Hi there,

      I have been using QT creator as my IDE so I did the creation of the interface for the demo app in the GUI interface tool. This is essentially the same as the standalone QT designer app. If I recall right I made the layout without the QtOgre widget to begin with and then in the initialisation code I programmatically added it as the centre widget of the layout, in the same way you can add any type of widget. Let me know if you need further detail and I’ll see if I can dig up a source code example.

      radman
      December 13th, 2012
  6. I am also using the QTDesigner for my UI. I tried it in several ways but it only works when we use setCentralWidget function…
    this->setCentralWidget(ogreWidget_);…

    if we try to add this ogrewidget in layout it does not work. such as ..this->ui->verticalLayout->addWidget(ogreWidget_);…

    I have also tried changing the attribute of the window to …
    setAttribute(Qt::WA_PaintOnScreen,true);
    setAttribute(Qt::WA_NoBackground);

    but nothing helped looks like there is some background update problem as mentioned here ..http://www.ogre3d.org/forums/viewtopic.php?p=345823

    could you please share your code, it will really help me to design the gui around my ogrewidget.

    thanks

    rony s
    December 16th, 2012
    • Hi rony,

      I’ve had a look over my code and have found that I have only ever used the OgreWidget with the setCentralWidget() method. I wouldn’t have thought adding it in a different location would have been a problem and unfortunately I don’t have any additional information for you about it. I may update later when I’ve had a chance to test more. Best of luck.

      radman
      January 22nd, 2013
  7. Great article! I loved reading about the journey just as much as looking at the beautifully documented code :)

    Richard Flood
    October 15th, 2013
  8. Thanks for the class and sample code. I’m beginning with Ogre on Linux.

    I’m trying to build your sample framework application: http://www.radmangames.com/wordpress/wp-content/uploads/2011/12/BasicQtOgreApp.zip

    I’m on Fedora 20 (64bit). I installed ogre from Fedora’s packaging system.

    When I build, I get “undefined reference to Ogre::GLPlugin::GLPlugin()” from QtOgreApplication.cpp:24.

    In my pro file, I have:
    LIBS += -lOgreMain -lOIS

    After getting this problem, as described in a comment above, I created a symlink for RenderSystem_GL.so and specified that too in LIBS. But there’s no improvement.

    Any ideas?

    Syam
    January 11th, 2014
    • Hi Syam,

      What you are encountering is a build system problem and as such I can’t give a specific solution that is not already contained in the tutorial. However, be aware that an “undefined external” error means that the declaration for the call has been found in the headers being included but not in any object file. This indicates that RenderSystem_GL is not being linked correctly. From here you have to test as you normally would from a point like this and double check your assumptions. As one example; verify that RenderSystem_GL is being linked by renaming it (you should get a missing library error). Best of luck, build systems can be tricky and annoying things :)

      radman
      January 12th, 2014

Leave a Comment