2

背景:私は DirectX 用の SlimDX C# ラッパーを使用しており、Sprite クラスを使用して多くの 2D スプライトを描画しています (従来は、基礎となる dll の Direct3DX 拡張から)。一度に数百のスプライトを画面に描画していますが、パフォーマンスは素晴らしいです。私のクアッド コアでは、10,000 以上のオブジェクトのロジックを含め、ゲーム全体でプロセッサの 3 ~ 6% を使用しています。 2 番目のスレッドのルーチンなど。明らかに、スプライトは完全なハードウェア アクセラレーションを使用して描画されており、すべてが本来あるべき状態になっています。

問題: Line クラスへの呼び出しを導入し始めたときに問題が発生します。(ドラッグ選択ボックス用に) 4 本の線を引くとすぐに、プロセッサの使用率が 13 ~ 19% に急上昇します。これでたったの4行!

私が試したこと:

  1. 線のアンチエイリアシングのオンとオフを切り替えます。
  2. GLines のオンとオフを切り替えます。
  3. 描画する呼び出しの周りで line.begin と line.end を手動で呼び出します。
  4. line.begin と line.end へのすべての呼び出しを省略します。
  5. line.draw への呼び出しが sprite.begin / sprite.end ブロック内にないことを確認します。
  6. sprite.begin / sprite.end ブロック内で line.draw を呼び出す。
  7. 4 ラインのレンダリング、または 300 のレンダリング。
  8. すべてのスプライトとテキストのレンダリングをオフにし、ライン レンダリングを 4 行だけ残します (これが何らかのモード変更の問題であるかどうかを確認するため)。
  9. 上記のほとんどの組み合わせ。

一般に、これらのいずれもパフォーマンスに重大な影響を与えませんでした。#3 では、プロセッサの使用率がおそらく 2% 減少しましたが、それでも、本来よりも 8% 以上高いままです。最も奇妙なことは、上記の #7 がパフォーマンスにまったく影響を与えなかったことです。4 行でも 300 行と同じくらい遅かったのです。私が把握できる唯一のことは、これが何らかの理由でソフトウェアで実行されているということです。および/または、グラフィックカードがある種の描画モードを継続的に切り替えていること。

マトリックスアプローチ:

誰かが上記の問題の修正を知っている場合は、それを聞いてみたいです!

しかし、これは一般的に directx 内の問題である可能性があると想定しているため、別のルートを追求してきました。つまり、独自のスプライト ベースのラインを作成することです。基本的に、1 ピクセルの白い画像があり、拡散色と変換を使用して線を描画しています。これはパフォーマンス的には機能します。このように 300 本の「線」を描画すると、クアッド コアで探している 3 ~ 6% のプロセッサ使用率のパフォーマンス範囲に収まります。

ピクセル ストレッチ ライン テクニックには 2 つの問題があります。変換について詳しい人が助けてくれることを願っています。水平線の現在のコードは次のとおりです。

    public void DrawLineHorizontal( int X1, int X2, int Y, float HalfHeight, Color Color )
    {
        float width = ( X2 - X1 ) / 2.0f;
        Matrix m = Matrix.Transformation2D( new Vector2( X1 + width, Y ), 0f, new Vector2( width, HalfHeight ),
            Vector2.Zero, 0, Vector2.Zero );
        sprite.Transform = m;

        sprite.Draw( this.tx, Vector3.Zero, new Vector3( X1 + width, Y, 0 ), Color );
    }

これは、画面上のほぼ正しい位置にほぼ正しいサイズの線を描画する限り、機能します。しかし、物事が右にずれて見えるのは奇妙です。私のマトリックスアプローチがまったく正しいかどうかはよくわかりません.1x1のスプライトを水平方向にある量のピクセルでスケーリングし、垂直方向に別の量だけスケーリングしたいだけです. 次に、それらを配置できるようにする必要があります-中心点で問題ありません。それが私がしなければならないことだと思いますが、左上で配置できれば、さらに良いでしょう。これは単純な問題のように思えますが、行列に関する私の知識はかなり貧弱です。

これにより、純粋な水平線と純粋な垂直線が機能するようになり、これがほとんどの戦いです。それだけで生活でき、現在斜めの線を使用している場所に他の種類のグラフィックを使用できます. しかし、この引き伸ばされたピクセルのアプローチを使用して角度のある線を描く方法があれば、本当にいいと思います. つまり、たとえば 1,1 から 7,19 までの線を引きます。行列の回転などでは、これは実行可能のようですが、推測とチェック以外にどこから始めればよいかわかりません。これには永遠に時間がかかります。

どんな助けでも大歓迎です!

4

2 に答える 2

1

パイプラインストールのように聞こえます。スプライトのレンダリングとラインのレンダリングの間でいくつかのモードを切り替えています。これにより、新しいプリミティブで開始する前に、グラフィックカードがパイプラインを空にします。

線を追加する前に、それらのスプライトはすべてレンダリングしましたか、それとも他のモードをすでに使用して画面上に他の要素がありましたか?

于 2009-03-11T15:16:50.023 に答える
0

さて、多くの実験の後、水平線を機能させることができました。これは、以前に見た奇妙なオフセットなしで機能します。同じ原則が垂直線にも当てはまります。これはline クラスよりもはるかにパフォーマンスが優れているため、これを水平線と垂直線に使用します。コードは次のとおりです。

    public void DrawLineHorizontal( int X1, int X2, int Y, float HalfHeight, Color Color )
    {
        float width = ( X2 - X1 );
        Matrix m = Matrix.Transformation2D( new Vector2( X1, Y - HalfHeight ), 0f, new Vector2( width, HalfHeight * 2 ),
            Vector2.Zero, 0, Vector2.Zero );
        sprite.Transform = m;

        sprite.Draw( this.tx, Vector3.Zero, new Vector3( X1, Y - HalfHeight, 0 ), Color );
    }

上記のように、斜めの線でも機能するバージョンが欲しいです。そのための提案はありますか?

于 2009-03-11T17:56:41.057 に答える