4

私の OpenGL プログラムでは、次のことを順番に実行しています。

// Drawing filled polyhedrons
// Drawing points using GL_POINTS
// Displaying information for each above point beside it

ポイント情報 (ポイント識別子/番号など) を表示するために、 gluProject ()を使用して、ポイントの 3D 座標を 2D ウィンドウ座標に変換します。glRasterPos () と 2D 文字レンダリング コードを使用して、その 2D ウィンドウ位置にポイント識別子を書き込みます。

レンダリングされたポイントが別のプリミティブによってオクルードされると、OpenGL パイプラインで発生する自動オクルージョン テストと深度テストにより、自動的に表示されなくなります。ただし、このオクルージョン情報を取得していないため、オクルードされている場合でも、ポイント識別子テキストがポイントの横に表示されます。

3D (レンダリングされた) ポイントがその前にある他の 3D (レンダリングされた) プリミティブによって遮られているかどうかを判断する方法は? または、オクルードされていない場合にのみ、その横にポイント情報テキストを表示するより良い方法はありますか?

注: 追加のレンダリング パスが必要なメソッドがあることは承知しています。私はそれらが私の目的のために高価であると感じています.

4

4 に答える 4

3

オクルージョン クエリの 2 番目のパスを使用したくない場合は、Z バッファーをサンプリングしてテスト ポイントと比較してみてください。

ポイントの横にテキストを追加しているので、ポイントの正規化された Z バッファ値を (gluProject を使用して) 取得し、その値をそのポイントでサンプリングされた Z バッファ (glReadPixels を使用) 値と比較します。ポイントがサンプリングした深さの値よりも後ろにある (より大きい) 場合、ポイントは遮られ、テキストを描画しないことを選択できます。

もちろん、これにはテキストの前にすべてのジオメトリをレンダリングする必要がありますが、それは問題ではありません。

サンプルコード:

// 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
于 2009-08-21T13:39:15.797 に答える
2

アランの答えに加えて、カメラの位置からポイントに光線を投影し、それがジオメトリのいずれかと交差するかどうかを判断することで、オクルージョンを数学的にテストできます。インターネット上には、光線とオブジェクトの交差テストを行うためのリファレンスがたくさんあります(たとえば、オブジェクト/オブジェクトの交差ページを参照してください)。ジオメトリがたくさんある場合は、バウンディングボリュームまたはBSPツリーを使用して処理を高速化することをお勧めします。

ボーナスとして、オクルージョンコードは、OpenGLからの値の抽出に依存しないため、単体テストがはるかに簡単になるはずです。

于 2009-08-25T04:05:18.487 に答える
2

最近のハードウェアでは、Zバッファからの読み取りが非常に遅くなる可能性があります。そのため、オクルージョンクエリが発明されました。ARB-occlusion-query拡張機能を検索します。結果を得るまでに数フレームの遅延がありますが、パフォーマンスに影響を与えることはありません。

何らかの理由でオクルージョンクエリが機能しない場合、次のフォールバックオプションは、BSPツリー(GLをまったく使用しない)を使用してソフトウェアのray-intersect-world操作を実行することです。

于 2009-08-23T23:01:12.763 に答える