2011-08-23 7 views
5

私は、CPUよりもglでいくつかの重い計算を行っています(gl/gpuはこれまでにCPUより100倍速く近似しています)が、通常の問題サイズが用意されているので、どれくらいの時間がかかるかを知るには良いプログレスバーが必要でした。qt内のgl計算の進捗状況を表示

私はQObjectから継承するようにクラスを設定し、しばらくの間毎回放出されるシグナルcurrentProgress(int)を持っています。 残念ながら、私のプログラムは計算中にフリーズし、進行状況は見えません。 QCoreApplication::processEvents()に解決策が見つかりましたが、もう1つ問題がありました。 この呼び出し中にウィンドウ全体の再描画がトリガーされ、ペイントイベントによってトリガーされるため、計算が無限再帰で呼び出されます。

ここで、これらの問題はプログラミングの直感的なスロットに何かを間違って設計したことを伝える信号なので、qtに最新のプログレスバーを表示する方法は何ですか?

また、計算を別のスレッドにプッシュしたいときは、おそらく新しいGLコンテキストを作成するか、少なくとも既存のコンテキストを移動する必要があります。だから、それが行く方法なら、誰かがQtでこれを達成する方法を私に説明するかもしれませんか?

EDIT

私はQGLWidgetに描くが、FBOを使用していない物事をより明確にするために。 おそらく、計算には独自のコンテキストを使用するのが最善ですが、それが正しい方法であるかどうかはわかりません。

新しい情報

だから私はあなたのアドバイスに従うことをしようとしたが、問題につまずきました。 QGLContextはスクリーン/ GUIオブジェクトに接続されている必要がありますので、オフスクリーンを作成することはできません。

さらに、私はQGLWidgetを他のスレッドに流し込むことはできません。それはエラーQGLContext::makeCurrent(): Failed.を返します私がそれについて読むすべてのエントリは、私のような同じ問題を抱えた人々でした。彼らは別のスレッドでレンダリングをしたいと思っていました。

答えて

3

この呼び出し中に、ペイントイベントによってトリガーされるため、計算が無限再帰で呼び出される結果となるウィンドウ全体の再ペイントがトリガーされます。

次に、ペイントイベントで計算を開始しないでください。ウィンドウがOpenGLウィンドウ(GPGPUのものがウィンドウに表示される)の場合は、計算の間は非表示にする必要があります。それがOpenGLウィンドウでない場合は、それをリフレッシュすることで計算を呼び起こすべきではありません。

実際に描画するためにOpenGLを使用している場合を除き、オフスクリーンのレンダーターゲットを使用する必要があります。基本的には、GLウィンドウを作成し、WGL_ARB_pbuffers(またはGUIシステムに応じてGLXに相当するもの)を使用してオブジェクトを共有する新しいコンテキストを作成します。オフスクリーンのレンダーターゲットです。その後、元のウィンドウを破棄します。

スレッディングに関しては、2つのGLコンテキストがあっても1つのGPUしか持たないことを忘れないでください。したがって、OpenGLを使ってウィンドウに描画し、OpenGLで計算を行う場合は、すべてがうまくいかない場合があります。

+0

あなたは再帰について正しいですが、答えがどうなるかはわかっていましたが、それは私が求める主な理由でした。しかし、あなたが描く方法は、私にとってはまったくプラットフォームではないように思えます。私の質問で編集したので、私の計算はすべてオフスクリーンです。 – Nobody

+0

@Nobody Qtがpbuffer管理用のクラス( 'QGLPixelBuffer')を持っていると考えると、なぜプラットフォームに依存しないのでしょうか? –

+0

@Christian:Aはウィンドウ固有のwgl関数について語っています。私もQTクラスを見ましたが、スレッド内に現在のコンテキストも必要ですが、コンテキストを取得しません。 – Nobody

2

はいこれを独自のスレッドに入れることは、方法です。 QGLWidgetは以下のメンバ関数を提供します:

void QGLWidget::makeCurrent() 
void QGLWidget::doneCurrent() 

処理スレッドから適切に呼び出します。 setUpdatesEnables(false);は、通常の信号処理が再描画をトリガするのを防ぎます。

私はニュースグループからあなたを知っていますか?comp.graphics.api.opengl?そこには "誰も"活動していません。自分のプロフィールを見て、私が誰であるかを知る。

+0

それは解決策のように見える、私はそれを試してみます。しかし、私がQTに慣れていないので、私の次の質問は、どうやって計算を別のスレッドにするかです。オントロジー:私が知っている限り、私はこのニュースグループにはいませんが、私の邪悪な双子が何をしているのかを知っていますか? ^^ – Nobody

+0

@Nobody:コンストラクタ内のQGLWidgetインスタンスへのポインタを取るクラスをQTh​​readから派生させます。スレッドのrun()メンバー関数呼び出しで、glwidget-> makeCurrent();を呼び出します。あなたの処理を行い、glwidget-> doneCurrent();で終了します。 – datenwolf

+0

@Nobody:Nicol Bolasは、PBufferを使って提案しました。もしPBuffersが利用可能なら、私もそうだと思います。 – datenwolf

関連する問題