0

私は、多くのXNAプロジェクトと同様に、Device.DrawIndexedPrimitives()呼び出しでレンダリングされる頂点のコレクションを生成するために使用される地形変位マップから開始した個人的なプロジェクトに取り組んでいます。

カスタムVertexDeclarationに更新しましたが、現在そのコードにアクセスできないため、少し古いが、パラダイム的に同一の(?)コードを投稿します。

私は次のように定義してVertexBufferいます:

VertexBuffer = new VertexBuffer(device, VertexPositionNormalTexture.VertexDeclaration, vertices.Length, BufferUsage.WriteOnly);
VertexBuffer.SetData(vertices);

ここで、「頂点」は次のように定義されます。

VertexPositionNormalTexture[] vertices

また、Update()の反復ごとに交換される2つのインデックスバッファーがあります。Draw()呼び出しで、私はバッファを設定しましたGraphicsDevice

Device.SetVertexBuffer(_buffers.VertexBuffer);
Device.Indices = _buffers.IndexBuffer;

無関係なコード行を無視して、境界形状内をチェックして、頂点がマウスカーソルの特定の半径内にあるかどうかを判断し、押されたキーに応じて頂点の位置を上下させるメソッドがあります。私の問題はVertexBuffer.SetData()、コンテナクラスの初期化時にが1回だけ呼び出されることです。

配列の頂点位置を変更してVertexPositionNormalTexture[]も、頂点位置の値は変更されますが、画面には反映されません。これは呼び出しに関連していると思いますが、頂点配列を変更した後でVertexBuffer.SetData()単純に呼び出すことはできません。SetData()

IndexBufferの処理方法(2つのバッファー、スワップされ、一度に渡される)を再検討した後、SetData()これが操作Update()を処理する方法であると思いますが、これは機能しますか?VertexBufferより適切な方法はありますか?ここで同様の質問への別の参照を見ましたが、ソースへのリンクはMegaUploadにあったので...

私は自分のVertexBuffer.Swap()アイデアを試してみますが、私はまた、参照を見てDynamicVertexBuffer、何が得られるのか疑問に思いますか?パフォーマンスはおそらく低下しますが、地形エディタの場合、頂点データを動的に操作できれば、それがあまりにも大きなトレードオフになるとは思いません。

さらにコードを投稿することはできますが、これはおそらく、デバイスバッファーがどのように設定されているか、またはデータがそれらにストリーミングされているかについての理解が不足していると思います。

編集:以下に提案された解決策は正しいです。すぐにコードを投稿します。

4

1 に答える 1

1

まず、地形から頂点を追加または削除していないと仮定しています。そうでない場合は、インデックスバッファをまったく変更する必要はありません。

2 つ目: 頂点の配列を編集するだけでは、画面に表示される内容が変更されないことを認識するのは正しいことです。VertexBuffer は、作成元の頂点から完全に分離されており、それらの元の配列への参照を保持しません。データを設定したときの頂点の「スナップショット」です。

あなたが行った仮定のように見えるもののいくつかについてはわかりません。私が知る限り、いつでも VertexBuffer.SetData() を呼び出すことができます。地形の頂点の数を変更せず、位置のみを変更する場合、これは適切です。頂点の位置を変更するたびに、バッファ内のデータを再設定するだけです。[注: 私が間違っていて、バッファにデータを一度しか設定できない場合は、バッファの古いインスタンスを新しいものに置き換えて、その上にデータを設定してください。ただし、頂点の数を変更していない限り、その必要はないと思います]

ただし、大きなバッファーの場合、SetData の呼び出しはかなりコストがかかります。地形の変更時にデータを設定するために必要なオーバーヘッドを回避するために、地形を多くの小さなバッファに「チャンク」することを検討してください。

私は DynamicVertexBuffer クラスについてあまり知りませんが、この状況には最適ではないと思います (たとえそうであるように聞こえても)。パーティクルの頂点に使用される方が多いと思います。でも、私は間違っているかもしれません。必ず調べてください。

好奇心から、なぜ 2 つのインデックス バッファーが必要なのですか? 頂点が同じ場合、フレームごとに異なるインデックスを使用するのはなぜですか?

編集: VertexBuffer を作成するためのコードは、BufferUsage.WriteOnly を使用します。BufferUsage を GraphicsDevice のそれと一致させることをお勧めします。デバイスの BufferUsage を設定していない場合は、おそらく BufferUsage.None を使用する必要があります。両方を試して、必要に応じてパフォーマンスの違いを確認してください。

于 2012-02-16T19:20:56.730 に答える