7

私は、WPFでも実行できる多くのことを可能にする複雑なUIシステムを持っていますが、複数のプラットフォーム(iOS、Android、Windowsなど)をサポートしています。まだ完了していませんが、現在、次の問題に直面しています。

私の設計者はオブジェクトを回転させたい! オブジェクトの回転は、単純な軸に沿ったオブジェクトよりもはるかに複雑です。これが、glScissorを使用できない理由です。問題を理解するのに役立つかもしれない小さなグラフィック:

効果

オブジェクト「サブコンテナ」を「親コンテナ」の境界でクリップする必要があることがわかります。私の知る限り、いくつかのオプションがあります:

  • ステンシル バッファを使用します。この場合、表示されないオブジェクトがあり、子オブジェクトをマスクする可能性があるため、ステンシル バッファにも影響を与える必要があるため、問題が発生しました。また、階層に戻るときにステンシル バッファーを減らす必要があるため、各オブジェクトを 2 回描画する必要があります。
  • UIオブジェクトを描画するために使用される平面(三角形化;またはその他のUIモデル)をカットします。これは、さまざまなポイントでクリップされる可能性があるため、余裕があるようです(回転したコンテナー内の回転したコンテナー内のコンテナーを想像してください. .. ) また、それらを正しくクリップするのは非常に難しく、パフォーマンスの問題の原因になる可能性があります

ただし、どちらもさまざまな問題を引き起こすようであり、パフォーマンス リークの原因となる可能性があります。私が欲しいものをアーカイブする他の方法はありますか、または上記の両方のアプローチを改善する方法はありますか?

4

3 に答える 3

5

私は Stencil-Buffer を使用することになりました。これは、深度アプローチよりも多くの描画呼び出しを生成しますが、実装がはるかに簡単です。

描画する前に、次のコードを書きました。

if (_Mask)
{
    if (Stage.StencilMaskDepth++ == 0)
        GL.Enable(EnableFlags.STENCIL_TEST);

    GL.ColorMask(false, false, false, false);
    GL.DepthMask(false);
    GL.StencilFunc(StencilFunction.ALWAYS, Stage.StencilMaskDepth, Stage.StencilMaskDepth);
    GL.StencilOp(StencilOp.INCR, StencilOp.INCR, StencilOp.INCR);

    // Draw rectangle
    DrawColor(Colors.Black);

    GL.ColorMask(true, true, true, true);
    GL.DepthMask(true);
    GL.StencilFunc(StencilFunction.EQUAL, Stage.StencilMaskDepth, Stage.StencilMaskDepth);
    GL.StencilOp(StencilOp.KEEP, StencilOp.KEEP, StencilOp.KEEP);
}

すべての子が描画された後、このコードが呼び出されます。

if (_Mask)
{
    GL.ColorMask(false, false, false, false);
    GL.DepthMask(false);
    GL.StencilFunc(StencilFunction.ALWAYS, Stage.StencilMaskDepth, Stage.StencilMaskDepth);
    GL.StencilOp(StencilOp.DECR, StencilOp.DECR, StencilOp.DECR);
    // Draw rectangle
    DrawColor(Colors.Black);

    GL.ColorMask(true, true, true, true);
    GL.DepthMask(true);

    if (--Stage.StencilMaskDepth == 0)
        GL.Disable(EnableFlags.STENCIL_TEST);
}

数か月以内に他のアプローチをテストするかもしれませんが、現時点ではこれが最も簡単に実装できます。

于 2013-03-05T00:11:42.947 に答える
3

これは単なるアイデアですが、マスキングを行うために深度バッファを使用するのはどうでしょうか?

  1. 深度バッファを有効にして、glDepthFunc(GL_LEQUAL) を設定します。
  2. コンテナ A とそのフレームを Z = 0 でレンダリングする
  3. コンテナをレンダリング Z = 1 の内部領域/背景 (他のネストされたコンテナがある場所)
  4. これで、深さ 0 のコンテナー フレームと深さ 1 のコンテナー内部を含む "深さステンシル" ができました。これは、中間でレンダリングするものはすべて、内部よりも上にあるが、フレームよりも下にあることを意味します (そして、それによってクリップされます)。
  5. 次のコンテナ B で、そのフレームを Z = 0.5 にレンダリングします (GPU 上の親コンテナ A によってクリップされます)。
  6. コンテナ B の内部領域を Z = 0.75 でレンダリング
  7. コンテナ B 内でレンダリングしたいものはすべて、Z = 0.75 である必要があります。コンテナの内部領域をオーバーレイしますが、コンテナ A と B の両方のフレームによってクリップされます。
于 2012-12-06T11:46:47.130 に答える
1

テクスチャにレンダリングしてみるとよいかもしれません。親テクスチャを作成します。次に、すべての子をそのテクスチャにレンダリングします。次に、親テクスチャを画面にレンダリングして、必要に応じて変形および移動します。このソリューションには、何を達成したいかによって、問題がある場合とない場合があります。特に、コンテナーのスケールをアニメートする場合や、多数のコンテナーがネストされた非常に複雑なツリーがある場合は、パフォーマンスの問題が発生する可能性があります。

于 2012-12-06T12:53:45.343 に答える