[HMC]年間5250円で独自ドメイン付属、ウィルスチェックありのレンタルサーバ!
Last update : 1999/08/19
DirectDraw基礎 第8回
作業用サーフェイスを作成し、データ転送
サンプルコードのダウンロード
  では、まずサンプルコードをダウンロードし、解凍して下さい。 私はVisual C++6.0でコンパイルしているので、をお持ちの方は Visual C++でプロジェクトファイルを開いて下さい(「ddraw_08.dsw」をダブルクリックすれば開けます)。 圧縮ファイルに含まれる「ddraw_08.exe」をダブルクリックし、実行してみて下さい。どうでしょう?画面が切り替わり、フルスクリーン化し、 が作業用サーフェイスに読み込まれ、そこから部分的にバックバッファにデータが転送されていると思います(謎
  というわけで、今回は作業用サーフェイスを作成し、データ転送をしたいと思います。
作業用サーフェイスの作成
  普段、ゲームを作成する場合は、オフスクリーンサーフェイス(作業用サーフェイス)と呼ばれる目に見えないサーフェイスを作成し、そこへビットマップを読み込み、そこからバックバッファへデータ転送し、フリップし、画面に表示させます・・・というのは何度も書いているので既に 解っていると思います。んでは、まずオフスクリーンサーフェイスの作成方法を記しておきます。

オフスクリーンサーフェイスの作成は自作関数「StartDirectDraw」に追加してあります。

  DirectDrawオブジェクトのメンバである「CreateSurface」については
第3回のプライマリサーフェイス作成時に多少説明しました。 今回はオフスクリーンサーフェイスを作成するという事で、dwFlagsには更に DDSD_WIDTH | DDSD_HEIGHT を追加指定し、サーフェイスの縦幅、横幅を指定出来るようにします。 そうしたら、dwWidthとdwHeightに縦幅、横幅を指定(今回はプライマリサーフェイスと同じ640×480) します。んで、ddsCaps.dwCapsにDDSCAPS_OFFSCREENPLAINを指定し、「CreateSurface」を呼び出せば、サーフェイスが作成されます。作成したいサーフェイスのサイズは 自由に変更可能ですが、プライマリサーフェイスよりも大きなサーフェイスを作成しようとするとDirectXのバージョンによっては失敗する可能性があるのでやめた方が良いですね。

  ちなみに、オフスクリーンサーフェイスはビデオメモリに作成されますが、ビデオメモリが足りなくなると、自動的にシステムメモリ内に作成されます。 また、意図的にシステムメモリ内へサーフェイスを作成したい場合はddsd.ddsCaps.dwCapsにDDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;を指定してやります。

  例によって、オフスクリーンサーフェイス(lpWork)は、ビデオメモリだろうがシステムメモリだろうが関係なしに、フロントバッファやバックバッファと同じように扱う事が出来ます (GDIの描画等含む)。
サーフェイス間のデータ転送
  では、オフスクリーンサーフェイスにキャラクターイメージを読み込んだ後、このイメージを他の場所へ転送します。 で、ただ転送するだけでなく、透明色を使用した転送が出来ます。その場合、どの色を透明色にするかをサーフェイス毎に設定しておかなければなりません。 では、透明色の指定方法を以下に記します。

  まず、DDCOLORKEY構造体のメンバに透明色にしたい色を指定します。DDCOLORKEY構造体は以下のようになっています。

メンバ変数は2つあります。パレット番号のLowValueからHighValueの範囲を透明色とするらしいのですが(未確認)、 普段は1色しか透明色として使用しないので、LowもHighも同じ値にします。そうしたら、DirectDrawサーフェイスのメンバである 「SetColorKey」を呼び出します。構文は以下の通りです。
書式HRESULT SetColorKey( DWORD dwFlags, LPDDCOLORKEY lpDDColorKey );
dwFlags透明色を指定する場合はDDCKEY_SRCBLTを指定する。これは、転送元サーフェイスの指定した色以外を転送する事を意味する。転送元カラーキーとも言う。

他にもDDCKEY_DESTBLTというのがあるが、これは転送先の指定した色の部分にのみ転送する。転送先カラーキーとも言う。こっちは滅多に使用しないので解説省略だぃ(いつか解説するかも)。
lpDDColorKeyDirectDrawSurface オブジェクトの新しいカラーキー値を含んでいる DDCOLORKEY 構造体へのポインタ。
戻り値 成功するとDD_OKが返ってくるらしい。

  さて、今回はパレット1番の紫色(パレット番号は0から始まります)を透明色として使用する事にします。 そうしたら、今度はデータ転送です。

データ転送をするには、転送先のサーフェースがメンバ関数「BltFast」を呼び出します。 「BltFast」の構文は以下の通りです。
書式HRESULT BltFast( DWORD dwX, DWORD dwY, LPDIRECTDRAWSURFACE lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwTrans );
dwX,dwY転送先のXおよびY座標
lpDDSrcSurface転送元のサーフェイスへのポインタ。言い忘れてたかもしれませんが LPDIRECTDRAWSURFACE型は、これだけでポインタなので&はいりません。
lpSrcRect転送元の領域を指定したRECT構造体へのポインタ。RECT構造体については下で詳しく解説しています。
dwTrans転送タイプ。
DDBLTFAST_NOCOLORKEYは、透明色無しの転送。
DDBLTFAST_SRCCOLORKEYは、透明色有り(転送元カラーキーを使用)の転送
DDBLTFAST_WAITは、何らかの原因で転送出来ない時に、転送できるまで待つという指定。
これらはOR演算(|)で同時に複数指定できます。
戻り値 成功するとDD_OKが返ってくるらしい。

  BltFastを使用するには、RECTと呼ばれる構造体のメンバに転送元の領域を指定する必要があります。RECT構造体は 以下のように定義されています。
  例えば、転送元の画像のX,Y座標が32,0から64,32だとする場合は

  というように指定します。こうして転送元の範囲を指定したらBltFastを呼び出します。 転送先がバックバッファ(lpBack)、転送先のX、Y座標32,32、転送元がオフスクリーンサーフェイス(lpWork)とした場合の 転送(透明色を使用 する/しない)の書き方は以下の通りです。
  ただ、転送タイプの指定「DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT」というのが非常に長いため、ソースの無駄遣いのような気になります(爆)。 このフラグをテーブル化し、数値で指定するようにしたのが自作関数「Blt」というわけです。
後始末
  作成したオフスクリーンサーフェイス(lpWork)は解放してやらなきゃいけません。 「lpWork->Release();」というふうにしてやります。いつも通り、マクロを使用するならば「RELEASE(lpWork);」ですかね。