1

別のスレッドで glReadPixels を呼び出すと、データが返されません。呼び出しスレッドで新しいコンテキストを作成し、メモリをコピーする必要があることを示唆するどこかを読みました。これをどのように正確に行うのですか?

これは私が使用する glReadPixels コードです:

pixels = new BYTE[ 3 * width * height];
glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels);
image = FreeImage_ConvertFromRawBits(pixels, width, height, 3 * width, 24, 0xFF0000, 0x00FF00, 0x0000FF, false);
FreeImage_Save(FIF_PNG, image, pngpath.c_str() , 0);

または、別のコードを使用するよう提案しているこのスレッドを読みましたが (最後を参照)、origX、origY、srcOrigX、srcOrigY とは何かわかりません。

4

3 に答える 3

4

共有コンテキストを作成すると、意図したとおりに機能します。参照してくださいwglShareLists(名前の選択が不適切です。単なるリスト以上のものを共有しています)。または、WGL_ARB_create_contextコンテキストの共有も直接サポートする を使用します (質問「ウィンドウ」にタグを付けましたが、非 WGL にも同様の機能が存在します)。

ただし、代わりにピクセル バッファ オブジェクトを使用する方がはるかに簡単で、マルチスレッドと同じ正味の効果があり (レンダリング スレッドをブロックすることなく転送が非同期に実行されます)、何倍も複雑ではありません。

于 2011-09-09T17:59:37.827 に答える
3

さまざまなオプションがあります。

レンダリング スレッドでパイプライン化されたReadPixelを呼び出します。この場合、返されたデータは、画像の保存専用のスレッドのキューに入れることができるバッファーに格納されます。これは、バッファ キュー、ミューテックス、およびセマフォを使用して簡単に実行できます。レンダリング スレッドはReadPixelを使用してデータを取得し、ミューテックスをロックし、(システム メモリ) ピクセル バッファをキューに入れ、ミューテックスをロック解除し、セマフォを増やします。ワーカー スレッド (セマフォでロックされている) は、レンダリング スレッドによって通知され、ミューテックスをロックし、ピクセル バッファーをデキューし、ミューテックスをロック解除し、画像を保存します。

それ以外の場合は、現在のフレーム バッファをテクスチャまたはピクセル バッファ オブジェクトにコピーできます。この場合、2 つの異なるスレッドが必要で、OpenGL コンテキストがそれぞれ ( MakeCurrentを介して) 最新であり、オブジェクト空間を互いに共有しています ( user771921で提案されているように)。最初のレンダリング スレッドがReadPixels (またはCopyPixels ) を呼び出すと、2 番目のスレッドに操作について通知します (たとえば、セマフォを使用)。2 番目のレンダリング スレッドは、ピクセル バッファ オブジェクトをマップします (またはテクスチャ データを取得します)。この方法には、ドライバーが最初のスレッド読み取り操作をパイプライン処理できるという利点がありますが、追加のサポート バッファーを導入することで、実際にはメモリ コピー操作が 2 倍になります。さらにReadPixel操作は、2 番目のスレッドがバッファーをマップするときにフラッシュされます。このバッファーは、2 番目のスレッドが通知された直後に (おそらく) 実行されます。

最初のオプションをお勧めします。これは、はるかにクリーンでシンプルだからです。2 つ目は複雑すぎるため、これを使用しても利点が得られるとは思えません。画像の保存操作はReadPixelよりもはるかに低速です。

ReadPixel がパイプライン化されていなくても、FPS は本当に遅くなりますか? プロファイリングする前に最適化しないでください。

リンクした例では、OpenGL に関連しない GDI 関数を使用しています。コードがフォームの再描画イベントを引き起こし、ウィンドウ クライアント領域の内容をキャプチャすると思います。この問題について実際にプロファイリングを実行していなくても、ReadPixelと比較してはるかに遅いようです。

于 2011-09-10T18:05:00.740 に答える
1

まあ、マルチスレッド プログラムで opengl を使用するのは悪い考えです。特に、コンテキストが作成されていないスレッドで opengl 関数を使用する場合はそうです。

それとは別に、コード例には何も問題はありません。

于 2011-09-09T13:45:57.380 に答える