マスタリングDirectXを読んでみた

PART1 はじめに(10:00)

DirecXが世間一般にどうとらわれてるか書かれている。
あとソースをプリントアウトしたほうがいいとある。うんこれは納得。仕事でもよくプリントアウトして紙に出して読むよ。書き込みながらね。そんで検索とかは画面のエディタ使いながらとか。


初めてDirecXやった2とか3のころは確かに、すぐにハングアップして再起動しまくりだったけど、DirectX7あたりから大分扱いやすくなった気がするな〜。しかしそれでもやっぱり普通のプログラミングに比べたらハングすることが多いしやっぱ敷居高いんだろうな。


「SDKのアップデートは慎重に」とある。BugFixとかでも、微妙に関数の引数が入れ替わって動かなくなることもあるらしい。やっぱライブラリでラッピングする必要があるか?

PART2 DirectXとはなんなのか?(10:10)

DirectXは大変だよとう脅し?見たいな感じ。覚悟してねみたいなw

DirectXとGDIの違い
GDI
CPUメインで描画。各グラフィックボードの共通の描画機能のみを使うため、ボードごとの差異がない。
DiretX
ドライバを直接操作して描画。CPUを使わない。ある機能がない場合はエミュレーション(HEL)する。

11:00 - 11:00 部屋かたづけ

PART3 クラスを知ろう(11:20)

クラスは大変だよって話。クラスについては散々ならしてるから基本は大丈夫だな。
しかしクラスは難しい難しいって若干大袈裟な気もする。

インスタンスで確保される領域はメンバ変数のみ。メンバ関数のコード量が多くてもメモリ使用量は増えない。言われてみれば当たり前のことだが、しばらくCやってないとメモリまわりのこと気にしないからこんなことも忘れかけてる。。。
C++で記述するときのメリットデメリット。

変数初期化時はNULLを代入すること。javaでは自動的に初期化されるからこの慣習忘れてたなぁ。気をつけよう。

次章からやっとDirectXの本題だ^^

PART4 思いつきに形を与えるために(11:55)

DirectX始まると思ったらまだ始まらないw。ゲームを作るうえでの心構えでした。

  • 現在はさまざまなゲーム開発の知識が散乱している
  • これらを寄せ集めればなんとがゲームが開発するよ
  • でも自分プログラムの中でこれらを活用できるようになるまでには多大な労力が必要だよ。
  • これらの情報は「いつか必ず役に立つ情報」としてストックされる。
  • 結局、それらの情報を活用できずにプログラムに飽きることが多い。

見たいな感じ。そのとおりですね。反省します。

  • 頭の中だけで思い描いて開発始めても多くの場合失敗する
  • まずは頭の中の設計図を紙に書こう!パソコンじゃないよ。
  • ゴールをこまめに設定する。いきなり市販ゲームクオリティは無理

たしかに趣味プロでは、頭の中だけでまともに書き出すことは少なかった気がするな。これも反省だわ。

PART5 最小限のDirectXアプリケーション(12:25)

CreateDeviceメソッドの話
  CreateDevice(
    D3DADAPTER_DEFAULT, // シングルモニタの場合、これで決まり
    D3DDEVTYPE_HAL,     // HALを使うよ
    hWnd,               // ウィンドウハンドル
    D3DCREATE_HARDWARE_VERTEXPROCESSING, // フラグ
    &g_D3DPParamas,    // デバイス初期化のパラメータ
    &g_pD3DDevice      // 生成したデヴァイスを格納するための変数
)
  • &g_D3DPParamasで指定したパラメータは後から変更できない。たとえば色深度などがそう
  • ウィンドウモード実行中のアプリでコンパネから色深度変更した場合でも、アプリの色深度はかわらない。
  • ウィンドウをリサイズしても、描画領域の画像サイズは変更されない
BeginSceneとEndSceneメソッド
  • BeginSceneメソッドを呼び出すと、DirectXアプリ以外のアプリ(スレッド)がいったん動きを止めるらしい
  • その動きが止まってる間に描画処理を実行する
  • ちなみにその描画処理はバックバッファに対して実施される
  • で、終わったらEndSceneを呼び出す。これでほかのアプリ(スレッド)が再開される

これは知らなかった。

フルスクリーンモードの話
  • フルスクリーンにするにはいったんデバイスを開放しなくてはならない。
  • その後、もう一度モデルやテクスチャを再確保する必要があり、かなり面倒
  • できれば、ソースコード上のフラグ定数などで静的に切り替えるのが、バグを抑えるという意味でお勧め
  • もしくはプログラム起動後に、タイトル画面などでモードをユーザに選択させるなど。

ALT+Enterでの切り替えはやめたほうがいいかな。でも昔作ったプログラムはALT+Enterで動的に切り替えてた気がする。。。

PART6 ウィンドウとモデルの表示(Direct3D)(13:30)

カメラの設定
    D3DXMatrixPerspectiveFovLH( &matProj,
                                D3DX_PI/4,  // 視野角
                                tmpAspect,// アスペクト比
                                1.0f,       // 最近接距離
                                800.0f );   // 最遠方距離
アスペクト比
よこ/たて。忘れてたな。
視野角
2PI=360度。PI=180度。だからD3DX_PI/4は45度。復習復習。
最短距離、最長距離
Zバッファの0は最短。1は最長。
メッシュの表示
D3DXLoadMeshFromX(filename            // ファイル名
                  D3DXMESH_SYSTEMMEM, // メッシュを作成するときのオプションフラグ
                  theDevice,          // デバイス
                  NULL,               // 隣接製データをうんたらかんたら。よくわからん
                  &pMaterials,        // マテリアル配列を受け取るためのポインタ
                  NULL,               // エフェクト配列のためのポインタ
                  &(aModels->objNumOfMaterials), // マテリアル配列の数
                  &(aModels->objMesh)) // 受け取るメッシュオブジェクトへのポインタ

この関数を使って、マテリアル情報を取得し、マテリアルとテクスチャ情報をコピーして使いまわす。

モデルの表示部分。マテリアルごとにDrawSubsetを呼び出す。

VOID drawMesh( LPDIRECT3DDEVICE9 theDevice, int objNum )
{
	SetupObjMatrixMulti( theDevice , objNum );	//オブジェクトの表示用行列を設定
	int	theType = g_Object[objNum].MdlType;		//オブジェクトのモデルの種類

	// マテリアルの数だけループ
	for(DWORD j0=0; j0 < g_ObjModels[theType].objNumOfMaterials ; j0++ )
	{
		// サブセットにマテリアルとテクスチャを設定。
		theDevice->SetMaterial( &(g_ObjModels[theType].objMeshMaterials[j0]));
		theDevice->SetTexture( 0, g_ObjModels[theType].objMeshTextures[j0] );
		
		// メッシュ・サブセットの描画。
		g_ObjModels[theType].objMesh ->DrawSubset( j0 );
	}
}


今日はここまで。いまから飲み会だわ。あんま進まなかったな〜。(15:30)

マスタリングDirectXプログラミング

マスタリングDirectXプログラミング