#region Using ステートメント
using Microsoft.Xna.Framework.Graphics;
#endregion
namespace Demo
{
///
/// 連続書き込み用の頂点バッファ管理クラス
///
///
/// 動的頂点バッファへの書き込みは書き込み先がGPUの読み込み中の場所と
/// バッティングしないよう注意する必要がある。
///
/// http://blogs.msdn.com/ito/archive/2009/03/25/how-gpus-works-01.aspx
///
/// 管理自体は簡単でも余計な変数や
/// 処理が増えるので、その処理をこのクラスで管理している。
/// DynamicVertexBufferとの違いはSetData>T<をメソッドが書き込んだ
/// オフセットを返すのでその値を以下の様に使うことができる
///
/// int offset = writableVB.WriteData( ... );
/// GraphicsDevice.SetVertexBuffer(writableVB.VertexBuffer, offset);
///
///
public class WritableVertexBuffer where T : struct
{
///
/// バッファを取得する
///
public DynamicVertexBuffer VertexBuffer { get { return vb; } }
///
/// WritableVertexBufferの生成
///
/// この頂点バッファに関連付けるグラフィックデバイス
/// この頂点バッファに格納できる最大要素数
public WritableVertexBuffer(GraphicsDevice device, int maxElementCount)
{
this.vb = new DynamicVertexBuffer(device, typeof(T), maxElementCount,
BufferUsage.WriteOnly);
this.maxElementCount = maxElementCount;
}
///
/// 頂点データの書き込み
///
/// 書き込む頂点データ配列
/// 書き込んだデータの先頭オフセット
public int WriteData(T[] vertices)
{
return SetData(vertices, 0, vertices.Length);
}
///
/// 頂点データの書き込み
///
/// 書き込む頂点データ配列
/// 書き込むデータの先頭インデックス
/// 書き込む要素数
/// 書き込んだデータの先頭オフセット
public int SetData(T[] vertices, int startIndex, int elementCount)
{
// 頂点データの書き込み
int position = currentPosition;
SetDataOptions hint = SetDataOptions.NoOverwrite;
// 最大要素数を超えるようであれば、頂点バッファの先頭に移動し、Dicardオプションを使う。
if (position + elementCount > maxElementCount)
{
position = 0;
hint = SetDataOptions.Discard;
}
// 頂点データを頂点バッファへ書き込む
int strideSize = vb.VertexDeclaration.VertexStride;
vb.SetData(position * strideSize, vertices, startIndex, elementCount, strideSize, hint);
currentPosition = position + elementCount;
return position;
}
// 実際の頂点バッファ
DynamicVertexBuffer vb;
// 現在の書き込み位置
int currentPosition;
// 最大頂点数
int maxElementCount;
}
}