Direct3Dの基本的なプログラムの解説
基本的な解説
●4つのソースファイル
ファイル名 | 内容 |
---|
main.cpp | プログラムの中核。Windowの作成と描画とメッセージループ。 |
Init3D.cpp | Direct3Dの初期化と開放 |
XFile.cpp | Xファイルの読み込み |
Render.cpp | 3Dモデル描画 |
ソースファイルは1本でも十分ですが、頭をすっきりさせるために機能別にソースを分けてあります。
基本的なサンプルプログラム
●解説
Direct3Dで描画をする方法には、決まった過程があります。
まず、プログラム起動時にDirect3Dの初期化をし、プログラム終了時にそのインスタンスを開放をします。
描画はWindowsのメッセージ処理中に描画関数を呼び出して描画させるのが定型のようです。
また、それ以外に3Dモデルを読み込む処理が必要です。
これらの処理はほぼ一定で一度作れば使いまわしができます。
・処理の中心
@.Direct3Dの初期化
A.モデルの読み込み
B.描画処理をする
C.終了時にDirect3Dの開放をする
あと、必要に応じたレンダリング設定を実行します。
だいたい起動時に設定します。頻繁に設定を変える必要がある場合もあるので、そのときは描画の前に設定したりします。
@Direct3Dの初期化
初期化は、Direct3D9インターフェースの取得をし、更にDirect3D9Deviceインターフェースの取得をします。
これは、どんな3Dプログラムも同じ処理をしますので一度書いてしまえば他でも使えます。
LPDIRECT3D9 g_pD3D; // Direct3D9インターフェース
LPDIRECT3DDEVICE9 &g_pd3dDevice; // Direct3D9Deviceインターフェース
// インスタンスの作成
g_pD3D = Direct3DCreate9( D3D_SDK_VERSION );
g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice );
g_pD3D->CreateDevice() を実行する前に、
D3DPRESENT_PARAMETERS d3dpp; に必要な設定をしてから呼び出します。
他に、基本的なレンダリング設定をここでします。
Aモデルの読み込み
3DモデルはDirect3Dが扱えるXファイルを読み込みます。
読み込みは、D3DXLoadMeshFromX() 関数で行います。
モデルのマテリアルデータと、テクスチャデータは上記の関数でその情報のアドレスが入るだけなので、
そのマテリアル数分の配列エリアを new で確保し、そこにそれぞれのデータをコピーする、というスタイルを採ります。
マテリアルにテクスチャがある場合、そのデータも読み込みます。
注意するのは、Xファイル名はフォルダ込みのファイル名指定で読み込めますが、テクスチャはプログラムの起動
フォルダを探すので、ファイル名にフォルダ名を付けて読み込むか、読み込む前に、テクスチャデータの保存フォ
ルダに一時的に切り替えて読み込むなどの対策をします。
B描画処理をする
ここが一番重要でかつわかりにくい部分かもしれません。
しかし、これも手続きはだいたい同じ工程になりますので、基本が理解できれば応用が効きます。
描画も一定の処理がされます。
void 3D描画(void)
{
1.画面クリア
2.デバイスに描画開始を通知する
3.ワールド変換の設定(表示位置を設定)
4.ビュー変換の設定(カメラの設定)
5.射影変換の設定(レンダリング設定)
6.モデルの描画
7.デバイスに描画終了を通知する
8.バックバッファを切り替える
}
以上のような工程を辿ります。
3.4.5の順番は順不同でもけっこうです。4.5 は変更がなくば起動時の初期化後に一度行えば大丈夫です。
3.4.5では行列を使用しますが、難しいことは考えず、所定の関数と変数に位置を指定すれば大丈夫です。
6のモデル描画はXファイル読み込みでセットされたメッシュ、マテリアル、テクスチャを描画します。
これらもだいたい定型的な処理で実現できます。
C.Direct3Dの開放
これは、@で取得したDirect3Dのインスタンスを開放するだけです。
描画寸前の各種設定
上記の中で解りにくいのが、ワールド変換、ビュー変換、射影変換、ではないかと思います。
@.ワールド変換
これは、3D空間のどの位置に表示するかということを決めます。
表示するときの位置は、D3DXMatrixTranslation() 関数で指定します。
回転は、D3DXMatrixRotationX(),D3DXMatrixRotationY(),D3DXMatrixRotationZ() 関数で指定します。
拡大縮小は、D3DXMatrixScaling() 関数で指定します。
{
D3DXMATRIX mTranslation, mRotation; // 行列変数
D3DXMatrixTranslation( &mTranslation, x, y, z ); // 位置
D3DXMatrixRotationY( &mRotation, 0.1f ); // 回転
mWorld = mTranslation * mRotation; // 行列演算。回転と移動を合算する。
g_pd3dDevice->SetTransform( D3DTS_WORLD, &mWorld ); // D3DDevice に設定する。
}
表示位置を変更するには、x,y,z の位置を変更すると位置が変更されます。
シューティングゲーム等は敵キャラなどの位置をその都度変更するので、D3DXMatrixTranslation()関数
が頻繁に使われます。
A.ビュー変換
これはカメラ位置を設定すると考えるといいでしょう。
カメラ設定は、カメラそのものの座標位置、カメラが見据える注視点の座標位置、カメラの俯瞰位置
などを設定し、それらを D3DXMatrixLookAtLH(() 関数で一つの行列に合成してビュー設定をします。
{
D3DXMATRIXA16 matView; // 行列記憶構造体
D3DXVECTOR3 vEyePt( 0.0f, -1.0f,-5.0f ); // カメラそのものの座標位置
D3DXVECTOR3 vLookatPt( 0.0f, 2.0f, 4.0f ); // カメラが見据える注視点の座標位置
D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f ); // カメラの俯瞰位置(上方向ベクトル)
D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec ); // ビュー変換行列の作成
g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView ); // D3DDevice に設定する。
}
B.射影変換
これはレンダリングに関する設定で、視錐台の面の大きさや角度を設定します。
2Dにレンダリングするための基準位置を指定するわけです。
D3DXMatrixPerspectiveFovLH() 関数で設定します。
{
D3DXMATRIXA16 matProj;
D3DXMatrixPerspectiveFovLH( &matProj, D3DXPI/4, 1.0f, 1.0f, 100.0f ); // 射影変換行列の作成
g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj ); // D3DDevice に設定する。
}
// 引数の内容
D3DXMatrixPerspectiveFovLH( 結果格納ポインタ, Y方向視野角, 画面のアスペクト比, 近クリップ面のZ値, 遠クリップ面のZ値 );
Xファイルの作成
Direct3Dでゲームを作成するには、少なくとも3Dソフトでモデリングし、Xファイルに出力する。
ということをしなければなりません。プログラマであり、3Dクリエーターでなければなりません。
Xファイルを出力するソフトには以下のものがあります。
ソフト名 | 価格 | 備考 |
---|
LightWave | 有償 | 出力にはプラグインが必要です。(XPorter) |
3dsMax | 有償 | 出力にはプラグインが必要です。 |
XSI Mod Tool | 無償 | 無料ですが、ちょっと情報が少ないのが残念。 |
Metasequoia | 無償 | アニメーションは出力できない。モデルデータのみ出力できる。有償版は5,000円 |
LightWaveに付属のサンプルデータをXファイルに出力すると、時々、キャラクタのオブジェクトがとんでもない所に
表示されるということがあります。原因はわかりませんが。
ゲーム作成の手引き
・シューティングゲーム
シューティングゲームは、敵キャラを出現させてそれを常時動かす、ということが主流ですから
それが処理の中心になります。そしてそれと自機の発射した弾との当たり判定による破壊の処理
がだいたいの処理の中心です。敵キャラの位置は乱数などを使ってランダムな移動をさせたりし
ます。
技術的な問題は、敵キャラの表示と移動方法、自キャラの弾の発射と敵キャラの当たり判定を習
得すれば基本的な処理テクニックはマスターできます。
・ロールプレイングゲーム
ロールプレイングゲームでは、アニメーションが多用されます。歩く、走る、攻撃、受撃などの
キャラクターアニメーションデータが必要なので、シューティングゲームよりは遥かに3D製作
の部分で大変になります。コースを歩くには歩くアニメーションが必要です。そのキャラクタを
コース内で歩かせ、はみ出しや突き抜けの防止をします。人と話すアクションなんかも必要です
ね。そしてバトルでは、自分や敵キャラのアクションアニメーションが必要になります。
・アクションゲーム
アクションもRPGと同じように歩く、話す、戦う、などのアニメーションが必要です。RPG
に準じるところがあります。攻撃、受撃では、メッシュが相手と衝突したときの判定が必要です。
・格闘ゲーム
格闘ゲームもそれぞれの攻撃をアニメーションで表現します。キー入力に従ったアニメーション
の再生をし、相手との衝突判定をして勝負の判定をします。
3Dでゲームを作成する対象は上記の4種が主なものだと思います。他のシュミレーションゲーム
とかカードゲームとかなどは特に3Dで作らなくともいいと思いますが、それらを3Dでやろうと
した場合、上記4種のテクニックを学べば、その実現はさほど難しいものではないと思います。
3Dでゲームを作成するにはとにかく手間がかかります。キャラクタの製作、アニメーションの製
作、テクスチャ、背景、環境など、3Dクリエーター、3Dアニメーター、お絵描き屋さん、音楽
クリエイトなど、いろんなことをしなければなりません。