DirectX Graphicsでの最も少ない頂点情報で表現されるポリゴンは三角形であり、3個の頂点情報だけで描画できる。DirectX Graphicsにおけるポリゴンの最小単位は三角形となっている。

ポリゴンの頂点座標は(x、y、z)で表わされる。3つの頂点座標を用意し、それぞれの頂点を線で結べば三角形ができる。作成された三角形は次のような特徴を持つ。
つまり、3つの頂点の奥行きをすべて同じ値にすれば、2Dの画像になることが分かる。
では実際に三角形ポリゴンをウィンドウに表示する方法を解説する。手順は次のとおり。
4章1で作成したプログラム(このページの上からもダウンロードできる)を上記手順どおりに編集し、三角形ポリゴンを表示してみる。
頂点座標を扱うために必要なものを準備する。
// マクロ #define WINMODE FALSE // ウィンドウモードの指定(TRUE:ウィンドウモード/FALSE:フルスクリーン) #define SCREEN_WIDTH 640 // ウィンドウの幅 #define SCREEN_HEIGHT 480 // ウィンドウの高さ /* ゲームの状態を識別する(フレーム番号) */ #define START_INIT 0 #define START_FRAME 1 #define GAME_INIT 10 #define GAME_FRAME 11 /* 頂点フォーマット(基本形)*/ #define FVF_TLVERTEX (D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1) // 構造体の宣言 /* 頂点構造体 */ typedef struct _TLVERTEX { float x, y, z; //位置情報 float rhw; //頂点変換値 D3DCOLOR color; //頂点カラー float tu, tv; //テクスチャ座標 } TLVERTX, *LPTLVERTEX; // プロトタイプ宣言 LRESULT CALLBACK WinProc(HWND, UINT, WPARAM, LPARAM); // Windows関数 BOOL InitApp(HINSTANCE, int); // ユーザー関数 HRESULT InitDX8(void); // DirectX8初期化処理 void ReleaseD3D(void); // DirectX8開放処理 void ResetWindow(void); // ウィンドウ再生成処理 BOOL UpdateFrame(void); // ゲームメイン処理 void StartInit(void); // スタート画面初期化処理 void StartFrame(void); // スタート画面処理 // グローバル変数 HWND hWnd; // ウィンドウハンドル BOOL g_appActive = FALSE; // ウィンドウの状態 char szWinName[] = "Exer004"; // ウィンドウクラス用文字列 char szWinTitle[] = "DirectX Graphicsでの2D表示"; // ウィンドウクラス用文字列 LPDIRECT3D8 gl_lpD3d = NULL; // Direct3D8インターフェイス LPDIRECT3DDEVICE8 gl_lpD3ddev = NULL; // Direct3DDevice8インターフェイス D3DPRESENT_PARAMETERS gl_d3dpp; // ディスプレイパラメータ BYTE g_FrameNo = START_INIT; // フレーム選択用 BYTE gl_KeyTbl[256]; // キーボードの状態を格納 TLVERTX VertexDataTbl[3]; // 頂点情報配列
1で作成した構造体の型を持つ構造体変数(要素数3の配列)を宣言し、頂点座標をセットする。今後の使い勝手を考え、頂点座標セット用の関数を作成した。
// プロトタイプ宣言 LRESULT CALLBACK WinProc(HWND, UINT, WPARAM, LPARAM); // Windows関数 BOOL InitApp(HINSTANCE, int); // ユーザー関数 HRESULT InitDX8(void); // DirectX8初期化処理 void ReleaseD3D(void); // DirectX8開放処理 void ResetWindow(void); // ウィンドウ再生成処理 BOOL UpdateFrame(void); // ゲームメイン処理 void StartInit(void); // スタート画面初期化処理 void StartFrame(void); // スタート画面処理 void InitVertex(LPTLVERTEX); // 頂点情報格納 ・ ・ ・ //---------------------------------------------------------------------------------------- // 関数名 : InitVertex() // 機能概要: 頂点データを格納する //---------------------------------------------------------------------------------------- void InitVertex(LPTLVERTEX v) { //頂点配列をゼロクリア ZeroMemory(v, sizeof(TLVERTX)); //---頂点A1のデータ定義 v[0].x = 100.0f; // 頂点X座標 v[0].y = 100.0f; // 頂点Y座標 v[0].z = 0.0f; // 頂点Z座標 v[0].rhw = 1.0f; // 2Dを扱うときの値 v[0].color = D3DCOLOR_XRGB(0,0,255); // 頂点色 //---頂点A2のデータ定義 v[1].x = 200.0f; v[1].y = 200.0f; v[1].z = 0.0f; v[1].rhw = 1.0f; v[1].color = D3DCOLOR_XRGB(0,0,255); //---頂点A3のデータ定義 v[2].x = 0.0f; v[2].y = 200.0f; v[2].z = 0.0f; v[2].rhw = 1.0f; v[2].color = D3DCOLOR_XRGB(0,0,255); }
セットした頂点情報を持つポリゴンを描画する。現在のプログラムにはスタート処理しかないため、スタート画面初期化処理で頂点座標をセットし、スタート画面処理でポリゴンを描画する。
//-----------------------------------------------------------------------------
// 関数名 : StartInit()
// 機能概要: スタート画面初期化処理
//-----------------------------------------------------------------------------
void StartInit(void)
{
//--------------------------------------------------- 各変数の初期化
// 頂点データを格納する
InitVertex(VertexDataTbl);
//--------------------------------------------------- フレームナンバーセット
g_FrameNo = START_FRAME;
}
//-----------------------------------------------------------------------------
// 関数名 : StartFrame()
// 機能概要: スタート画面処理
//-----------------------------------------------------------------------------
void StartFrame(void)
{
// 頂点フォーマットを設定
gl_lpD3ddev->SetVertexShader(FVF_TLVERTEX);
// 三角形ポリゴンをバックバッファに転送
gl_lpD3ddev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 1, VertexDataTbl, sizeof(TLVERTX));
// リターンキーが押されたら、ゲーム開始
if ( gl_KeyTbl[VK_RETURN] & 0x80 ) g_FrameNo = GAME_INIT;
}
HRESULT DrawPrimitiveUP( D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, CONST void* pVertexStriamZeroData, UINT VertexStreamZeroStride );
※動作確認
頂点情報を元にポリゴンを描画するには、頂点情報データの構造をデバイスにセットしてから描画しなければならない。
// 頂点フォーマットを設定
gl_lpD3ddev->SetVertexShader(FVF_TLVERTEX);
// 三角形ポリゴンをバックバッファに転送
gl_lpD3ddev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 1, VertexDataTbl, sizeof(TLVERTX));
しかし、頂点情報データ構造(構造体)自身はゲーム・ループ中に変更されることはありえない。よって、頂点フォーマットの設定はシーン開始直後に行えばよい。つまり、スタート画面処理やゲーム画面処理で行うのではなく、UpdateFrame関数内で実行すればよい。
//-----------------------------------------------------------------------------
// 関数名 : UpdateFrame()
// 機能概要: ゲームメイン処理
//-----------------------------------------------------------------------------
BOOL UpdateFrame(void)
{
/* 現在のキー情報を取得 */
if ( !GetKeyboardState(gl_KeyTbl) ) {
MessageBox(hWnd, "キー情報の取得に失敗", "ERROR", MB_OK);
return (FALSE);
}
/* 画面のクリア */
gl_lpD3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(255,255,255), 0.0, 0);
/* シーン開始 */
gl_lpD3ddev->BeginScene();
/* 頂点フォーマットを設定 */
gl_lpD3ddev->SetVertexShader(FVF_TLVERTEX);
/* 処理の振り分け */
switch ( g_FrameNo ) {
case START_INIT:
// スタート画面を表示する前に実行する初期化関数を実行
StartInit();
case START_FRAME:
// スタート画面表示処理関数を実行
StartFrame();
break;
case GAME_INIT:
// ゲーム画面を表示する前に実行する初期化関数を実行
case GAME_FRAME:
// ゲーム画面表示処理関数を実行
break;
default:
MessageBox(hWnd, "g_FrameNoの値が例外です。", "ERROR", MB_OK);
return (FALSE);
}
/* シーン終了 */
gl_lpD3ddev->EndScene();
/* フリップ */
gl_lpD3ddev->Present(NULL, NULL, NULL, NULL);
return (TRUE);
}
//-----------------------------------------------------------------------------
// 関数名 : StartFrame()
// 機能概要: スタート画面処理
//-----------------------------------------------------------------------------
void StartFrame(void)
{
/* 描画処理 */
// 三角形ポリゴンをバックバッファに転送
gl_lpD3ddev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 1, VertexDataTbl, sizeof(TLVERTX));
// リターンキーが押されたら、ゲーム開始
if ( gl_KeyTbl[VK_RETURN] & 0x80 ) g_FrameNo = GAME_INIT;
}
※上記修正を行い、正しく表示されることを確認すること!!
| BACK(ポリゴンについて) | NEXT(ポリゴンの描画(四角形)) |