【DirectDraw 初期化処理詳細】
【関数仕様】
関数名: | InitDD
|
返値: | HRESULT (TRUE)で初期化成功
|
引数: | HWND hWnd (ウインドウへのハンドル)
|
【プログラムリスト1】
DDSURFACEDESC2 ddsd;
HRESULT hRet;
LPDIRECTDRAW pDD;
上記、変数宣言である。解説はいらないであろう。
【プログラムリスト2】
hRet = DirectDrawCreate(NULL, &pDD, NULL);
if (hRet != DD_OK)
return InitFail(hWnd, hRet, "DirectDrawCreate FAILED");
上記について、
DirectDrawCreate は、DirectDraw が提供するAPI 関数である。
これにより、DirectDraw オブジェクトが生成される。
DirectDraw オブジェクトへのポインタは、第二引数の pDD に保存される。
初期化に失敗すると、InitFail を呼び出し、アプリケーションを終了させている。
【プログラムリスト3】
hRet = pDD->QueryInterface(IID_IDirectDraw4, (LPVOID *) & g_pDD);
if (hRet != DD_OK)
return InitFail(hWnd, hRet, "QueryInterface FAILED");
上記、判りにくい所であるが、
DirectDraw オブジェクトへのインターフェイスを取得している。
プログラムリスト2 で取得するオブジェクトは、DirectX 1.0 と互換性のある、
DirectDraw オブジェクトである。
ここでは、新バージョンの DirectDraw オブジェクトを取得している。
【プログラムリスト4】
hRet = pDD->SetCooperativeLevel(hWnd, DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN);
if (hRet != DD_OK)
return InitFail(hWnd, hRet, "SetCooperativeLevel FAILED");
上記、DirectDraw API の、SetCooperativeLevel 関数を使って、他のアプリケーションとの
協調レベルの設定を行っている。
今回はフルスクリーン専用アプリケーションを作る。
設定は上記でOKである。
【プログラムリスト5】
hRet = pDD->SetDisplayMode(640,480,SCREEN_BIT_DEPTH);
if (hRet != DD_OK)
return InitFail(hWnd, hRet, "SetDisplayMode FAILED");
DirectDraw API の、SetDisplayMode 関数を使って、スクリーンモードを設定している。
本来ならば、ディスプレイモードを調べて、設定すべきであるが、ここでは今の所必須モードである、
VGA 256色モードを設定している。(そのうち 256 色モードは廃止されるらしい。)
なお、マクロ定数、SCREEN_BIT_DEPTH は、今回のプログラム内で設定されている。
数値は、8である。
【プログラムリスト6】
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS|DDSD_BACKBUFFERCOUNT;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE|DDSCAPS_FLIP|DDSCAPS_COMPLEX;
ddsd.dwBackBufferCount = 1;
hRet = g_pDD->CreateSurface(&ddsd, &g_pDDSPrimary, NULL);
if (hRet != DD_OK)
return InitFail(hWnd, hRet, "CreateSurface FAILED");
プライマリサーフェイスを生成している。
プライマリサーフェイスとは、表示に使用するサーフェイスである。
サーフェイスとは、早い話が、VRAM だと考えてもらえば良い。
描画・表示環境である、VRAM を抽象化して、サーフェイスと呼んでいる。
渡しているパラメータの詳細は、MS社のマニュアルを参照してもらいたいが、
ここでは、プライマリサーフェイスとともに、バックバッファ
(表示されないサーフェイス)を一枚作成している。
【プログラムリスト7】
DDSCAPS2 ddsc;
ddsc.dwCaps = DDSCAPS_BACKBUFFER;
hRet = g_pDDSPrimary->GetAttachedSurface(&ddsc,&g_pDDSOffScreen);
if (hRet != DD_OK)
return InitFail(hWnd,hRet,"GetAttachedSurface FAILED");
プログラムリスト6の解説で述べた、バックバッファを取得し、
g_pDDSOffScreen というグローバル変数にそのポインタを格納している。
【プログラムリスト8】
if (SCREEN_BIT_DEPTH > 8){
g_pDDPal=NULL;
}else{
g_pDDPal = DDLoadPalette(g_pDD, szBitmap);
if (g_pDDPal){
g_pDDSPrimary->SetPalette(g_pDDPal);
g_pDDPal->Release();
g_pDDPal=NULL;
}
}
パレットの設定をしている。
基本的に、パレットを使用するのは、8bit カラー以下のモードなので、
16bit カラー以上では、パレットは設定していない。
パレットを作った後、Release で捨てているのだが、ここは COM オブジェクトの
変な所。
SetPalette 関数で、プライマリサーフェイスへ合体させたら、
消してしまってOKです。
(実際には消えません。困ったもんです。イヤハヤ・・・。)
【プログラムリスト9】
g_dwEraseColor = DDColorMatch(g_pDDSPrimary,
(120<<16)
+(120<<8)
+36);
今回のプログラム内の関数、DDColorMatch を使用して、画面をクリアする為のカラーデータ
を作成して、グローバル変数、g_dwEraseColor に保存している。
DDColorMatch に渡している引数のうち、第一引数は、表示用のサーフェイス。
第二引数は、RGB 三値の輝度をそれぞれ、0〜255までの256段階で表現。
そして、B×65536+G×256+R で表現したものです。
【プログラムリスト10】
g_pDDSOne = DDLoadBitmap(g_pDD, szBitmap, 0, 0);
if (g_pDDSOne == NULL)
return InitFail(hWnd, hRet, "DDLoadBitmap FAILED");
return DD_OK;
ここで、ビットマップを読み込んでいます。
読み込んだビットマップは新たなサーフェイスに保存され、
そのサーフェイスへのポインタを、g_pDDSOne というグローバル変数に記録しています。
mission3 の段階では、このビットマップ使用してないのですが、
mission4 への前振りなのです。
以上で初期化は完了。
戻る