Threaded OpenGL mit gemeinsam genutzten QGLWidgets-Problemen mit Qt 5.1

Ich benutze zwei QGLWidgets. Eine zum Laden von Texturen und eine zum Rendern, aber es funktioniert nicht.

Ich habe die folgende Erklärung aushttp://blog.qt.digia.com/blog/2011/06/03/threaded-opengl-in-4-8/

Thread zum Hochladen von Texturen Das Hochladen vieler (oder großer) Texturen ist in der Regel ein teurer Vorgang, da die Datenmenge auf die GPU übertragen wird. Auch dies ist einer der Vorgänge, die Ihren Hauptthread unnötig blockieren können. In 4.8 können Sie dieses Problem lösen, indem Sie ein Paar freigegebener QGLWidgets erstellen. Eines der Widgets wird in einem separaten Thread auf den neuesten Stand gebracht, jedoch nie auf dem Bildschirm sichtbar gemacht. Der Haupt-Thread informiert den Upload-Thread darüber, welche Bilder hochgeladen werden sollen, und der Upload-Thread ruft einfach bindTexture () für jedes dieser Bilder auf und benachrichtigt dann den Haupt-Thread, wenn jedes fertig ist, damit es auf dem Bildschirm angezeigt werden kann.

Mit Qt 4.8 mit MinGW funktioniert es gut, aber jetzt verwende ich Qt 5.1 mit MSVC. Ich erhalte eine Fehlermeldung, wenn ich das Widget im Thread aktuell machen möchte:

QOpenGLContext kann nicht in einem anderen Thread als aktuell festgelegt werden

Ich verstehe den Fehler, aber wie kann ich ihn beheben? Wenn ich das Widget nicht auf aktuell stelle, kann ich keine Texturen laden (eingefroren bei der Funktion bindTexture ()). Ich frage mich auch, warum es mit meiner alten QT-Version funktioniert. Wenn der Fehler auftritt, kann ich "Fehler ignorieren" drücken und das Programm lädt die Texturen trotzdem.

Hier ist ein Beispielcode:

Laden von Texturen:

GLContext::GLContext(QWidget *parent, QGLWidget *myDisplayWidget) :
  QGLWidget(parent,myDisplayWidget)
{
}

...

GLContext* myTextureWidget = new GLContext(this,myDisplayWidget);

...

void TextureLoadingThread::run()
{    
    makeCurrent(); //Here is the bug!
    QImage *im = new QImage(filename);
    GLuint textid = myTextureWidget->bindTexture(*im, GL_TEXTURE_2D, GL_RGBA);
}

BEARBEITEN:

Wenn ich den Kontext des myTextureWidget in den Thread verschiebe, funktioniert es, aber dann erhalte ich den makeCurrent-Fehler von der API, wenn die GUI erstellt wird (der Stack-Trace, der bei der QLineEdit :: setPlaceHolderText-Funktion in QT5Widgetsd angegeben wurde). Wenn ich das myTextureWidget einige Sekunden nach dem Anzeigen des Hauptfensters in den Thread verschiebe, funktioniert alles einwandfrei. Aber woher soll ich wissen, wann die GUI-Erstellung abgeschlossen ist? Ich zeichne die GUI zu einem QGraphicsView mit einem QGLWidget-Ansichtsfenster.

myTextureWidget->context()->moveToThread(myTextureLoadingThread);

Antworten auf die Frage(2)

Ihre Antwort auf die Frage