DirectGraphics�AアフィリエイトDirectGraphics�A前回作ったCLKsDGクラスに新たな機能を追加します。今回は画面上に四角いポリゴン(正確には三角をふたつ)描画して、多少描画っぽいことをして見ます。これが出来ないと、画像の表示なんかも無理なので必要なステップです。ハイレベルD3DCLKsへトップDirectXとは?環境構築DirectInput�@DirectGraphics�@DirectGraphics�ADirectGraphics�BDirectGraphics�C3D画面を描くということDirect3Dを使えば3Dで描画できると思っている方は多いはず。確かにそうですが、何もDirect3Dを使わなくても自分で3D描画をすること可能です。(まぁ、計算が重くてやってられないと思いますが)Direct3Dは3D座標空間内のオブジェクトを2D座標へと計算して置き換え(これをグラボにまかせていますが)2Dの画像を画面上に表示しているに過ぎません。最終的には2Dなのです。今回は、Direct3Dを使って2Dの四角形を描画してみます。2Dの描画をするには、Direct3Dへ3Dから2Dへ座標変換したあとのデータですよ〜と偽って情報を渡してやればその通り2Dの描画を行ってくれます。Direct3Dを使って色々な表示を行う上では、この「色々な計算を行って最終的には2D座標になったデータを描画しているんだ」という感覚が結構重要になってくると思います。3Dは便利な道具ですが、ただの計算に過ぎません。今回のサンプルプログラム前回(DirectGraphics�@)で作った画面を塗りつぶすプログラムに手を加え、四角いポリゴンを描画します。ついでに頂点色をいじってグラデーションもさせてみましょう。Direct3DSample2左の画面が今回のサンプルプログラムです。グラデーションがかかった四角形と一色で塗られた四角形がクルクル回っています。グラデーションのかかった四角はただのサンプルで、実際は1色で塗られたほうが実用的でしょう。サンプルプログラム(dgsample2.lzh)プロジェクトは前回のものに改造を加えるので、前回のコードをベースに作っていきます。DirectGraphics�Aのサンプルプログラムをダウンロードして置いてください。Direct3Dの頂点の話3Dに興味のある方なら知っていると思いますが、3次元の物体は頂点の座標と面の情報で構成されています。頂点3つで三角形(面)を表現し、それをいくつも描画することで、ある物体を描画していきます。実際には3次元の座標を複雑な計算で2次元の座標へ写し、その変換後の三角形を2次元平面上に描画します。冒頭でも触れましたが、今回は「Direct3Dへ3Dから2Dへ座標変換したあとのデータですよ〜と偽って情報を渡す」方式で2次元座標の好きな位置に四角形を描画します。Direct3Dではどの状態まで変換したデータなのかを頂点のフォーマットで判断しています。テクスチャー座標・頂点カラーなど多くの情報を含むことになります。このように、Direct3Dの頂点フォーマットは非常に複雑なものなのです。頂点の描画手順(2Dの場合)さて、3D関連の薀蓄はこのくらいにしておいて、今回メインの2Dの描画方法について紹介します。2Dつまり座標変換をDirect3Dに任せない場合は以下のような手順をとります。Direct3Dで描画を行う場合、頂点情報の配列をそのまま渡して描画をすることはできません。データ配列は必ず頂点バッファ(VertexBuffer)というものに書き込んでから、デバイスのDrawPrimirivesメソッドへ渡して描画を行います。配列と頂点バッファの生成は一度やっておけば十分なので、今回はコンストラクタの初期化部分に書いておくことにします。�B頂点データの書き込み〜�Dはどのような場合も全く同じ手順で実行するためこれだけをメソッドにまとめて、座標を渡すだけで描画してくれるようなメソッドを作ることにします。配列・頂点バッファの生成まずは、頂点配列とそれを書き込む頂点バッファの生成です。以下のコードをCLKsDGクラスの変数宣言部(フィールド)とコンストラクタに追加してください。Pool.Managed);頂点の型は「CustomVertex.TransformedColoredTextured」というものを使います。この型の頂点は、すでに座標変換された座標(つまり2D)と頂点の色、そしてテクスチャーの座標を保持します。テクスチャー座標は画像を表示する際に必要となりますので、将来を見越してこの型の頂点を使うことにました。頂点バッファはどのようなフォーマットの頂点でも「VertexBuffer」型のオブジェクトを使います。この二つはprivateのインスタンス変数として宣言しておいてください。オブジェクトの生成は通常通りnewを使って行います。今回は四角形を描画するので4つ分の頂点配列を生成します。頂点バッファのコンストラクタは少々面倒で、書き込む予定の頂点のフォーマットとその数、使用するDirect3Dデバイスなどを渡します。引数には、頂点型を、第二引数には書き込む頂点の数(今回は4)、第三引数にはDirect3Dデバイス、第五引数には書き込む頂点データのフォーマットを渡しください。typeof(〜)で「System.Type」型を取得することがでます。そのほかの引数についてはこういうものだと覚えておいてください。これで、頂点バッファの生成は完了します。頂点バッファへの書き込み手順と前後しますが、頂点配列のデータを頂点バッファへと書き込む方法を先に紹介します。verts)」メソッドをCLKsDGクラスに追加します。CustomVertex.TransformedColoredTextured.Format;//描画device.DrawPrimitives(PrimitiveType.TriangleStrip,0,2);}DrawPrimitivesを使って描画するところまで書いてありますが、それはあとで説明します。前半の頂点バッファへの書き込みです。ManagedのDirect3Dでは〜バッファと呼ばれるものがいくつかありますが、大体が「GraphicsStream」オブジェクトを使って書き込みます。VertexBufferの「Lock()」メソッドを呼ぶとGraphicsStream型のインスタンスが返されます。Lockの引数も色々と機能があるのですが、取り合えず全て0で問題ないでしょう。取得したGraphicsStreamの「Write」メソッドでVertexBufferに頂点データを書き込み、頂点バッファを「Unlock」します。頂点バッファへの書き込みはロックされている間しかできません。先ほどのコードの後半部分です。Direct3Dで何かを描画する際には、描画メソッドに直接それを渡すのですはなく、デバイスに値をセットしてそのあと描画メソッドを呼ぶという形をとります。CustomVertex.TransformedColoredTextured.Format;」でセットしています。厄介なのが、頂点バッファはメソッドで設定して、フォーマットはプロパティーに代入するところですね。このように、Direct3Dデバイスを描画前に準備しておくのです。デバイスの準備が終わったらようやく描画メソッドの「DrawPrimitives」を呼びます。引数にはプリミティブのタイプと、描画に使う頂点データの開始インデックス、描画する三角形の数を渡してやります。プリミティブのタイプについては、もっと高度な話が出てきたときにまとめて紹介することにしましょう。今回は「TriangleStrip」を渡してください。手順が逆になりましたが、頂点座標の設定をします。全て同じ色の四角形を描画するメソッドを作りましょう。color.ToArgb();}this.drawRectPrim(verts);}四角形の中心座標(x,y)と大きさ(w,h)、塗りつぶす色(color)を渡してやるとそのとおりに描画する「DrawBox」メソッドバージョン1です。受け取った引数から適切な座標を算出し、最後に先ほど作った「drawRectPrim」メソッドに渡して描画しています。TransformedColoredTextured型の頂点には頂点座標(X,Y,Z)、頂点カラー(Color)、テクスチャー座標(Tu,Tv)があり、それら全てに値を設定します。頂点座標には中心座標と大きさから計算した適切な値を代入していきます。今回は変換後の2D座標なのでZは機能しませんので0を入れておけばいいでしょう。Colorはint型の変数を代入しなくてはいけませんが、.NETのSystem.Drawing.Color構造体には「ToArgb()」というint型カラーデータを返してくれる便利なメソッドがあるのでそれを使って設定します。テクスチャー座標については、次回説明します。今回は適当に値を入れてください。頂点配列の何番目にどこの座標を入れてもちゃんと描画してくれるというものではありません。四角を描画するといっても実際は三角を二つ描画しているだけで、三角形の作り方を間違えてしまうと変な形の図形が描かれてしまいます。どの順番で描くかはDrawPrimitivesのときに指定したプリミティブタイプで決定するのですが、ここでは取り合えず「0に左上」「1に右上」「2に左下」「3に右下」の座標をセットしてください。詳しい話はまたいつか...(ためしに代入先を変えて実行してみるといいと思います)頂点カラーを変更さて、先ほどのメソッドでは頂点カラーを全て同じに設定してみましたが、全てばらばらにすることもできます。すると、各頂点間で補完された色がグラデーションで塗られます。このサンプルがDrawBoxのオーバーロードメソッドとして実装してありますので、サンプルをダウンロードしてご覧ください。解説するほどのことでもないので。作ったメソッドの呼び出し最後に、今まで作ったメソッドを呼び出して描画します。サンプルでは前回同様Mainメソッド内に作ったループの中で処理を行っています。{//メインループ//講座で紹介したFPS安定タイマーを使用しています。wait;}Application.DoEvents();}}ポリゴンの描画の部分が今回追加したところです。DrawBoxメソッドに座標を渡してやるだけで好きなところに、好きなサイズの四角形を描画できます。DirectXは一つの仕事をするのに同じようなコードをたくさん書かなくてはいけないことが多いので、このようにメソッドにまとめておくとプログラムするのが楽になりますね。前回やったとおり、Begin→描画→End→Presentの順で呼んでいるのが分かると思います。まとめ今回は概念的に重要なことが色々とありました。3Dは単に計算した座標を2Dとして描画しているだけということ。次に、DirectXでは必ずバッファというものにデータを書き込んでから使用すること。描画はデバイスの前準備をしてから行うことです。3Dの物体を描画する際にはこの概念が非常に重要になりますので、頭の隅にでも置いておくと良いかと思います。次回は、今回作った四角形の上に画像を貼り付けてみます。いわゆるテクスチャーという奴です。これが出来れば、かなりゲームらしいものが作れそうですね。