OpenGLの:3D(レンダリング)ポイントは、それの前で他の3D(レンダリング)プリミティブによって閉塞しているかどうかを判断するには?
質問
私のOpenGLのプログラムでは、私は順番に次のことをやってます:
// Drawing filled polyhedrons
// Drawing points using GL_POINTS
// Displaying information for each above point beside it
ポイント情報を(たとえばポイント識別子/番号)を表示するため、私は、2Dウィンドウに点の3次元座標を変換は、の gluProject のを()。私はの glRasterPos <使用して、その2Dウィンドウの位置でポイント識別子を書き込みます/ strong>のの()と2D文字のレンダリングコードます。
レンダリングされたポイントは、別のプリミティブによって閉塞されている場合、は、自動的にはによるOpenGLパイプラインで起こる自動閉塞試験および深さ試験に表示されません。しかし、私のポイント識別子のテキストは、私は、この閉塞情報を得ることはありませんので、それが閉塞された場合でも、ポイントの横に表示されます。
3D(レンダリング)点は、それの前に他の3D(レンダリング)プリミティブによって閉塞されているか否かを決定する方法?それとも横にポイント情報のテキストを表示するためのより良い方法があります。ののみのそれが閉塞されていない場合?
注:私は、余分なレンダリングパスを必要とする方法を知っています。私はそれらが私の目的のために高価であることを感じます。
解決
あなたはオクルージョンクエリを使用して喜んでない場合は第二、あなたのテストポイントと比較するために、Zバッファをサンプリングしようとすることができ渡します。
は、ポイントの隣にテキストを追加するため、正規化されたZバッファの値を取得し、その時点での値(glReadPixelsを使用して)サンプリングZバッファにその値を比較し、点の(gluProjectを使用して言います)。あなたのポイントは、背後にある(より大きい)である場合は、サンプリングされた深度値は、あなたのポイントは、閉塞される必要がありますし、テキストを描画しないように選択することができます。
これはもちろん、あなたがテキストの前に、すべてのジオメトリをレンダリングすることが必要ですが、それは問題ではありません。
サンプルコード:
// Assumed to already hold 3D coordinates of point
GLdouble point3DX, point3DY, point3DZ;
// Project 3D point coordinates to 2D
GLdouble point2DX, point2DY, point2DZ; // 2D coordinates of point
gluProject( point3DX, point3DY, point3DZ,
mMatrix, pMatrix, vMatrix, // MVP matrices
&point2DX, &point2DY, &point2DZ);
// Read depth buffer at 2D coordinates obtained from above
GLfloat bufDepth = 0.0;
glReadPixels( static_cast<GLint>( point2DX ), static_cast<GLint>( point2DY ), // Cast 2D coordinates to GLint
1, 1, // Reading one pixel
GL_DEPTH_COMPONENT, GL_FLOAT,
&bufDepth);
// Compare depth from buffer to 2D coordinate "depth"
GLdouble EPSILON = 0.0001; // Define your own epsilon
if (fabs(bufDepth - point2DZ) < EPSILON)
// 3D point is not occluded
else
// 3D point is occluded by something
他のヒント
zバッファからの読み出しは、最新のハードウェア上で非常に非常に遅いことができます。オクルージョンクエリが発明された理由です。 ARB-オクルージョンクエリ拡張を検索します。あなたが結果を得ることができます前に、それはラグのフレームのカップルを持っていますが、それはあなたのパフォーマンスにヒットしません。
オクルージョンクエリが何らかの理由で仕事に行くされていない場合は、、次のフォールバックオプションは、(すべてでGLを使用していません)BSPツリーを使用してソフトウェア線交差世界の操作を行うことです。
また、アランの答えに、あなたはあなたのポイントにカメラの位置から光線を投射し、それはあなたのジオメトリのいずれかと交差するかどうかを決定することによって、数学的に閉塞するためにテストすることができます。参考文献の多くは、例えば、線オブジェクトの交差テスト(参照を行うためのインターネット上であり、オブジェクト/ )交差点ページオブジェクト。あなたは、ジオメトリの多くを持っているなら、あなたは境界ボリュームやBSPツリーを使用して物事をスピードアップすることがあります。
それは、OpenGLから値を抽出に依存しないので、ボーナスとして、あなたの閉塞コードは、ユニットテストに非常に簡単である必要があります。
のAshwin Nanjappaからの返信は非常に有用でした。私は、OpenGLの専門家ではないので、MVPの行列を取得する方法を見つけるために私にしばらく時間がかかりました。私は彼のポストを補完するために、ここでコードを共有しています:
GLint viewport[4];
GLdouble modelview[16];
GLdouble projection[16];
glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
glGetDoublev( GL_PROJECTION_MATRIX, projection );
glGetIntegerv( GL_VIEWPORT, viewport );