Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Can rendering be done from a thread to MainWindow process?



  • I was browsing posts about embedding a rendering engine in Qt (Ogre) and came across one where someone stated it may not be possible to render in a subthread of a Qt window, and not much more than that.

    I am trying to integrate Ogre (2.3) into a Qt window using OpenGL3+ and while I've been able to do this in the past with an older version of Ogre, I'm having difficulty with how I changed it up for 2.3. (For those familiar with the Ogre samples, I'm following tutorial 06 using a logic and rendering thread.)

    But my question is about rendering from a thread to the MainWindow. I'm running a MainWindow class derived from the QMainWindow in the main process but the QOgreWidget which is derived from QWidget is running in a thread. The main appears as follows:

    int main(int argc, char* argv[])
    {
        QApplication app(argc, argv);
    
        // ...
    
        threadHandles[0] = Ogre::Threads::CreateThread(THREAD_GET(renderThread), 0, &threadData);
        threadHandles[1] = Ogre::Threads::CreateThread(THREAD_GET(logicThread), 1, &threadData);
    
        // ...
    
        MainWindow mainWin(pgs);
        mainWin.show();
    
        while (mainWin.isRunning())
            app.processEvents();
    
        // ...
    }
    

    It all compiles and runs, but the Ogre window is white when it should be black and I'm thinking may not have initialized correctly by being in a thread. Hence my question about rendering from a threads to the main process where the MainWindow is displayed.

    Does anyone see issues here?



  • @johnby
    While you await a more specific answer from an expert, all UI stuff is to be done in one UI thread, nothing across threads, else likely problems....



  • Here's just a bit more detail in case anyone can confirm that this is the case.

    I'm wondering if this one widget (the render window) is considered "UI stuff." I am doing all the "Qt UI" stuff in the main thread, with the exception of this one class which is derived from QWidget which is being done in a thread (has it's own update() loop). My QOgreWidget class has an ogreWidget->getWindow() which returns the created rendering window and I have a handle to this in the main process.

    Just really hoping there's a way around this if this is the case. Really not wanting to run the rendering updates in the main process.

    Update:

    I did confirm that if I place my window widget (QOgreWidget) within the main thread, my canvas appears as normal and I can draw on it. Though I'd really like to be able to place the rendering window in a thread.

    Thanks for any help if possible.


  • Moderators

    @johnby said in Can rendering be done from a thread to MainWindow process?:

    I did confirm that if I place my window widget (QOgreWidget) within the main thread, my canvas appears as normal and I can draw on it. Though I'd really like to be able to place the rendering window in a thread.

    You can call Ogre functions in a separate thread. However, you must only call QWidget functions in the main thread.

    I am trying to integrate Ogre (2.3) into a Qt window using OpenGL3+

    Rather than QWidget, perhaps QOpenGLWidget or QOpenGLWindow might suit you better.

    These classes allow some operations to be done in secondary threads (read their documentation for details)


  • Lifetime Qt Champion



  • @SGaist said in Can rendering be done from a thread to MainWindow process?:

    Are you aware that Ogre3D already provide Qt integration and has even done a major update to it ?

    Yes, unfortunately, the version 1.x of Ogre is very different than the 2.x release.

    @JKSH said in Can rendering be done from a thread to MainWindow process?:

    Rather than QWidget, perhaps QOpenGLWidget or QOpenGLWindow might suit you better.

    I'm looking at QOpenGLWindow and not exactly sure how to integrate the rendering engine I'm using.

    I've done the following:
    - subclassed QOpenGLWindow.
    - overridden initializeGL(), resizeGL(), paintGL() which are all currently empty.
    - Added QSurfaceFormat and set a default format.

    What I don't understand from looking at the examples is that, I'm not making native OpenGL calls and that's how all the examples I've seen are done. Are there any examples any where's that show how to do updates from a thread?

    Here is my rendering window constructor that I've been trying to convert by subclassing with QOpenGLWindow. Am I on the right track by creating my rendering window in this way? This is sort of how I did it when subclassing from QWidget in the past.

    QOgreWindow::QOgreWindow(QWidget* parent) :
        QOpenGLWindow(parent),
        renderWindow(nullptr),
        camera(nullptr),
        cameraController(nullptr),
        timeSinceLastFrame(0.0f)
    {
        int width = 800;
        int height = 600;
    
        Ogre::String windowHandle =
            Ogre::StringConverter::toString((uintptr_t)(this->winId()));
    
        params["parentWindowHandle"] = windowHandle;
    
        renderWindow = Ogre::Root::getSingleton().createRenderWindow(
            "My Window", width, height, false, &parameters);
    }

Log in to reply