前回の『初めてのDirectX9』でDirectXの初期化が完了しました。
今回はついに実際に画面に絵を出してみようと思います。
いきなり最初から3Dは難しいので先ずは2Dの単純なポリゴンを描画していきます。
初めての描画
描画に最低限必要なものとして頂点バッファというものがあります。
頂点バッファとは描画する座標や色、テクスチャーUV等の様々な指定をするためのバッファです。
今回は必要最低限のものだけを使用して実装していきます。
頂点フォーマット
#define FVF_CUSTOM2D (D3DFVF_XYZRHW | D3DFVF_DIFFUSE) struct SimpleVertex { float x, y, z; float rhw; DWORD color; };
頂点フォーマットとしては単純で座標とカラーのみを指定しています。
x, y, zで表示する座標を指定します。 rhwはトランスフォーム済み頂点だという事を表すために必要な値になります。
colorはそのままでカラーを指定する値です。
FVF_CUSTOM2Dに関しては後述します。
単純な描画処理
void Render(void) { IDirect3DDevice9* pDevice = GetDirect3DDevice(); // 描画シーンの開始 pDevice->BeginScene(); // バックバッファのクリア pDevice->Clear(0, NULL, D3DCLEAR_TARGET, 0x00000000, 1.0f, 0); const SimpleVertex vertices[4] = { { 10.0f, 10.0f, 0.0f, 1.0f, 0xffffffff }, { 50.0f, 10.0f, 0.0f, 1.0f, 0xffffffff }, { 10.0f, 50.0f, 0.0f, 1.0f, 0xffffffff }, { 50.0f, 50.0f, 0.0f, 1.0f, 0xffffffff }, }; // 頂点フォーマットの指定 pDevice->SetFVF(FVF_CUSTOM2D); // 描画 pDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, vertices, sizeof(SimpleVertex)); // 描画シーンの終了 pDevice->EndScene(); // モニターに絵を表示する pDevice->Present(NULL, NULL, NULL, NULL); }
今回の処理では黒い背景の画面で左上の方に白い四角形を1つ表示するプログラムになっています。
Render関数を呼び出すと(10, 10), (50, 50)の範囲に四角形が描画されます。
Render関数はWinMainのメインループ内で呼び出すことになります。
// メインループ while( !IsQuitMessage() ) { // メッセージの更新が無い時にゲームの処理を動かす if( !UpdateWindowMessage() ) { // ゲームの更新や描画処理はここで行う Render(); } }
次のページでは各処理の説明をしていきます。
描画の手順
描画の処理を行う際の手順として下記の事が必要です。
1.描画シーンの開始と終了
pDevice->BeginScene(); // ~描画処理~ pDevice->EndScene();
DirectX9における決まりとして描画処理をBeginSceneとEndSceneの間で行うする必要があります。
この間以外では描画処理を行うことが出来なくなっています。
試しにDrawPrimitiveUP関数の呼び出しをEndSceneの後にしてみると描画されないことが確認できます。
2.バックバッファのクリア(背景色の設定)
pDevice->Clear(0, NULL, D3DCLEAR_TARGET, 0x00000000, 1.0f, 0);
今回の処理ではバックバッファを黒く塗りつぶしています。
D3DCLEAR_TARGETは現在の描画ターゲットをクリア対象として指定しています。
D3DCLEAR_ZBUFFERやD3DCLEAR_STENCILを|(OR演算子)で指定することでDepthやStencilを同時にクリアすることも出来ます。
0x00000000は色の指定になっていて上位から8bit毎にA, R, G, Bという順番で指定が出来ます。
3.頂点フォーマットの構造の指定
#define FVF_CUSTOM2D (D3DFVF_XYZRHW | D3DFVF_DIFFUSE) pDevice->SetFVF(FVF_CUSTOM2D);
D3DFVF_XYZRHWを指定するとトランスフォーム済みの座標を含みます。
D3DFVF_DIFFUSEを指定すると頂点カラーを含みます。
4.描画処理
pDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, vertices, sizeof(SimpleVertex));
今回は四角形を1つ描画しています。
D3DPT_TRIANGLESTRIPは頂点を描画する時のルールを指定しています。
今回は単純を四角形を1つ描画する時に楽なD3DPT_TRIANGLESTRIPを指定しています。
2は描画するプリミティブの数を指定しています。
今回は四角形ですので三角形のポリゴンが2つで成り立っているため2になります。
次のVertexは頂点データ、最後のsizeof(SimpleVertex)は頂点1つ辺りのサイズを指定しています。
5.モニターへの反映
pDevice->Present(NULL, NULL, NULL, NULL);
描画処理が終了してバックバッファの絵が完了した後はモニターにそれを表示する必要があります。
Presentではフリップを行っています。
フリップとはバックバッファを実際に表示を行うプライマリバッファに転送する処理の事です。
その為、Presentを呼び出さない限りは描画した内容が画面に表示されません。
何故、一度バックバッファに書き込んでから転送して表示しているのかと言うと
直接プライマリバッファを書き換えて描画途中の絵が画面に表示されてしまう現象を防ぐためです。
これで矩形の描画が出来るようになりました。
矩形が描画できるようになればブロック崩しや簡単なゲームであれば作ることもできます。
次回は頂点バッファとインデックスバッファについて書いていきます。