ここに書いてあるソースは1.1の改造版です。まずはそちらをお読み下さい。
頂点データの扱い方が変わりました。名前空間にも若干の変化があります。
using System; using System.Drawing; using System.Windows.Forms; using Microsoft.DirectX; using Microsoft.DirectX.Direct3D; using Microsoft.DirectX.Generic; using Microsoft.DirectX.Direct3D.CustomVertex; namespace Project1 { /// <summary> /// md3d1 の概要の説明です。 /// </summary> public class MD3D1 : Form { //クライアント領域のサイズ const int clientHeight = 600; const int clientWight = 800; public MD3D1() : base() { //固定サイズのフォーム this.FormBorderStyle = FormBorderStyle.FixedSingle; //サイダかボタン無し this.MaximizeBox = false; //クライアント領域サイズ this.ClientSize = new Size(clientWight, clientHeight); //ウィンドウの名前(かっこいいのを付けてあげてください) this.Text = "Direct3D-My"; } private Device device_; /// <summary> /// Direct3Dの初期化を行います。 /// </summary> /// <returns>初期化が成功したかどうか</returns> public bool DXInitialize() { try { //プレゼンテーションパラメータを作成 PresentParameters pp = new PresentParameters(); //ウィンドウモード pp.IsWindowed = true; //スワップエフェクトを設定。 pp.SwapEffect = SwapEffect.Discard; //デバイスを作成 device_ = new Device(0, DeviceType.Hardware, this.Handle , CreateFlags.HardwareVertexProcessing, pp); //#################################################追加 //頂点バッファを作成 this.creatVertex(); //#################################################ここまで //初期化成功 return true; } catch (Exception ex) { MessageBox.Show(ex.ToString()); //初期化失敗 return false; } } //#################################################追加 /// <summary> /// 頂点バッファ /// </summary> private VertexBuffer vertexBuffer_; /// <summary> /// 頂点バッファ作成関数 /// </summary> private void creatVertex() { //頂点バッファ領域を確保 vertexBuffer_ = new VertexBuffer(device_ , TransformedColored.StrideSize * 3, 0 , TransformedColored.Format, Pool.Default , new EventHandler(setVertexData)); } /// <summary> /// 何故かイベントを受け取ってから処理する /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void setVertexData(object sender, EventArgs e) { VertexBuffer vb = ((VertexBuffer)sender); TransformedColored[] verts = new TransformedColored[3]; //頂点データ verts[0].Position = new Vector4(150, 50, 0.5f, 1); verts[0].Color = System.Drawing.Color.Aqua; verts[1].Position = new Vector4(250, 250, 0.5f, 1); verts[1].Color = System.Drawing.Color.Brown; verts[2].Position = new Vector4(50, 250, 0.5f, 1); verts[2].Color = System.Drawing.Color.LightPink; //バッファをロック GraphicsBuffer<TransformedColored> gb = vb.Lock<TransformedColored>(0, 0, 0); //頂点データをバッファに書き込み gb.Write(verts); //バッファのロックを解除 vb.Unlock(); } public void Render() { if (device_ == null) return; if (this.WindowState == FormWindowState.Minimized) return; //クリア処理 device_.Clear(ClearFlags.Target, Color.Blue, 1.0f, 0); //描画開始 device_.BeginScene(); //#################################################追加 //頂点バッファをセット device_.SetStreamSource(0, vertexBuffer_, 0,TransformedColored.StrideSize); //頂点バッファのフォーマットをセット device_.VertexFormat = TransformedColored.Format; //描画 device_.DrawPrimitives(PrimitiveType.TriangleList, 0, 1); //#################################################ここまで //描画終わり device_.EndScene(); //更新 device_.Present(); } } /// <summary> /// エントリクラス /// </summary> class Program { public static void Main() { try { using (MD3D1 dxform = new MD3D1()) { //Direct3Dの初期化を実行 if (!dxform.DXInitialize()) { MessageBox.Show("Direct3Dの初期化に失敗しました。" , "初期化の失敗"); return; } //ウィンドウを表示 dxform.Show(); //メッセージループ //フォームがある間だけまわるようにする while (dxform.Created) { //描画する dxform.Render(); //たまっているメッセージを処理する Application.DoEvents(); } } } catch (Exception ex) { MessageBox.Show(ex.ToString()); } } } }
それでは変更点についてまとめていきます。
かなりの変化があります。まずは初期化です。
/// <summary> /// 頂点バッファ /// </summary> private VertexBuffer vertexBuffer_; /// <summary> /// 頂点バッファ作成関数 /// </summary> private void creatVertex() { //頂点バッファ領域を確保 vertexBuffer_ = new VertexBuffer(device_ , TransformedColored.StrideSize * 3, 0 , TransformedColored.Format, Pool.Default , new EventHandler(setVertexData)); }
VertexBuffer.VertexBuffer ( Device device, int sizeInBytes, Usage usaage, VertexFormats, Pool memoryPool, EventHandler createdEvent )
まずは「CustomVertex」が名前空間になってちょっと呼び出し方が変わっています。Usingしているので「TransformedColored」直接呼べています。
次に「sizeInBytes」というのもを設定するようになっています。これバッファの大きさを決めるものです。CustomVertexを利用する場合は「~.StrideSize * 頂点数」と指定します。
最後に「createdEvent」です。どうやらこれを使うようです。バッファの作成時に自動的に呼び出しをしてくれるので、そこで頂点データをセットします。
ここで2.0の本命「ジェネリクス」の登場です。
void setVertexData(object sender, EventArgs e) { VertexBuffer vb = ((VertexBuffer)sender); TransformedColored[] verts = new TransformedColored[3]; //頂点データ verts[0].Position = new Vector4(150, 50, 0.5f, 1); verts[0].Color = System.Drawing.Color.Aqua; verts[1].Position = new Vector4(250, 250, 0.5f, 1); verts[1].Color = System.Drawing.Color.Brown; verts[2].Position = new Vector4(50, 250, 0.5f, 1); verts[2].Color = System.Drawing.Color.LightPink; //バッファをロック GraphicsBuffer<TransformedColored> gb = vb.Lock<TransformedColored>(0, 0, 0); //頂点データをバッファに書き込み gb.Write(verts); //バッファのロックを解除 vb.Unlock(); }
まずは呼び出してもらった中で「sender」を使いやすいようにしておきます。
「verts」の所でも変化があります。「Color構造体」をセットできます。ちょっとソースコードがすっきりします。Positionは(X,Y,Z,Rhw)の順番です。この方がソースコードが見やすいかもしれません。
バッファのロックはジェネリクスを利用しています。ですが、あんまり変化ありません。見たまんまです。
ここの設定が重要です。一番見落としやすそうな所は「Device.SetStreamSource」です。
void Device.SetStreamSource( int StreamNumber, VertexBuffer streamData, int offsetInBytes, int stride )
最後の「stride」にしっかりと値をセットしないと、CustomVertexが正常に使用できません。
とりあえずはこれくらいだと思います。変わったようで案外変わっていないかもしれません。でも、私から見ると前よりも合理的になったと思います。