Rendering to a QGLWidget from a QThread - makeCurrent fails [solved]
Hi there,
I'm currently writing a Qt4 GUI for an emulator and need to offload the rendering of a QGLWidget to a separate QThread. The reason for this is that since our GPU emulation is using OpenGL for rendering, we'd have to run emulation on the GUI thread, which is kinda awkward. I don't want to restructure the underlying emulator code (especially since it's supposed to be toolkit-independent) to avoid this (if that's even possible), so I figured the best way would be to leave the GUI thread as it is and let the emulation run on a separate QThread.
This article suggests that this idea should be perfectly feasible. However, when I'm trying to implement it like described in the article, I get an "QGLContext::makeCurrent(): Failed." error whenever I'm calling glwidget->makeCurrent() from the QThread (glwidget->context()->isValid() returns true though). I've tried coding a minimal application that will test the implementation, and it also outputs makeCurrent errors:
Code:
#include <QtGui>
#include <QtOpenGL>
#include <X11/Xlib.h>
class MyGLWidget;
{
public:
MyThread(MyGLWidget* _glw);
void run();
private:
MyGLWidget* glw;
};
{
public:
MyGLWidget
(QWidget* parent
= NULL);
void start_rendering() { thread.start(); }
private:
MyThread thread;
};
MyThread::MyThread(MyGLWidget* _glw) : glw(_glw) {}
void MyThread::run()
{
while(1) {
glw->makeCurrent(); // error
glClear(GL_COLOR_BUFFER_BIT);
glw->swapBuffers();
glw->doneCurrent();
}
}
int main(int argc, char* argv[])
{
QCoreApplication::setAttribute(Qt
::AA_X11InitThreads);
// or just XInitThreads();
MyGLWidget* glw = new MyGLWidget(&win);
win.setCentralWidget(glw);
win.show();
glw->start_rendering();
return app.exec();
}
Note that I'm running this on an openSUSE Linux system right now. I haven't had a chance to test it on a Windows machine, yet, but will do so once I get a chance.
Anyway, I would be REALLY thankful if anyone could help me out with this one, I've spent so many hours on this already without finding a solution. Thanks in advance!
Re: Rendering to a QGLWidget from a QThread - makeCurrent fails
I just solved the problem.
For reference, I thought it wasn't necessary to overload the paintEvent and resizeEvent methods in QGLWidget. However, you need to do that because otherwise QGLWidget will internally keep calling makeCurrent, thus causing the makeCurrent calls in the QThread to fail.
Re: Rendering to a QGLWidget from a QThread - makeCurrent fails
I just registered to say Thank you, No info anywhere that it NEEDS to be overloaded, even in documentation, so frustrating to find it only after so many hours of search.