画像の矩形をサーフェイスに転送するメソッドとしてBltFastメソッドを使ってきたが、Bltメソッドもある。この章では、Bltメソッドの使い方を学ぶ。
(日本語HELPに解説は書いてあるが、サンプルコードがないので・・・)
BltFast関数とBlt関数は、どちらも
指定したサーフェイスの矩形を、別のサーフェイスに転送する機能を持つ。では、どう違うのだろうか。
- BltFastメソッド
- ・サーフェイス間で、矩形を転送する
- ・転送時、カラーキーを指定することにより、指定した色以外を転送することができる(スプライト処理)
- Bltメソッド
- ・BltFastの機能はすべて使える
- ・転送時、矩形にさまざまな効果をつけることができる
- ・転送先の矩形を、任意の色で塗りつぶすことができる
- ・BltFastと比べ、転送速度が若干遅い
つまり、BltFastは、Bltの簡易版であることが分かる。
Bltメソッドは、
を指定してブロック転送を行う。引数は5つで、内容は次のとおり。
- 転送先の位置とサイズ
- 転送元サーフェイス
- 転送元の座標値
【文法】
HRESULT Blt( LPRECT lpDestRect, LPDIRECTDRAWSURFACE7 lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx );【引数の説明】
- lpDestRect
- 転送先サーフェス上にブリットする矩形の左上と右下の位置を定義するRECT構造体のアドレス。このパラメータが NULL の場合、転送先サーフェス全体を使用する。
- lpDDSrcSurface
- ブリットの転送元であるDirectDrawSurfaceオブジェクトのIDirectDrawSurface7インターフェイスのアドレス。
- lpSrcRect
- 転送元サーフェス上からブリットする矩形の左上と右下の位置を定義するRECT構造体のアドレス。このパラメータがNULLの場合、転送元サーフェス全体を使用する。
- dwFlags
- カラーキー情報を指定する、またはメソッドから特別な動作を要求する、関連付けられた DDBLTFX 構造体の有効メンバを決定するフラグの組み合わせ。(※)
- lpDDBltFx
- DDBLTFX 構造体のアドレス。指定しないときはNULL。
※フラグの種類
評価フラグ DDBLT_COLORFILL 転送先サーフェス上の転送先矩形を格納する RGB 色として DDBLTFX 構造体の dwFillColor メンバを使用する DDBLT_DDFX このブリットに対して使用するエフェクトを指定する、DDBLTFX 構造体の dwDDFX メンバを使用する DDBLT_DDROPS Microsoft Win32 API の部分ではないラスタ処理 (ROPS) を指定する、DDBLTFX 構造体の dwDDROP メンバを使用する DDBLT_DEPTHFILL 転送先 Z バッファ サーフェス上の転送先矩形を格納する深度値として、DDBLTFX 構造体の dwFillDepth メンバを使用する DDBLT_KEYDESTOVERRIDE 転送先サーフェスのカラー キーとして DDBLTFX 構造体の ddckDestColorkey メンバを使用する DDBLT_KEYSRCOVERRIDE 転送元サーフェスのカラー キーとして DDBLTFX 構造体の ddckSrcColorkey メンバを使用する DDBLT_ROP このブリットにおける ROP に DDBLTFX 構造体の dwROP メンバを使用する。これらの ROP は、Win32 API で定義されているものと同じである DDBLT_ROTATIONANGLE サーフェスの回転角 (1/100 度単位で指定される) として DDBLTFX 構造体の dwRotationAngle メンバを使用する カラー キー フラグ DDBLT_KEYDEST 転送先サーフェスに関連付けられたカラー キーを使用する DDBLT_KEYSRC 転送元サーフェスに関連付けられたカラー キーを使用する 動作フラグ DDBLT_ASYNC 受け取った順序でファーストイン、ファーストアウト (FIFO) ハードウェアから非同期的にこのブリットを実行する。FIFO ハードウェアの空き領域を利用できない場合、呼び出しは失敗する DDBLT_DONOTWAIT DirectX 7.0 で追加。ブリットを実行せずに返す、またはブリットがビジーの場合に DDERR_WASSTILLDRAWING を返す DDBLT_WAIT ブリットがビジーの場合、DDERR_WASSTILLDRAWING 戻り値をすぐに返さずに待機する。そして、ブリットがセット アップされるか、別のエラーが発生したら即座に返す 使用例:普通に転送する場合
バック・バッファの(100, 100, 164, 164)の矩形に、キャラクタ用サーフェイスの(0, 0, 64, 64)の矩形を転送する。転送の際、カラーキーを指定する。
RECT rcDest, rcSrc;
SetRect(&rcDest, 100, 100, 164, 164);
SetRect(&rcSrc, 0, 0, 64, 64);
hRet = g_pDDSBack->Blt(&rcDest, g_pDDSChara, &rcSrc, DDBLT_WAIT | DDBLT_KEYSRC, NULL);
if (hRet != DD_OK) return;※転送先と転送元で矩形の大きさが違う場合、転送元画像は転送先の矩形に合わせて拡大・縮小される
9章1〜2確認問題(必須)
Bltメソッドの機能をいろいろ試すため、第9章用プログラム(第6章用プログラムと同じもの)を使う。ダウンロードし、DDraw09という名前でプロジェクトを作成する。
- 問題1
- 自キャラの描画処理を、BltFastメソッドからBltメソッドに書き換え、描画できるかどうかを確認する。(エラーがなく描画できたら次へ進む)
- 問題2
- 自キャラの移動処理を改造する。カーソルキーの上下を押すとキャラクタが縦に伸び縮みし、左右を押すと横に伸び縮みするプログラムを作成しなさい。
ただし、幅と高さが1より小さくなった場合や、ゲーム画面をはみ出した場合の処理は考えないものとし、確認のためにゴキブリとの当たり判定処理をはずす。[ 実行結果サンプル ]
矩形転送時、矩形に対してつけることができる効果を紹介する。
効果フラグの種類(抜粋)
DDBLTFX_MIRRORLEFTRIGHT 左右に反転 DDBLTFX_MIRRORUPDOWN 上下に反転 DDBLTFX_ROTATE90 時計回りに 90 度回転 未サポート DDBLTFX_ROTATE180 時計回りに 180 度回転 未サポート DDBLTFX_ROTATE270 時計回りに 270 度回転 未サポート 他にもいろいろあるが、よく使うのはこれくらいだろう・・・
(詳しくはHELPを参照)使用例:効果をつける(左右反転の場合)
DDBLTFX ddBltFx;
RECT rcDest, rcSrc;
ZeroMemory(&ddBltFx, sizeof(ddBltFx));
ddBltFx.dwSize = sizeof(ddBltFx);
ddBltFx.dwDDFX = DDBLTFX_MIRRORLEFTRIGHT;
SetRect(&rcDest, 100, 100, 164, 164);
SetRect(&rcSrc, 0, 0, 64, 64);
hRet = lpDDSOne->Blt(lpBltRect, lpDDSSrc, lpSrcRect, DDBLT_WAIT | DDBLT_KEYSRC| DDBLT_DDFX,&ddBltFx);
if (hRet != DD_OK) return FALSE;9章3確認問題(必須)
1つのキャラクタ画像を元に、以下の効果をつけた画像をゲーム画面の任意の位置に表示するプログラムを作成しなさい。
- 矩形をそのまま表示
- 左右に反転して表示
- 上下に反転して表示
[ 実行結果サンプル ]
Bltメソッドには、3で紹介した効果のほかにも様々な機能がある。その中から、よく使う(かもしれない)
塗りつぶしについて解説する。たとえば背景に
無地の任意の色を使いたい場合、画面の大きさで任意の色を塗っただけの背景画像を用意するのは(ビデオメモリの要領を少なくしたい場合には)もったいない。かといって、小さい画像をタイル上に並べるのはプログラム的に面倒である。
そのような場合、次のようにBltメソッドを実行すると、画像を使うことなくサーフェイスを塗りつぶすことができる。【背景を黒く塗りつぶす(256色モードの場合)】
DDBLTFX ddBltFx;
ZeroMemory(&ddBltFx, sizeof(ddBltFx));
ddBltFx.dwSize = sizeof(ddBltFx);
ddBltFx.dwFillColor = 0;
hRet = g_pDDSBack->Blt(NULL, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddBltFx);
- 指定した色で転送先サーフェイスを塗りつぶす
- DDBLTFX構造体のdwFillColorメンバに塗りつぶす色を指定する(※)
- 転送元サーフェイスと、転送先の矩形(RECT構造体のポインタ)は指定する必要がない
※色の指定について
dwFillColorメンバに指定する色は、サーフェイスのピクセル・フォーマットに合ってなければならない。ウィンドウを256色モードで作成した場合、
プライマリ・サーフェイスに設定したパレットから、指定された番号の色が使われる。
(フルスクリーンではなくWindowモードの場合、1〜8番(くらい)はWindowsで予約されている色が格納される)
256色のパレットは、0番が黒、255番が白で予約され、残りの1〜254番が、パレットの元となっている画像で使われている色が順番に格納される。つまり、dwFillColorに1〜254を指定した場合、塗りつぶされる色は元となる画像によって変わる。
また、ウィンドウをFullColor以上で作成した場合、パレットは必要ないため、規程の色の範囲で指定できる。9章4確認問題(必須)
スタート画面の背景を、背景画像を使わずに「白」で塗りつぶすようプログラムを修正しなさい。
[ 実行結果サンプル ]
任意の矩形を塗りつぶすには?
Bltメソッドの1つ目の引数は転送先の矩形であり、NULLを指定すると、転送先サーフェイス全体を指す。つまり、RECT構造体を指定すれば、指定した矩形のみを塗りつぶすことができる。
/* 指定した矩形を黒く塗りつぶす */
ZeroMemory(&ddBltFx, sizeof(ddBltFx));
ddBltFx.dwSize = sizeof(ddBltFx);
ddBltFx.dwFillColor = 0;
SetRect(&rcDest, 100, 400, 540, 450);
hRet = g_pDDSBack->Blt(&rcDest, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddBltFx);
if (hRet != DD_OK) return;この機能を利用し、絶対に変わらない背景(画面の枠など)は一度だけ転送し、再描画しなければいけない領域だけを塗りつぶしてから必要な画像を転送すれば、描画の回数を減らすことができ、パフォーマンスがあがる。
[ 実行結果サンプル ]