ここでは、実際にスケルトンプログラムにDirectX Graphicsの各処理を組み込む方法を紹介する。この授業ではまず、ウィンドウの大きさ640x480、色数16Bitのフルスクリーン・モードでDirectX Graphicsを使ってみる。
スケルトンプログラムへDirectX Graphicsの各処理を組み込む方法を、順番に解説する。
まずはヘッダファイル、このあと作成する予定の関数のプロトタイプ宣言、この後利用する予定のグローバル変数を次のように追加する。
#include <stdio.h> #include <windows.h> // WindowsAPIを使用可能にする #include <windowsx.h> #include <d3d8.h> // DirectX8ヘッダファイル #include <d3dx8.h> // D3DXヘッダファイル // マクロ #define WINMODE TRUE // ウィンドウモードの指定(TRUE:ウィンドウモード/FALSE:フルスクリーン) #define SCREEN_WIDTH 640 // ウィンドウの幅 #define SCREEN_HEIGHT 480 // ウィンドウの高さ // プロトタイプ宣言 LRESULT CALLBACK WinProc(HWND, UINT, WPARAM, LPARAM); // Windows関数 BOOL InitApp(HINSTANCE, int); // ユーザー関数 HRESULT InitDX8(void); // DirectX8初期化処理 void ReleaseD3D(void); // DirectX8開放処理 // グローバル変数 HWND hWnd; // ウィンドウハンドル char szWinName[] = "Exer002"; // ウィンドウクラス用文字列 char szWinTitle[] = "スケルトンプログラムにDirectX Graphicsを追加する"; // ウィンドウクラス用文字列 LPDIRECT3D8 gl_lpD3d = NULL; // Direct3D8インターフェイス LPDIRECT3DDEVICE8 gl_lpD3ddev = NULL; // Direct3DDevice8インターフェイス D3DPRESENT_PARAMETERS gl_d3dpp; // ディスプレイパラメータ
DirectX Graphicsの初期化を行う関数 InitDX8を作成する。以下のプログラムを、プロトタイプ宣言の順番のとおりにInitApp関数の下に作成する。
//-----------------------------------------------------------------------------
// 関数名 : InitDX8()
// 機能概要: Direct Draw オブジェクトの生成
// 戻り値 : 正常終了のとき:DD_OK、異常終了のとき:エラーコード
//-----------------------------------------------------------------------------
HRESULT InitDX8(void)
{
D3DDISPLAYMODE DispMode; // ディスプレイモード
HRESULT hr;
/* DirectX8オブジェクトの生成 */
gl_lpD3d = Direct3DCreate8(D3D_SDK_VERSION);
if( !gl_lpD3d ) { // オブジェクト生成失敗
MessageBox(hWnd, "DirectXD3D8オブジェクト生成失敗", "ERROR", MB_OK);
return E_FAIL;
}
/* DirectX8のプレゼンテーションパラメータを設定 */
// ディスプレイデータ格納構造体初期化
ZeroMemory(&gl_d3dpp, sizeof(D3DPRESENT_PARAMETERS));
// 現在のディスプレイモードデータ取得
gl_lpD3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &DispMode);
// バックバッファフォーマットをディスプレイと等価に
gl_d3dpp.BackBufferFormat = DispMode.Format;
// 横ドット幅設定
gl_d3dpp.BackBufferWidth = SCREEN_WIDTH;
// 縦ドット幅設定
gl_d3dpp.BackBufferHeight = SCREEN_HEIGHT;
// バックバッファの数
gl_d3dpp.BackBufferCount = 1;
// フリップの方法(通常はこの定数でよい)
gl_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
//
gl_d3dpp.EnableAutoDepthStencil = TRUE;
// ステンシルフォーマット
gl_d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
// ウインドウモードの設定
gl_d3dpp.Windowed = WINMODE;
/* デバイスオブジェクトの生成 */
//高性能なハードウェアデバイスの生成を試みる
hr = gl_lpD3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_HARDWARE_VERTEXPROCESSING, &gl_d3dpp, &gl_lpD3ddev);
if ( FAILED(hr) ) {
//ハードウェアデバイスの生成を試みる
hr = gl_lpD3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, &gl_d3dpp, &gl_lpD3ddev);
if ( FAILED(hr) ) {
//ソフトウェアデバイスの生成を試みる
hr = gl_lpD3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, &gl_d3dpp, &gl_lpD3ddev);
if ( FAILED(hr) ) {
//--どのデバイスも取得できなかった
MessageBox(hWnd, "DirectXデバイス生成失敗", "ERROR", MB_OK);
return E_FAIL;
}
}
}
return S_OK;
}
作成したすべてのオブジェクトは、アプリケーション終了時にすべて開放しなければならない。以下のプログラムを、プロトタイプ宣言の順番どおり、InitDX8関数の下に追加する。
//-----------------------------------------------------------------------------
// 関数名 : ReleaseD3D()
// 機能概要: DirectX8オブジェクトの開放
//-----------------------------------------------------------------------------
void ReleaseD3D(void)
{
//デバイスオブジェクトの開放
if ( gl_lpD3ddev != NULL ) {
gl_lpD3ddev->Release();
gl_lpD3ddev = NULL;
}
//DirectX8オブジェクトの開放
if ( gl_lpD3d != NULL ) {
gl_lpD3d->Release();
gl_lpD3d = NULL;
}
}
アプリケーション実行時にDirectX Graphicsの初期化処理を行い、終了時にオブジェクトを開放するよう、WinMain関数を次のように修正する。
//-------------------------------------------------------------------------------------------------
// メイン関数(エントリーポイント)プログラムはここから始まる
//-------------------------------------------------------------------------------------------------
int WINAPI WinMain(HINSTANCE hThisInst, HINSTANCE hPrevInst, LPSTR lpszArgs, int nWinMode)
{
MSG msg; // メッセージ構造体変数
HRESULT hr;
//表示するウィンドウの定義、登録、表示
if (!InitApp(hThisInst, nWinMode)) return (FALSE);
// DirectX8の初期化
hr = InitDX8();
if ( FAILED(hr) ) return (FALSE);
// メッセージループ
// Windowsは「WM_QUIT」メッセージを受けると偽(0)を戻す
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg); // メッセージの解析
DispatchMessage(&msg); // メッセージの破棄
}
// DirectX8オブジェクトの削除
ReleaseD3D();
return msg.wParam;
}
※この時点でビルドしてもエラーになるので注意!!
| BACK(DirectX Graphicsプログラミングの基礎) | NEXT(ビルドの準備) |