Page 1 of 1

[2.1] Rendering Ogre 2.1 in a Qt widget using SDL

Posted: Wed Sep 21, 2016 4:35 am
by lambrtz
I am trying to render Ogre 2.1 in a Qt widget using SDL. My project builds upon one of the examples provided in Ogre 2.1.
My problem is that the widget does not render Ogre, although mRoot->renderOneFrame() is called.

The original example contains the following lines in GraphicsSystem.cpp.

Code: Select all

mSdlWindow = SDL_CreateWindow(
            windowTitle.c_str(),    // window title
            posX,               // initial x position
            posY,               // initial y position
            width,              // width, in pixels
            height,             // height, in pixels
            SDL_WINDOW_SHOWN
              | (fullscreen ? SDL_WINDOW_FULLSCREEN : 0) | SDL_WINDOW_RESIZABLE );
Then, the widget is initialised as follows.

Code: Select all

m_pRenderer = new OgreRenderer(ui.centralwidget);
m_pRendererWidget = QWidget::createWindowContainer(
    m_pRenderer,
    ui.centralwidget);
m_pRendererWidget->resize(ui.centralwidget->size());
m_pRenderer->Initialize();
OgreRenderer is responsible to render the Ogre scene. ui.centralwidget is a QFrame. I also implemented the resizeEvent and showEvent functions.
This renders an empty Ogre scene with a blue skybox in a separate window, as shown below.
Image

Now I want to render the scene in the same window. Based on this tutorial, I changed those lines to the following.

Code: Select all

mSdlWindow = SDL_CreateWindowFrom((void*)widget->winId());
As shown below, this doesn't render anything in the top widget. After resizing the window, some parts of the bottom widget is also rendered in the top widget.
Image

So is there any way I can debug this to find what is wrong with the code? Please let me know if I need to give more information. If there is another way to render Ogre 2.1 in Qt, I am also happy to hear.
I use Qt 5.7, Visual Studio 2015, Windows 8.1.
Thank you.

Re: [2.1] Rendering Ogre 2.1 in a Qt widget using SDL

Posted: Wed Sep 21, 2016 12:37 pm
by dark_sylinc
Are you creating a compositor workspace? It is required for rendering.

You may want to take a look at https://github.com/spookyboo/HLMSEditor as it uses Qt for the UI as well. It may give you some ideas.

Cheers

Re: [2.1] Rendering Ogre 2.1 in a Qt widget using SDL

Posted: Wed Sep 21, 2016 6:04 pm
by lambrtz
dark_sylinc wrote:Are you creating a compositor workspace? It is required for rendering.
There is this function:

Code: Select all

Ogre::CompositorWorkspace* GraphicsSystem::setupCompositor(void)
which in the initialisation is called like this:

Code: Select all

mWorkspace = setupCompositor();
So I suppose the compositor is already created?
dark_sylinc wrote:You may want to take a look at https://github.com/spookyboo/HLMSEditor as it uses Qt for the UI as well. It may give you some ideas.
Thank you! I saw the screenshot and it looks like something that I want to achieve. I will take a look at it. :)

Re: [2.1] Rendering Ogre 2.1 in a Qt widget using SDL

Posted: Wed Sep 21, 2016 7:45 pm
by spookyboo
Or.. take a look at https://github.com/spookyboo/Magus_bin
This is an editor that can generate a Qt application with 1..n Renderwindows for you. It support Ogre 1.9, 2.0 and 2.1

Re: [2.1] Rendering Ogre 2.1 in a Qt widget using SDL

Posted: Thu Sep 22, 2016 7:23 am
by lambrtz
spookyboo wrote:Or.. take a look at https://github.com/spookyboo/Magus_bin
This is an editor that can generate a Qt application with 1..n Renderwindows for you. It support Ogre 1.9, 2.0 and 2.1
Thank you spookyboo, I'll take a look at it too. :)

Re: [2.1] Rendering Ogre 2.1 in a Qt widget using SDL

Posted: Mon Jul 22, 2019 10:05 pm
by blacdard
spookyboo wrote: Wed Sep 21, 2016 7:45 pm Or.. take a look at https://github.com/spookyboo/Magus_bin
This is an editor that can generate a Qt application with 1..n Renderwindows for you. It support Ogre 1.9, 2.0 and 2.1
I know this is a tad old, but I've got a question about the Qt applications the Magus program generates. (by the way, thanks for that. It does a great job of showing what is minimally required for adding Ogre to a Qt Widgets application)

The generated code uses a main() that does something slightly odd. Instead of just calling app.exec(), it's got a loop that processes Qt events, runs the Ogre update, waits 10 ms and repeats. The Ogre update happens outside the Qt event loop.

This highly implies there's some issue with running Ogre updates from within the Qt event loop... but converting the update() call to a slot and calling it from a QTimer event seems to work.

Is there a specific issue or issues that the Magus generator is trying to get around by updating Ogre outside of the Qt event loop? Maybe I just haven't run into it yet?

Re: [2.1] Rendering Ogre 2.1 in a Qt widget using SDL

Posted: Wed Jul 24, 2019 3:01 am
by dark_sylinc
Hi!

I don't know the exact reasons spookyboo went for that choice, he may know better. Maybe there's no particular reason.

In my experience when drawing inside the UI toolkits' event loop, UI toolkits in general (not talking Qt specifically) can:
  • Raise OpenGL commands that conflict with us (note Qt may be compiled w/ and w/out GL support, thus SDK flavour has an impact)
  • Works fine in one OS, breaks on another OS (or different drivers, or even different version of that OS)
  • Has unreliable timing (extremely variable framerate, e.g. from 60 fps to 1 fps)
  • Breaks or becomes too unpredictable if rendering takes too long (e.g. using a timer of 60hz but your app takes much longer than 16.67ms; knowing what happens with missed events is important: will Qt attempt to call all of raised events and queue them up until it runs out of memory? will it just skip them?)
  • Occasionally issues two timer events before the same WM_PAINT event (that's bad). Usually related to the previous point.
  • Breaks on weird resizing events (when the app decides to increase its window size, but then the OS decides it has to be clamped)
  • Breaks on particular UI focus events
Sometimes it just works ok all the time. Your mileage can vary a lot here.
Implementation details matter a lot, and that can vary per OS, Desktop Environment used (e.g. GNOME vs KDE), SDK flavour, how long your code takes, the toolkit's version used, etc.
Which is why running your loop outside Qt's loop is a way of ensuring there are no implementation details that can mess with you.

Cheers