5

これは、3D シーンでマウスの位置を取得するために使用するコードです。

void GetOGLPos(int x, int y, GLdouble &pX, GLdouble &pY, GLdouble &pZ){
 GLint viewport[4];
 GLdouble modelview[16];
 GLdouble projection[16];
 GLfloat winX, winY, winZ;

 glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
 glGetDoublev(GL_PROJECTION_MATRIX, projection);
 glGetIntegerv(GL_VIEWPORT, viewport);

 winX = (float)x;
 winY = (float)viewport[3]-(float)y;
 glReadPixels(x, (int)winY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ);

 gluUnProject(winX, winY, winZ, modelview, projection, viewport, &pX, &pY, &pZ);
}

しかし、悪いことに気付きました... フレームごとにその関数を 1 ~ 2 回呼び出すと、CPU 使用率が 100% になり、3 回以上呼び出すと CPU 使用率が 200% になります (4 コア、1 ~ 2 回の呼び出し = 25%、3 回以上の呼び出し) = 50%、50% を超えることはできないと思います..)

これを効率的に行う他の方法はありますか?フレームごとにその関数への呼び出しを 4 回使用しているので、シーンにレンダリングする必要がある領域を把握しています (画面の各コーナーから取得します)。

また、マウスでどこを指しているかを知るためにも使っているのでリアルタイムで必要なのですが、1回の呼び出しでもシングルコアで100%使えるのでCPUの使用を減らしたいです。

編集

glPushName() メソッドを試してみましたが、CPU よりも GPU の方が遅く、遅くなる可能性が高くなります。また、プログラムで glReadPixels() 呼び出しを 1 回も使用しない場合、CPU 使用率は 0 ~ 1% 程度です。奇妙なことは、CPU使用率が高くなることですが、100%の使用率で期待するようにプログラムが遅れることはありません...プログラムがオンになっているときに他のプログラムを使用すると問題が発生し、それらを使用するのが遅くなります.

4

3 に答える 3

1

OpenGLでピッキングしようとしているようです。

このチュートリアルをチェックしてください。あなたのアプローチよりもパフォーマンスの低下が少ないはずです: http://gpwiki.org/index.php/OpenGL:Tutorials:Picking

この場所では、OpenGL でピッキングを行う他の方法について言及しています: http://www.opengl.org/resources/faq/technical/selection.htm

于 2010-02-05T23:56:46.183 に答える
0

glReadPixels は、PBO を使用しようとしても、CPU を使用してフレームバッファから読み取ったデータを変換します。たとえば、PBO でカラー データを読み取ろうとすると、param を GL_BGRA に設定した場合のみ、関数は変換を行わずにすぐに戻ります。それ以外の場合、param を GL_RGBA に設定すると、CPU 使用率が占有されます。また、フレームバッファから深度データを読み取ろうとしていますが、glReadPixels はどのようなパラメータ設定でも確実にデータを変換します

于 2013-01-18T09:49:34.900 に答える
0

問題を引き起こしているのはその単一の機能であると確信していますか? プロファイリングツールを試して確認しましたか? 私はあなたを疑いたいわけではありません。コードの大部分をデバッグしたり変更したりするという問題を経験する前に、あなたに確信を持ってもらいたいだけです。

私は、OpenGL 呼び出し (1 ピクセルを読み取るため) がCPU時間を消費していることにかなり驚いています。どちらかといえば、CPU 使用率は 0 ですが、フレームレートは遅いと思います。しかし、これには本当に問題があると疑うほど OpenGL について十分な知識はありません。直感的ではないように思えます。

glReadPixels のパフォーマンスに関するフォーラムの投稿は、特定のグラフィックス カード (特に古いもの) が GPU から CPU にデータを移動する際に非常に効率が悪いことを示唆しています。コードを別のコンピューターで実行して、ビデオ カードだけであるかどうかを確認できますか? これは、特に ATI カードを持っていて友人の NVIDIA カードで実行する場合、またはその逆の場合に、開始するのに最適な方法です。

この投稿では、データ型が違いを生む可能性についても言及しています。これが大きな違いになるとは思いませんが、誰が知っていますか。

もう 1 つ試してみてください。関数を 4 回連続して呼び出すと、現在の行列を読み取るための不要な呼び出しセットが 3 つ増えます。代わりに、パラメーターを介して行列を取得することを検討してください。しかし、glGetDoublev/glGetIntegerv に本当に時間がかかっているとは思えません。

何をしているのかにもよりますが、フラストラム カリングについて読みたいと思うかもしれません。これは、画面の四隅を取得してやろうとしていることのように聞こえます。glUnProject を使用する代わりに、数学を自分で実装する方が費用がかからない場合があります。

于 2010-03-05T19:33:30.443 に答える