[Atelier Blue アトリエブルー]HomeプログラミングManaged DirectX3D(Managed DirectX 2.0)>三角形を描く(2.0)

三角形を描く(2.0)

ここに書いてあるソースは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());
            }
        }
    }
}


変更点について

それでは変更点についてまとめていきます。

名前空間

とりあえず、「Microsoft.DirectX.Generic」と「Microsoft.DirectX.Direct3D.CustomVertex」を追加してください。「CustomVertex」は昔の場所から名前空間に昇格です。

VertexBuffer作り方

かなりの変化があります。まずは初期化です。

/// <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が正常に使用できません。

まとめ

とりあえずはこれくらいだと思います。変わったようで案外変わっていないかもしれません。でも、私から見ると前よりも合理的になったと思います。


ページの一番上へ
前のページへ 一覧に戻る 次のページへ

初版2006-3-11
[Atelier Blue アトリエブルー]HomeプログラミングManaged DirectX3D(Managed DirectX 2.0)>三角形を描く(2.0)