0

記事OpenGL のクリッピングで説明されている問題に関して、新たな疑問が生じます。

ノードベースの 2D シーン グラフのクリッピングを実装しています。クリッピング ボックスの軸が揃っているときは常に、 OpenGL クリッピングで提案されているように glScissor を使用してい ます。軸が揃ったボックスのノード クリッピングを正常に実装しました。

各ノードは、クリッピングを使用する祖先のクリッピング四角形と交差する必要があることがわかります。(これは、先祖のクリッピング ボックスと重なる兄弟の場合に必要です)。

軸が揃っていない長方形を交差させるメカニズムは、ステンシル バッファーを使用して実装する必要があります。OpenGL クリッピングで提案されたソリューションの実装を開始しましたが、先祖のものと重なっているクリップ四角形を持つ子供に問題があります。

現在、ステンシル クリッピングは 1 つのクリッピング ボックスで完全に機能します。しかし、祖先と交差する子または孫の場合、アルゴリズムは失敗します。これは、子の完全な四角形ではなく、マスクとして (軸に沿ったバージョンのように) 2 つの関連する四角形の交差がここで必要になるためです。

私は次のアルゴリズムを考えました:

The topmost node writes start with a counter value of 1 and draws it's clippingrectangle with 1s to the stencil buffers and renders it's children stencil-testing against 1. クリッピングがオンになっている各兄弟は、境界の四角形に1 を追加して描画します。ステンシル バッファーを使用してから、2 に対してテストを行います。兄弟のクリッピング四角形が祖先の四角形とオーバーラップすると、それらがオーバーラップする領域が 2 で埋められ、2 に対するテスト時に完全なクリッピングが得られます。このアルゴリズムは、最大 255 のネストされたクリッピング ノードに拡張できます。

ここに私の質問があります:

レンダリングが実行されるたびに、1 が書き込まれる代わりに、現在のステンシル バッファー値に 1 が追加されるように、ステンシル バッファーへのレンダリングを実行するにはどうすればよいですか。

これは、ステンシル バッファーへのレンダリングの準備に使用するコードです。

glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_ALWAYS, ref, mask);
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);

ref をバッファーに書き込むのではなく、ステンシル バッファーの現在の値を ref の値だけ増やすセットアップを探しています。

誰かが私を助けることができますか?

4

1 に答える 1

2

glStencilFunc(GL_ALWAYS, ref, mask);それを言う:

  • 最初の引数は、ステンシル比較テストが常に成功することを示しています
  • したがって、2番目と3番目は無視されますが、原則として、ステンシルバッファからの値と、比較に使用されるビットを比較するための定数が設定されます。

glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);次のような効果があります。

  • ステンシルテストが失敗すると、新しい値が古い値に置き換わります(最初の引数ごとに)
  • 深度テストが失敗したがステンシルテストが合格した場合、新しい値が古い値を置き換えます(2番目の引数ごと)
  • ステンシルテストと深度テストの両方に合格すると、新しい値が古い値に置き換わります(3番目の引数ごと)

したがって、描画しようとするすべてのものがステンシルテストに合格するように設定します。いずれの場合も、テストに合格するかどうかに関係なく、その値がステンシルバッファにコピーされます。

おそらくあなたがしたいのは、通過するピクセルでglStencilOpを実行するように引数をに変更することです。GL_INCRしたがって、ステンシルバッファでは、1つのポリゴンが接触する場所には「1」、2つの連続するポリゴンを描画した場所には「2」、3を描画した場所には「3」などが表示されます。

ユーザーに表示されるものを描画するときは、glStencilFuncset to GL_GEQUALやなどを使用して、入力値を「1」、「2」、「3」などと比較できます。

ステンシルに1つのクリップ領域が描画されていると仮定して、深さのレベルを追跡したくない場合は、次の方法で次のクリップ領域に変更できます。

  1. GL_INCR;を使用してすべての新しいジオメトリを描画します。これにより、両方の領域にあったすべてのピクセルの値が「2」になり、1つの領域にのみあったすべてのピクセルの値が「1」になるステンシルバッファが作成されます。
  2. フルスクリーンポリゴンを描画し、ステンシルファンドGL_GREATERと参照値0でのみ渡すには、を使用しGL_DECRます。結果は、一度もペイントされなかった、または1回だけペイントされたすべての場所で「0」、2回ペイントされたすべての場所で「1」になります。
于 2011-09-27T14:43:16.410 に答える