前回は画面に表示させる頂点をデータとして用意したので、今回はそれをGPUにも読んで解釈できるように、読み方(ヘルプ)を伝える処理を扱っていきます。
1,頂点の構成情報をまとめる意味とは
前回、頂点一つ一つを構造体としてまとめてデータを作成しました。それを実際に三角形の描画を行うGPUに転送する必要があります。
しかし、転送するときは頂点一つ一つを区切ってわかるように書き込まれるのではなく、すべての頂点が連続してメモリに書き込まれていきます。また座標や色等のデータも続けて書き込まれるために、もはやデータが送られてきたGPUにはどこをどう読めばいいのかわからない状態になってしまいます。
それでもGPUに、読み方の指南書を渡してあげれば話は別です。上図のような情報を与えておけば「0~12の位置に座標が書いてあって、12~28には色が書いてあるんだな」と解釈できるわけです。
そのため、頂点の座標や色がどの部分に書き込まれているのかを事前にGPUに伝えることが必要となるのです。今後はその情報のことを「頂点の構成情報」と呼びますが、まずはその情報の作り方から見て行きましょう。
2,頂点の構成情報を作る
頂点の構成情報を作るためには、まず頂点の構成要素(座標や色)一つ一つがどこに書き込まれていて、どんな役割を持つのかをVertexElementを作成して決めていきます。
これがVertexElementのコンストラクタです。いま気にするべきは2,3,5行目です。
- 2行目には、データが始まる番地を書く
例えば、座標はこの表でいうと「0」番目から始まっています。ですので座標用のVertexElementを作成するときは、2行目の引数を「0」に設定するわけです。色でしたら「12」になりますね - 3行目には、データの型を書く
データの型は、C#でいうint,float,string等と同じものです。3つ要素(xyz)があるものなら「.Float3」と、4つ要素(rgba,xyzw)があるものなら「.Float4」と設定します。つまり座標なら3の方で、色なら4ですね。 - 4行目には、使用目的を書く
座標だったら「Position」とか、色だったら「Color」と書いておきます。まんまです。
まとめると以下の様な定義をしてあげれば良いわけです。
//座標用
new VertexElement(0, 0, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Position, 0)
//色用 new VertexElement(0, 12, DeclarationType.Float4, DeclarationMethod.Default, DeclarationUsage.Color, 0)
次に、作った情報をすべて配列にまとめます。その際、配列の最後の要素には終わりの合図としてVertexElement.VertexDeclarationEndをいれておきます。作った配列は、前回作った頂点構造体の中に入れておくと扱いが楽です。
[StructLayout(LayoutKind.Sequential)]
public struct PositionColor
{
public Vector3 Position;
public Vector4 Color;
public static readonly VertexElement[] Elements =
{
new VertexElement(0, 0, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Position, 0),
new VertexElement(0, 12, DeclarationType.Float4, DeclarationMethod.Default, DeclarationUsage.Color, 0),
VertexElement.VertexDeclarationEnd
};
}
ここまでで作ったVertexElement配列を使って、VertexDeclarationというものを作成します。これがGPUに与える指南書になります。VertexDeclarationは、Direct3D9デバイスを初期化してからでなければ作れません。
VertexDeclaration vertexDec = new VertexDeclaration(D3Device, PositionColor.Elements);
4,まとめ
GPUには、頂点データを連続的に書き並べたバイト列のみが転送されてくるため各要素の位置や意味をそれだけでは解釈することができません。
そこで、あらかじめ解釈するためのヘルプのようなものを渡しておくことで、GPUにも頂点の意味を理解することが可能になります。今回は、そのヘルプの作成の仕方を扱いました。
次回は、解釈の仕方が分かったGPUに頂点データを送ってみようと思います。
P.S.
今回が一番の山場だったので次回は今回苦労した分楽になる予定?