2 つの QGLWidget を使用します。1 つはテクスチャの読み込み用、もう 1 つはレンダリング用ですが、機能していません。
http://blog.qt.digia.com/blog/2011/06/03/threaded-opengl-in-4-8/から次の説明を使用しました
テクスチャのアップロード スレッド 多くの (または大きな) テクスチャのアップロードは、GPU に大量のデータがプッシュされるため、通常は負荷の高い操作です。繰り返しますが、これはメイン スレッドを不必要にブロックする操作の 1 つです。4.8 では、共有 QGLWidget のペアを作成することで、この問題を解決できます。ウィジェットの 1 つが別のスレッドで現在の状態になりますが、画面に表示されることはありません。メイン スレッドは、アップロードする画像をアップロード スレッドに通知します。アップロード スレッドは、これらの各画像に対して bindTexture() を呼び出すだけで、各画像が終了するとメイン スレッドに通知し、画面に描画できるようにします。
Qt 4.8 と MinGW では正常に動作しますが、現在は Qt 5.1 と MSVC を使用しています。スレッド内のウィジェットを最新にしたいときにエラーが発生します。
別のスレッドで QOpenGLContext を最新にすることはできません
エラーは理解できますが、どうすれば修正できますか。ウィジェットを現在に設定しないと、テクスチャをロードできません (bindTexture() 関数でフリーズします)。また、なぜ私の古い QT バージョンで動作するのか疑問に思っています。エラーが表示されたら、「エラーを無視する」を押すと、プログラムはとにかくテクスチャをロードします。
サンプルコードは次のとおりです。
テクスチャを読み込んでいます:
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);
}
編集:
myTextureWidget のコンテキストをスレッドに移動すると動作しますが、GUI がビルドされるときに API から makeCurrent エラーが発生します (スタック トレースは QT5Widgetsd の QLineEdit::setPlaceHolderText 関数で述べられています)。メインウィンドウが表示されてから数秒後に myTextureWidget をスレッドに移動すると、すべて正常に動作します。しかし、qt がすべての GUI 構築作業をいつ終了したかをどのように知ることができますか? QGLWidget ビューポートを使用して QGraphicsView に GUI を描画します。
myTextureWidget->context()->moveToThread(myTextureLoadingThread);