10. クリッピング、カリング、可視性テスト

10.010  頂点がクリップされたかされないかはどうしたら解りますか?

頂点が切り取られるかどうかを決定するために、OpenGLフィードバック機能を使用できます。 フィードバックモードにいた後に、GL_POINTSプリミティブとして問題の頂点を単に送ってください。 そして、後ろにGL_RENDERモードに切り換えて、フィードバックバッファのサイズをチェックしてください。 0のサイズにより、切り取られた頂点が示されます。

一般に、OpenGLインプリメンテーションは速いフィードバックメカニズムを提供しません。 クリップテストを手動で実行することがより速いかもしれません。 そうするには、クリップ同等の眺めボリュームと一致している6つの飛行機方程式を構成し、現在のModelView行列によってそれらをオブジェクトスペースに変換してください。 もしそれが6つの飛行機方程式のうちのいくつかに違反するならば、ポイントは切り取られます。

ここには、見えて、どのようにそれらに対するオブジェクトスペース見方ボリューム飛行機とクリップテスト隣接ボックスを計算するかのGLUT例があります

10.020  隠れているか、見えているかのテストはどのようにしたらできますか?

OpenGLは、直接的なサポートを、与えられた観点のための場面で、与えられたプリミティブが見えるかどうかを決定することに全然提供しません。 最悪の場合でも、アプリケーションはこれらのテストを手動で実行する必要があります。 先決問題は、情報を、どのようにこれをするかに含んでいます

問題10.010からのコード例は、この見方選択例コードを生み出すために、Nateコマドリの優秀な展望チュートリアルと結合されました

より高レベルAPI〈Fahernheitラージモデルなどの〉はこの機能を提供できます

HP OpenGLプラットフォームは閉塞選択拡張をサポートします。 この拡張を使うためには、閉塞テストを可能にし、いくらかの隣接幾何学をし、幾何学の視界ステータスを得るために、glGetBooleanv()を呼んでください。

10.030  矩形でないビューポートの場合どう描けばよいのでしょう?

OpenGLの型板バッファは、矩形ではないビューポートの外でエリアをマスキングするために使用できます。 使用可能であった型板および適切に設定された型板テストによって、与えることは、その時、暴露されたエリアに存在するかもしれません。 一般に、アプリケーションは型板マスクを1回書き、それから、繰り返されたフレームを、暴露されたエリアに表現します。

深さバッファ アプリケーションとして、ウィンドウと文脈が作成される時には、型板バッファを要求しなければなりません

アプリケーションはそのような表現を次の通り実行します

可能化型板テストおよび出発それ 最後まで */glEnableで 可能であ
る (GL_STENCIL_TEST);

ビューポート*/glStencilFuncの外で単一のビットをエリアの型板バッファに書き込む準
備(GL_ALWAYS、0x1、0x1);

ここのビューポートの外で、幾何学のセットを、エリアのために対応しているようにして
ください

現在の型板バッファは、ビューポート*/の外でエリアにより描かれた単一のビットを持っ
ています

場面をビューポート*/glStencilFuncに表現する準備(GL_EQUAL、0x0、0x1);

ここでビューポートの中の場面をしてください

/*...render 再びの場面 アニメーション目的*/のために必要があった 

ビューポートの外で単一のビットがエリアにより描かれた後に、アプリケーションは幾何学を中のエリアまたは外 ビューポート に与えることができます。 中のエリアに与えるためには、コード上記ショーとしてglStencilFunc(GL_EQUAL、0x0、0x1)を使ってください。 ビューポートの外でエリアに与えるためには、glStencilFuncを使ってください(GL_EQUAL、0x1、0x1)。

深さテストだけを使って同様な結果を得ることができます。 3D場面を矩形のビューポートに与えた後に、アプリは深さ緩衝器をきれいにし、矩形ではないフレームをできます。

10.040  OpenGL プリミティブの、ある頂点がウィンドウの外に出た時に、突然色や、マッピングがおかしくなりました。何が起こっているのでしょうか?

これに2つの潜在的な原因があります

プリミティブがウィンドウの外に部分的に横たわっている時には、それはしばしば眺めボリューム境界を横切ります。 OpenGLは、眺めボリューム境界を横切るどのようなプリミティブでも切り取らなければなりません。 プリミティブを切り取るために、OpenGLは色価値を改ざんしなければなりません。従って、それらは新しいクリップ頂点で正しい。 この補間は正しいパースペクティブです。 しかし、プリミティブがrasterizedされる時には、色価値は、しばしば、正しいパースペクティブではないウィンドウスペースのリニアの補間を使って生成されます。 生成された色価値の違いは、プリミティブが切り取られるかどうかで、満たされたプリミティブ、色価値のどのような与えられたbarycentric同等位置のためにでも、違う依存であるかもしれないのを意味しています。 もしラスタ化の間に生成された色価値が正しいパースペクティブであるならば、この問題は存在しないでしょう。

いくつかのOpenGLインプリメンテーションのために、ラスタ化の間に生成されたテクスチャー座標は、正しいパースペクティブではありません。 しかし、通常、それらを、glHintを呼ぶことによって正しいパースペクティブにすることができます(GL_PERSPECTIVE_CORRECTION_HINT、GL_NICEST);。 ラスタ化段階で生成された色は、ほとんどすべてのOpenGLインプリメンテーションにおいて正しいパースペクティブであらず、そのようにされえません。 この理由のために、テクスチャーが調和するより色についてのこの問題に遭遇しそうです。

切り取られたプリミティブのために色またはテクスチャー・マッピングが不正確であるかもしれない2番目の理由が、色価値またはテクスチャー座標が非平面であるからです。 個々の頂点の三色のコンポーネントが3Dカラー・スペースの飛行機にない時には、色価値は非平面です。 2 でDテクスチャー座標はいつも平面です。 しかし、この文脈において、非平面である用語は、織られているプリミティブのために形で適合していないtexelエリアを探すテクスチャー座標のために使われます。

非平面の色またはテクスチャー座標は、三角のプリミティブのための問題ではないけれども、問題は、GL_QUADS、GL_QUAD_STRIP、およびGL_POLYGONプリミティブによって起こるかもしれません。 非平面の色価値またはテクスチャー座標を使う時には、切り取られた頂点と関連した新しい価値を生成するための正しい方法がありません。 補間をパースペクティブ訂正することさえしてください 切り取られたおよび切り取られなかったプリミティブの違いを作成できる 。 この問題の解決策は、非平面の色価値とテクスチャー座標を使わないことです。

10.050 ジオメトリがビューボリュームの中に在ることが分かっています。その際、パフォーマンスを最大にするために OpenGL のボリュームクリッピングをオフにするには、どうしたらよいですか?

標準のOpenGLは、見方ボリュームを切り取っているテストを使用不可にするために、メカニズムを提供しません; 従って、それは、送るすべてのプリミティブのために起こります。

OpenGLのいくつかのインプリメンテーションがGL_EXT_clip_volume_hint拡張をサポートします。 もし拡張が入手可能ならば、glHint(GL_CLIP_VOLUME_CLIPPING_HINT_EXT、GL_FASTEST)への呼び出しにより、幾何学が眺めボリューム内に完全にあり、見方ボリュームを切り取ることが不要なのが、OpenGLに知らせられるでしょう。 刈っている正常は、このヒントをGL_DONT_CAREに設定することによって再開できます。 刈り込みの時に、このヒントによって使用不可にされる もし実際、幾何学が眺めボリュームを越えているならば、結果は不確定です。

10.060  オブジェクトの近くに視点を動かすと、オブジェクトが消え始めますOpenGL の zNear クリッピングプレーンの効果を無くすることができますか?

することができません。 もしそれについて考えるならば、それは意味をなします: もし観点が場面の中央にあるならば? 確かに、いくらかの幾何学が、切り取られるビューアとニーズの後ろにあります。 それをすることは不適当な結果を引き起こします。

正しいパースペクティブと深さバッファ計算が起こり、zNearを切り取っている飛行機を0.0にセットし、also not オプション でもあるために。 zNearを切り取っている飛行機は、目の前でポジティブ(不0)距離でセットされなければなりません。

違った形で起こるかもしれない切り取っている人工物を避けるために、アプリケーションが場面内の観点位置を追跡しなければならず、それが少しの幾何学とも近すぎるようにならないことを保証してください。 通常衝突検出の簡単なフォームによってこれをすることができます。 このFAQはOpenGLによって衝突検出についてのより多くの情報を含んでいます

もし幾何学が見方ボリューム飛行機のうちのどれも横切っていないと確信しているならば、刈ることを使用不可にするために、拡張を使用することができるでしょう。 詳細については先決問題を見てください

10.070  ウィンドウの左端や一番下の外にある点を glRasterPos の初期値としてglBitMap や glDrawPixels プリミティブを描くのにはどうしたら良いですか?

ウィンドウの外でラスタポジションが設定される時には、それはしばしば眺めボリュームの外にあり、無効なので、後でマークされます。 glBitmapとglDrawPixelsプリミティブをすることは無効のラスタポジションによって起こりません。 glBitmap/glDrawPixelsが上に、およびラスタポジションの右にピクセルを生み出すので、左および/またはウィンドウの底エッジにより切り取られたこのタイプのプリミティブをすることが不可能であるようです。

しかし、ここには、しばしば使われた計略があります: ラスタポジションを眺めボリュームの中の有効な価値に設定してください。 そして、以下の電話をかけてください:

glBitmap (0、0、0、および0、xMove、yMove、NULL);

これは、OpenGLに、無-opビットマップをするけれども、現在のラスタポジションを、過ぎることに動かすように命じます(xMove、yMove)。 アプリケーションは、ラスタポジションを眺めボリュームの外に置く価値を供給します(xMove、yMove)。 glBitmap()によってこの呼び出しに続いてください。さもなければ、 表現をするglDrawPixels() 要求します。

10.080   glClear は切り取った長方形の外ではなぜ働かないのですか?

OpenGL指定により、シザーテストが可能な時にglClear()がシザー長方形をクリアするのだけが述べられます。 もし全体の窓をきれいにしたいならば、コードを使ってください:

glDisableです(GL_SCISSOR_TEST);
glClear(…);
glEnableです(GL_SCISSOR_TEST);

10.090  面カリングはどのようにして使うのですか?それが表面の法線を使わないのはなぜですか?

OpenGL面選択により ウィンドウ同等スペースの満たされたプリミティブのサインされたエリアが計算されます。 右回りの時にウィンドウ座標がカウンター右回りの注文とネガティブにある時には、サインされたエリアがポジティブです。 前での直面またはプリミティブへの後ろ直面と解釈されるように、指定する 注文する、カウンター右回りのまたは ために、アプリがglFrontFace()を右回りに用いることができます。 アプリケーションは、glCullFace()を呼んで前または後ろの顔を選ぶことを指定できます。 最後に、面選択はglEnableなので、呼び出し に によって可能でなければなりません(GL_CULL_FACE); .

OpenGLは、2つの理由のために選ぶ面を決定するために、プリミティブのウィンドウスペース投射を用います。 興味深い点火効果を作成するために、しばしば、近づかれている表面のために直角ではない垂直線を指定することが望ましい。 もし面選択のために、これらの垂直線が使われるならば、それは、いくつかのプリミティブを、誤って選ぶでしょう。 また、いつも、DCスペースのサインされたエリアが定義されるのに対してドット製品選択計画は、いつも可能であるわけではない(すなわち行列が非凡なケースにおいて)行列逆を必要とするかもしれません。

しかし、いくつかのOpenGLインプリメンテーションがGL_EXT_ cull_vertex拡張をサポートします。 もしこの拡張が存在するならば、アプリケーションはオブジェクトスペースの均質な目ポジションを指定するでしょう。 選ばれるように頂点には旗を掲げて、ベクトルによって頂点から目に現在の正常のドット製品に基づきます。 もしプリミティブのすべての頂点が選ばれるならば、プリミティブはされません。 多くの状況〈この拡張を使い、より速い表現を結果として生じる〉において パイプラインのより早い段階でそれが面を選ぶ 。