Wątkowy OpenGL ze współdzielonym problemem QGLWidgets z Qt 5.1
Używam dwóch widgetów QGLWidgets. Jeden do ładowania tekstur i jeden do renderowania, ale nie działa.
Użyłem następującego wyjaśnieniahttp://blog.qt.digia.com/blog/2011/06/03/threaded-opengl-in-4-8/
Wątek do przesyłania tekstur Przesyłanie wielu (lub dużych) tekstur jest zwykle kosztowną operacją ze względu na ilość danych przesyłanych do GPU. Ponownie, jest to jedna z tych operacji, które mogą niepotrzebnie blokować główny wątek. W 4.8 można rozwiązać ten problem, tworząc parę współdzielonych widgetów QGLWidgets. Jeden z widżetów jest wyświetlany w osobnym wątku, ale nigdy nie jest widoczny na ekranie. Główny wątek informuje przesyłający wątek, które obrazy do przesłania, a wątek przesyłający po prostu wywołuje bindTexture () na każdym z tych obrazów, a następnie powiadamia główny wątek, gdy każdy z nich się skończy, więc można go narysować na ekranie.
Z Qt 4.8 z MinGW działa dobrze, ale teraz używam Qt 5.1 z MSVC. Pojawia się błąd, gdy chcę, aby widget był obecny w wątku:
Nie można utworzyć QOpenGLContext prądu w innym wątku
Rozumiem błąd, ale jak mogę to naprawić. Kiedy nie ustawiam aktualnego widżetu, nie mogę załadować tekstur (zamrożone przy funkcji bindTexture ()). Zastanawiam się także, dlaczego działa z moją starą wersją QT. Gdy pojawi się błąd, mogę nacisnąć „ignoruj błąd”, a program i tak załaduje tekstury.
Oto przykładowy kod:
Ładowanie tekstur:
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);
}
EDYTOWAĆ:
Kiedy przenoszę kontekst myTextureWidget do wątku, który działa, ale wtedy otrzymuję błąd makeCurrent z API, gdy GUI się zbuduje (ślad stosu powiedział w funkcji QLineEdit :: setPlaceHolderText w QT5Widgetsd). Kiedy przenoszę myTextureWidget do wątku kilka sekund po pokazaniu okna głównego, wszystko działa poprawnie. Ale skąd mam wiedzieć, kiedy qt zakończył tworzenie rzeczy w GUI? Rysuję GUI do QGraphicsView z rzutnią QGLWidget.
myTextureWidget->context()->moveToThread(myTextureLoadingThread);