2013-08-20 8 views
7

多くのテクスチャをアップロードしています(1秒あたり60個のVGA画像)、UIスレッドがブロックされています。 the Qt 5.1 QGLWidget manual page(強調鉱山):QGLWidgetは別のスレッドですか?関連するドキュメントは何ですか?

スレッド内でテクスチャをアップロードしています。 スレッド内でのテクスチャのアップロードは、フォトギャラリーアプリケーションなど、大量の画像を表示する必要があるアプリケーションに非常に役立ちます。これは、既存のbindTexture()APIを介してQtでサポートされています。これを行う簡単な方法は、2つの共有QGLWidgetsを作成することです。一方はメインGUIスレッドで現在のものになり、もう一方はテクスチャアップロードスレッドで最新のものになります。 アップロードスレッドのウィジェットは表示されません。メインスレッドとのテクスチャの共有にのみ使用されます。 bindTexture()でバインドされている各テクスチャに対して、テクスチャの使用を開始できるようにメインスレッドに通知します。

何ですか? QGLWidgetなどのQWidgetベースのクラスをスレッドにどのように移動できますか?私は、ドキュメントが、私は、例えば移動するために実装示唆されているものを理解していない

QObject::moveToThread: Widgets cannot be moved to a new thread 

:そこらでこれを実行しようとするとbindTexture()のUIスレッドからの実行。

これはまた、ここに記載されていますQt4/Opengl bindTexture in separated thread

ませんコードは、しかしそこに投稿しました。

答えて

3

QGLWidgetを別のスレッドに移動しなければならないと思っていますが、これは実際にどのように行ったのか覚えていません。それは現在のことを言う:QGLWidget::makeCurrent()。これにより、QGLWidgetのOpenGLコンテキストが新しいスレッドで最新のものになります。

しかし、私はQGLContextクラスで試してみます。 QGLContextをインスタンス化し、次にQGLWidgetの1つと共有するためにQGLContext :: create()を呼び出すことができます。 QGLContextでは、テクスチャをバインドできます。

+0

イエップ。詳細はこちら[こちら](http://blog.qt.digia.com/blog/2011/06/03/threaded-opengl-in-4-8/)。また、Qt 5では、QGL *クラスではなくQOpenGL *クラスを実際に使用する必要があります。 – peppe

6

答えは少し遅れますが、ウィジェットを作成したスレッドによってウィジェットを新しいスレッドに移動する必要があります。あなたのケースでのようなもの:

QGLWidget *glWidget=new QGLWidget(); 
QThread *newThread=new QThread(); 

glWidget->doneCurrent(); 
glWidget->context()->moveToThread(newThread); 

は、ここで私は、新しいスレッドにOpenGLコンテキストを移動し、これはQGLWidgetでいくつかのオーバーライドがキャッチされ、無視されている必要があります。 QGLWidgetから新しい派生クラスを作成し、それをオーバーライドする必要があります。

virtual void glInit(); 
virtual void glDraw(); 

virtual void initializeGL(); 
virtual void resizeGL(int width, int height); 
virtual void paintGL(); 

これにより、標準UIスレッドは、UIスレッドでOpenGLコンテキストを最新にすることを試みません。上記をオーバーライドすると、いくつかのイベントが発生したことをスレッドに通知するイベントシステムが必要になります。主にresizeGlとpaintGLが必要です。そうでない場合、ウィジェットは周囲の他のユーザーと適切に反応しません。

最後の部分はQGLWidgetの作成です。構築物中のパラメータの一つは、constのQGLWidget * shareWidgetです:

QGLWidget (QWidget * parent = 0, const QGLWidget * shareWidget = 0, Qt::WindowFlags f = 0) 
QGLWidget (QGLContext * context, QWidget * parent = 0, const QGLWidget * shareWidget = 0, Qt::WindowFlags f = 0) 
QGLWidget (const QGLFormat & format, QWidget * parent = 0, const QGLWidget * shareWidget = 0, Qt::WindowFlags f = 0) 

あなたは、スレッドのGLWidgetを作成するときに確認してUI QGLWidgetとねじGLWidget(上記のオーバーライドの全てでQGLWidgetからderivided)を作成しますQGLWidgetをsharedWidgetとして提供します。これにより、2つのOpenGLが共有されたコンテキストになり、両方が見ることのできるテクスチャを読み込むことができます。私は最近、主にOpenGLの/ OpenCLの相互運用のためのネジQGLWidgetsを使用して、ほとんどの例プログラムを書いた

QGLWidget *glWidget=new QGLWidget(); 
GLWidget *threadedWidget=new GLWidget(0/*parent*/, glWidget); 
QThread *newThread=new QThread(); 

threadedWidget->moveToThread(newThread); 

コードについては、それが単一のコンテキストを共有する描画スレッドでmuliple QGLWidgetsを使用して示しています。コードは次のようになります。コードはgithubにあり、説明はこちらhttp://www.krazer.com/?p=109

+0

リンクのみの回答はお勧めしません。リンクされたリソースのいずれかが移動または削除された場合、回答は無効になります。リンクの後ろにさらに多くのコンテンツがある場合でも、回答には少なくとも主なポイントが含まれている必要があります。 –

+0

+1。リンクは推奨されませんが、これは非常に良い返答であり、私はあなたを私たちのコミュニティの一員として見たいと思っています。 – Mikhail

関連する問題