4

私は C++ と DirectX は初めてで、XNA から来ました。Fly The Copter のようなゲームを開発しました。私が行ったことは、Wall という名前のクラスを作成することです。ゲームの実行中に、すべての壁を描きます。XNA では壁を ArrayList に保存し、C++ では vector を使用しました。XNA ではゲームの実行速度が速く、C++ では非常に遅くなります。C++ コードは次のとおりです。

void GameScreen::Update()
{
    //Update Walls
    int len = walls.size();
    for(int i = wallsPassed; i < len; i++)
    {
        walls.at(i).Update();
        if (walls.at(i).pos.x <= -40)
            wallsPassed += 2;
    }
}

void GameScreen::Draw()
{
    //Draw Walls
    int len = walls.size();
    for(int i = wallsPassed; i < len; i++)
    {
        if (walls.at(i).pos.x < 1280)
            walls.at(i).Draw();
        else
            break;
    }
}

Update メソッドでは、X 値を 4 減らします。Draw メソッドでは、sprite->Draw (Direct3DXSprite) を呼び出します。ゲームループで実行される唯一のコードです。これが悪いコードであることは承知しています。改善するアイデアがあれば、助けてください。私の英語に感謝し、申し訳ありません。

4

8 に答える 8

8

at() をすべて [] 演算子に置き換えてみてください。例えば:

 walls[i].Draw();

次に、すべての最適化をオンにします。[] と at() はどちらも関数呼び出しです。最大のパフォーマンスを得るには、それらがインライン化されていることを確認する必要があります。これは、最適化レベルを上げることです。

壁オブジェクトの最小限のキャッシュを実行することもできます - 例:

 for(int i = wallsPassed; i < len; i++)
 {
    Wall & w = walls[i]; 
    w.Update();
    if (w.pos.x <= -40)
        wallsPassed += 2;
 }
于 2010-01-28T21:36:49.440 に答える
2

パフォーマンスの問題の原因を絞り込むようにしてください (プロファイリングとも呼ばれます)。すべてのオブジェクトを更新し続けながら、オブジェクトを 1 つだけ描画してみます。突然速くなった場合は、DirectX の描画に問題があります。

それ以外の場合は、すべてのオブジェクトを描画してみますが、1 つの壁だけを更新してください。より速い場合、 update() 関数は高すぎる可能性があります。

于 2010-01-28T21:46:42.233 に答える
1
  • 「速い」とはどのくらい速いですか?
  • 「本当に遅い」とはどのくらい遅いですか?
  • いくつのスプライトを描いていますか?
  • 画像ファイルとしての各サイズと、画面上に描画されるピクセル数はどれくらいですか?
  • 描画されるスプライトの数を変更すると、パフォーマンスは (XNA/C++ で) どのように変化しますか?
  • 更新せずに描画した場合、またはその逆の場合、どのような違いが得られますか
于 2010-01-29T10:16:23.527 に答える
1

リリース モードをオンにするのを忘れただけかもしれません :) 過去にいくつか問題がありました。デバッグ モードのせいでコードが非常に遅いと思っていました。そうでない場合は、一部のレンダリングや膨大な数のオブジェクトに問題が発生する可能性があります。あなたが提供したコードは良さそうです...

于 2010-01-29T10:40:17.683 に答える
0

ビットマップ用に複数のバッファ (別名Double Buffering ) を試しましたか?

典型的なシナリオは、1 つのバッファーで描画し、最初のバッファーが画面にコピーされている間に、2 番目のバッファーで描画することです。

もう 1 つの手法は、メモリ内に巨大な「論理」画面を作成することです。物理ディスプレイに描画される部分は、論理画面の小さな領域へのビューポートまたはビューです。背景 (または画面) を移動するには、グラフィック プロセッサ側でコピーが必要です。

于 2010-01-28T22:45:22.230 に答える
0

異なるドローコールですべての壁を描画するのは悪い考えです。データを単一の頂点バッファー/インデックス バッファーにまとめて、単一の描画に送信してみてください。そのほうがまともな考えです。

とにかく、なぜゆっくりと進むのかを理解するには、CPU と GPU (PerfHud、Intel GPA など) を試してみて、最初に何がボトルネックなのか (CPU または GPU の場合) を調べます。そして、問題を軽減するために戦うことができます。

于 2010-01-29T09:53:22.923 に答える
0

壁のリストへのルックアップが速度低下の原因である可能性は低いです。オブジェクトを 3D で描画するコストは、通常、制限要因になります。

重要な部分は、描画コード、DirectX デバイスの作成に使用したフラグ、およびテクスチャの作成に使用したフラグです。暗闇の中での私の刺し傷...デバイスをREF(ソフトウェア3d)ではなくHAL(ハードウェア3d)として初期化していることを確認してください。

また、いくつのスプライトを描いていますか? 各描画呼び出しには、かなりの量のオーバーヘッドがあります。フレームごとに数百を超えると、それが制限要因になります。

于 2010-01-29T20:04:06.630 に答える
0

スプライト描画呼び出しのバッチ処理を支援できます。おそらく、描画呼び出しは、関連するパラメーターを使用して ID3DXSprite::Draw の唯一のインスタンスを呼び出します。

ID3DXSprite::Begin を (D3DXSPRITE_SORT_TEXTURE フラグを設定して) 呼び出し、レンダリングがすべて完了したら ID3DXSprite::End を呼び出すと、パフォーマンスが大幅に向上します。次に、ID3DXSprite はすべてのスプライト呼び出しをテクスチャ別に並べ替えて、テクスチャ スイッチの数を減らし、関連する呼び出しをまとめてバッチ処理します。これにより、パフォーマンスが大幅に向上します。

ただし、Update 呼び出しと Draw 呼び出しの内部を確認せずに、これ以上説明することは困難です。上記はあくまで推測ですが…

于 2010-01-29T08:48:45.613 に答える