カウンタ

  2Dポリゴンの表示

Google
▲探し物はこちら

 Direct3D なので3Dをやるべきなのですが、ちょっと説明することが多くなってしまうので、最初は認識しやすい2Dポリゴンを使って説明します。

2Dポリゴンの表示

 下のリンクから今回のプロジェクトをまるごとダウンロードできます。

ファイル名 言語 サイズ バージョン
polygon2d_cs_1_1.zip C# 21KB 1.1
polygon2d_vb_1_1.zip VB.NET 26KB 1.1
polygon2d_cpp_1_1.zip C++/CLI 12KB 1.1

 今回のメインコードファイルを載せます。重要なコードを赤色で表示させています

MainSample.cs

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;

namespace MDXSample
{
    /// <summary>
    /// メインサンプルクラス
    /// </summary>
    public partial class MainSample : IDisposable
    {
        /// <summary>
        /// 座標変換済み頂点データ
        /// </summary>
        private CustomVertex.TransformedColored[] _vertices = new CustomVertex.TransformedColored[3];


        /// <summary>
        /// アプリケーションの初期化
        /// </summary>
        /// <param name="topLevelForm">トップレベルウインドウ</param>
        /// <returns>全ての初期化がOKなら true, ひとつでも失敗したら false を返すようにする</returns>
        /// <remarks>
        /// false を返した場合は、自動的にアプリケーションが終了するようになっている
        /// </remarks>
        public bool InitializeApplication(MainForm topLevelForm)
        {
            // フォームの参照を保持
            this._form = topLevelForm;

            try
            {
                // Direct3D デバイス作成
                this.CreateDevice(topLevelForm);

                // フォントの作成
                this.CreateFont();
            }
            catch (DirectXException ex)
            {
                // 例外発生
                MessageBox.Show(ex.ToString(), "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }

            // 頂点データの設定
            this._vertices[0] = new CustomVertex.TransformedColored(
                200.0f, 50.0f, 0.0f, 1.0f, Color.Red.ToArgb());
            this._vertices[1] = new CustomVertex.TransformedColored(
                350.0f, 50.0f + 150.0f * (float)Math.Sqrt(3), 0.0f, 1.0f, Color.Blue.ToArgb());
            this._vertices[2] = new CustomVertex.TransformedColored(
                50.0f, 50.0f + 150.0f * (float)Math.Sqrt(3), 0.0f, 1.0f, Color.Green.ToArgb());

            return true;
        }

        /// <summary>
        /// メインループ処理
        /// </summary>
        public void MainLoop()
        {
            // 描画内容を単色でクリア
            this._device.Clear(ClearFlags.Target, Color.DarkBlue, 1.0f, 0);

            // 「BeginScene」と「EndScene」の間に描画内容を記述する
            this._device.BeginScene();


            // 描画する頂点のフォーマットをセット
            this._device.VertexFormat = CustomVertex.TransformedColored.Format;

            // 描画
            this._device.DrawUserPrimitives(PrimitiveType.TriangleList, 1, this._vertices);


            // 文字列の描画
            this._font.DrawText(null, "2Dポリゴン表示", 0, 0, Color.White);


            // 描画はここまで
            this._device.EndScene();

            // 実際のディスプレイに描画
            this._device.Present();
        }

        /// <summary>
        /// リソースの破棄をするために呼ばれる
        /// </summary>
        public void Dispose()
        {
            // フォントのリソースを解放
            if (this._font != null)
            {
                this._font.Dispose();
            }

            // Direct3D デバ��スのリソース解放
            if (this._device != null)
            {
                this._device.Dispose();
            }
        }
    }
}

 では、赤文字の部分を説明していきます。MainSamplePartial.cs ファイルのコードはこちらです。


 まず最初にポリゴンについて簡単に説明します。詳しいことはヘルプや書籍を参考にしてください。

 ポリゴンはトップの画像を見てもらうとおり、3Dの三角形の面のことです(今回は2Dですが)。3D上でよくモデルが動くシーンなどを見かけることが多いですが、あれは非常に多くのポリゴンを組み合わせて形作っているのです。
 この三角形ポリゴンを構成するには頂点データというものが必要です。頂点データには位置や色など複数のデータを持たせることでポリゴンを実現させています。

ポリゴン

 上でポリゴンは三角形と言いましたが、四角形や多角形もポリゴンといいます。でも大抵の場合最小単位のポリゴンは三角形です。


/// <summary>
/// 座標変換済み頂点データ
/// </summary>
private CustomVertex.TransformedColored[] _vertices = new CustomVertex.TransformedColored[3];

 上記で説明したとおり、ポリゴンを成り立たせるには頂点データが必要なので、それを持つデータを定義しなければなりません。大抵ひとつの頂点には複数のデータを持たせることが多いので構造体で定義することが多いです。

 しかし、Managed DirectX では一般的に使われる頂点データの型はすでに定義されていることが多いです。今回使用する「CustomVertex.TransformedColored」もそのうちのひとつで、座標変換済み頂点データとして使われます。

 座標変換済み頂点データというなにやら難しい言葉が出てきましたが、今は深く考える必要はありません。簡単に言い直せば2Dのポリゴンを表示させるのに使えるということが分かればいいです。逆にこの構造体は3D空間上では使用できません。

 CustomVertex.TransformedColored は下のようなデータを持っています。

CustomVertex.TransformedColored 構造体

X スクリーン座標での位置X
Y スクリーン座標での位置Y
Z 深度値。通常 0.0 ~ 1.0
Rhw 同次 w の逆数。通常 1.0
Color 頂点の色

 今回は三角形ポリゴンをひとつだけ表示するので、三角形に必要な頂点3つ分の構造体を作成します。


// フォントの作成
this.CreateFont();

 フォントの作成をメソッドにまとめました。


///// 頂点データの設定 /////
this._vertices[0] = new CustomVertex.TransformedColored(
    200.0f, 50.0f, 0.0f, 1.0f, Color.Red.ToArgb());
this._vertices[1] = new CustomVertex.TransformedColored(
    350.0f, 50.0f + 150.0f * (float)Math.Sqrt(3), 0.0f, 1.0f, Color.Blue.ToArgb());
this._vertices[2] = new CustomVertex.TransformedColored(
    50.0f, 50.0f + 150.0f * (float)Math.Sqrt(3), 0.0f, 1.0f, Color.Green.ToArgb());

 ここで3つ頂点データを設定しています。各パラメータは上にある表の通りですが、簡単に説明します。

CustomVertex.TransformedColored コンストラクタ

CustomVertex.TransformedColored 構造体を作成
xvalue そのままスクリーン座標での位置Xになります。一番左が 0 で右に行くほど大きくなります。
yvalue そのままスクリーン座標での位置Yになります。一番上が 0 で下に行くほど大きくなります。
zvalue 深度値ですが今回関係ないので 0.0f でいいです。
rhwvalue 同次 w の逆数という分かりにくい表現ですが、気にせず 1.0f でいいです。
c 頂点の色。頂点と頂点の間の色は綺麗に線形補間されます。

 位置指定で Math.Sqrt という平方根を使用していますが、綺麗な正三角形になるように計算しているだけなのであまり気にしないでください。

 色を指定するのに「Color」構造体で定義されている色を使用していますが、「int」に変換しないといけないので「Color.ToArgb」メソッドを使用して変換してます。


// 描画する頂点のフォーマットをセット
this._device.VertexFormat = CustomVertex.TransformedColored.Format;

// 描画
this._device.DrawUserPrimitives(PrimitiveType.TriangleList, 1, this._vertices);

 ようやくメインループの描画部分です。ここでは上の2行を使って描画しています。

 まず最初にデバイスにどのような頂点データを使用するかを示さなければなりません。これには Device.VertexFormat に柔軟な頂点フォーマットを指定します。これは CustomVertex.TransformedColored.Format ですでに定義されているのでそれを渡しています。

 次にポリゴンのレンダリングを行います。各引数の意味は下のとおりです。ちなみに描画とレンダリングはほとんど同じ意味で使用されます。

Device.DrawUserPrimitives メソッド

指定した頂点データでポリゴンを描画します。
primitiveType レンダリングするプリミティブのタイプを指定します。プリミティブとは点や線、面のことで、PrimitiveType 列挙型から指定します。今回は三角形ひとつなので「PrimitiveType.TriangleList」を指定しています。
primitiveCount レンダリングするプリミティブの数です。今回は三角形ひとつなので「1」を指定。
vertexStreamZeroData 使用するユーザーメモリ頂点データ。作成した頂点データを渡します。

 ちなみに「PrimitiveType」を図で表す下のようになります。

PrimitiveType
※この図は表裏関係を考慮していません。あくまでもイメージです。

その他の関連情報です▼