4.3D三角形の描画


0.はじめに

私事で間が開いてしまいましたが、今回は3Dの三角形を描画します。
前回との違いは、頂点データ、頂点宣言と、
3Dで描画するために必要になるワールド、ビュー、プロジェクションの各行列の設定になります。

1.頂点データ、頂点宣言

頂点データ、頂点宣言について前回は2D描画を行う為に座標変換済みの座標と色情報を持っていると宣言していましたが、
今回は3D描画を行う為に座標変換前の座標と色情報を持っていると宣言を変更しました。
プログラムでは次のようになりました。
3D用頂点宣言
D3DVERTEXELEMENT9 decl[] =
{
    {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
    {0, sizeof(float)*3, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
    D3DDECL_END()
};
次に頂点データはこんな感じになりました。
頂点データ
MyVertex verts[] =
{
    { -1.0f,-1.0f, 0.0f, 0xff000000, },
    { 1.0f,-1.0f, 0.0f, 0xff000000, },
    { 0.0f, 1.0f, 0.0f, 0xffffffff, },
};
次に3Dで描画するために必要になるワールド行列の設定を見ていきます。

2.ワールド行列の設定

まずワールド行列とは何かというと、今回でいうと三角形を空間のどこに、どんな向きで、
どんな大きさで配置するかというデータになります。
ゲームであればこの値を変更することでPCの移動や向きの変更などを表現できます。
今回はDirectXのサンプル通りに単純にY軸回転をさせています。
行列の設定
D3DXMATRIX matWorld;
D3DXMatrixRotationY(&matWorld, timeGetTime() / 150.0f);
pDev->SetTransform(D3DTS_WORLD, &matWorld);
D3DXMATRIXはDirectXのライブラリで定義されている行列型です。
内部的には単純なfloatの4x4配列なので自作行列型でも代用は出来ますが、
DirectXで行列を扱う場合はこれを使用すると便利かもしれません。
D3DXMatrixRotationY()はDirectXのライブラリで定義されているY軸回転行列の設定関数です。
この関数を使うことである点をY軸回転させる行列を手に入れることが出来ます。
SetTransform()はDirectXのライブラリで定義されている変換行列設定関数です。
この関数を使うことでワールド行列、ビュー行列、プロジェクション行列の各行列を設定することができます。
今回はSetTransform(D3DTS_WORLD, &matWorld)とすることで、
上で作っておいた回転行列をワールド行列に設定しています。

3.ビュー行列の設定

とここまでで3Dの空間に三角形を配置できたので、次はそれを写す為のカメラを設定します。
3D描画でカメラを設定する場合はビュー行列を使用します。
設定する為に必要なものはカメラ位置注視点カメラの上方向の3つになります。
今回は空間の中に三角形が一つだけあるだけなので、カメラを三角形の目の前において、
注視点を三角形の中心に設定し、カメラの上方向はY軸の正方向にしました。
カメラの設定
D3DXVECTOR3 eye(0.0f, 0.0f,-5.0f);
D3DXVECTOR3 at(0.0f, 0.0f, 0.0f);
D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);
D3DXMATRIX matView;
D3DXMatrixLookAtLH(&matView, &eye, &at, &up);
pDev->SetTransform(D3DTS_VIEW, &matView);
D3DXVECTOR3はDirectXのライブラリで定義されている3次元ベクトル型です。
今回はeye、at、upでそれぞれカメラ位置、注視点、カメラの上方向を定義するために使いました。
D3DXMatrixLookAtLH()はDirectXのライブラリで定義されている
カメラ位置、注視点、カメラの上方向を元にビュー行列を設定する為の関数です。
そしてワールド行列と同じようにSetTransform()を使ってビュー行列を設定しています。

4.プロジェクション行列の設定

とここまでで3Dの空間に三角形を配置し、それをカメラで写すことが出来ました。
次にそれを画面上にどのように表示するかの設定の為にプロジェクション行列を作成します。
設定できるものはFOV、アスペクト比、ニアクリップ、ファークリップです。
FOVは視野に関する設定でラディアン角度で設定します。この値を操作することでズームインやズームアウトが出来ます。
アスペクト比は縦横比です。640x480の画面であれば640/480=4/3=1.3333...になります。
ニアクリップファークリップでカメラからの距離によって描画するかしないかの設定が行えます。
でプログラムはこんな感じになりました。
プロジェクション設定
D3DXMATRIX matProj;
D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI/3, 1.0f, 1.0f, 100.0f);
pDev->SetTransform(D3DTS_PROJECTION, &mProj);
D3DXMatrixPerspectiveFovLH()はDirectXのライブラリで定義されているプロジェクション行列設定関数です。
今回はFOVを60度、アスペクト比を1、ニアクリップを1、ファークリップを100に設定しました。

5.描画

ここまで長々と描画の準備をしてきましたが、ようやく本題の描画です。
と言いながらもう一つ描画前に準備が残っていました。
今回はライティングを行わない為ライティングを切っておきます。
ライティングの未使用設定
pDev->SetRenderState(D3DRS_LIGHTING, FALSE);
でようやく描画です。描画自体はこれまで通り頂点宣言を設定し、
使用するデータを設定し、DrawPrimitive()を呼ぶだけです。
いつも通りの描画
//頂点定義の設定
pDev->SetVertexDeclaration(pVertDec);

//使用するデータの設定
pDev->SetStreamSource(0, pVB, 0, sizeof(MyVertex));

//設定されたデータを使って描画
pDev->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 1);
とようやく3Dの三角形が描画できました。
次回はこれまでに作った3D周りの処理をクラスでまとめて扱いやすくしようかなと思います。
今回のソース。
戻る。