[HMC]年間5250円で独自ドメイン付属、ウィルスチェックありのレンタルサーバ!
Last update : 1999/08/13
DirectDraw基礎 第6回
パレットを作成する
サンプルコードのダウンロード
  では、まずサンプルコードをダウンロードし、解凍して下さい。 私はVisual C++6.0でコンパイルしているので、をお持ちの方は Visual C++でプロジェクトファイルを開いて下さい(「ddraw_06.dsw」をダブルクリックすれば開けます)。 圧縮ファイルに含まれる「ddraw_06.exe」をダブルクリックし、実行してみて下さい。どうでしょう?画面が切り替わり、フルスクリーン化し、「フロントバッファ」と「バックバッファ」がカラフルに交互に表示されると思います(謎。 今回は、パレットを作成したいと思います。
パレット作成
  まず初めに、StartDirectDraw自作関数内へパレットオブジェクト作成部分を追加します (ディスプレイの色数が256色以下になっている時にだけ、パレットを使用する事が出来ます)。

まず、DirectDrawオブジェクト(lpDD)のメンバである「CreatePalette」関数を呼び出します。構文は以下の通りです。

書式HRESULT CreatePalette( DWORD dwFlags, LPPALETTEENTRY lpColorTable, LPDIRECTDRAWPALETTE FAR *lplpDDPalette, IUnknown FAR *pUnkOuter );
dwFlagsこのフラグでは、作成したいパレットの種類(2,4,16,256色)をマクロで指定するらしいのですが、私は256しか使用したことがないので(というかこれが最適)DDPCAPS_8BITを指定します。
lpColorTableこのDirectDrawPaletteオブジェクトを初期化するための2、4、16、256色分のPALETTEENTRY型配列へのポインタ。今回はあらかじめ定義しておいたPALETTEENTRY peEntry[256];のポインタを引き渡します。
lplpDDPalette作成するDirectDrawPaletteオブジェクトの格納先をアドレスで指定するらしい。今回は、あらかじめ定義しておいたLPDIRECTDRAWPALETTE lpPaletteのアドレスを引き渡します。
pUnkOuter将来拡張した時使用するらしいので、NULLを指定。
戻り値 成功した場合はDD_OKが返ってくるらしい。

そうしたら、次にサーフェイスのメンバ「SetPalette」関数を呼び出し、フロントバッファに作成したパレットを関連付けます。
色の設定
  さて、パレットを256個作成したら、その中に色を設定してやります。考え方としては、美術で256個の皿(部屋?)のあるパレットの中に、絵の具で色を作成するが、何故か絵の具が赤、緑、青の3つしか無く、その3つの絵の具の量を調整して様々な色を作成するというもの(わけわからん)。
  まぁ、とりあえずコードを見てみますか。

  自作関数SetPaletteColorでは、256個のパレットの内、no番目の色を「赤」、「緑」、「青」によって設定します。
ここではPALETTEENTRY構造体を使用します。この構造体のメンバ「BYTE peRed」(BYTE = unsigned char)、「BYTE peGreen」、「BYTE peBlue」 にそれぞれ「赤」、「緑」、「青」の量を0〜255の間で指定します(peFlagsメンバは1固定)。例えば、「赤」、「緑」、「青」を255,0,255にすると、赤と青が混ざった紫、127,127,127にすると、灰色というような感じです。
  そうしたら、前に作成したDirectDrawPaletteオブジェクト「lpPalette」のメンバ であるSetEntriesという関数を呼び出して、パレットの色を変更します。SetEntriesの構文は以下の通りです。

書式HRESULT SetEntries( DWORD dwFlags, DWORD dwStartingEntry, DWORD dwCount, LPPALETTEENTRY lpEntries );
dwFlagsこのフラグは現在使用していないらしいので0を指定しなければいけないらしい。
dwStartingEntry何番のパレットから設定するか(変更開始パレット番号)。
dwCount変更したいパレット数
lpEntriesパレットエントリ(PALETTEENTRY構造体)へのポインタ
戻り値 成功した場合はDD_OKが返ってくるらしい。

  この関数は、今回作成した自作関数のように1個1個パレットを設定するのでは無く、複数一気に変更出来るように 設計されています。ですから、peEntry[0]〜peEntry[255]を全て変更し、lpPalette->SetEntries(0,0,256,peEntry);とでもすれば、全部一括してパレットを変更できます。
  ただ、DirectDrawの特性上(?)0番(黒固定)と255番(白固定)のパレットは変更不可能になっています。 まぁ、白と黒は99%ゲームで使うと思うので変更出来ないからと言って気にはならないでしょう。
設定した色をGDI(テキスト)で使用してみる
  今回は、自作関数DdTextOutを改造して、色を指定できるようにします。

  まず、最初に付け加えたのがSetBkMode(hdc,TRANSPARENT);です。これは文字の背景を透明にするというもの。第5回までは、字の色が黒、背景が白という状態だったので 変な風に表示されていましたが、今回は背景を表示しないようにします。
  次にSetTextColorという関数を呼び出しています。ここで色を設定しています。GDIで色を指定する場合はRGB値(COLORREF型)という1つの数値を用いるのですが 、なんやよーわからんのでマクロ「RGB(赤,緑,青)」という便利なものを使用してRGB値を指定します。RGB(255,0,255)とすれば紫のRGB値という感じです。で、GDIでDirectDrawPaletteの色をそのまま色番号で指定する事は出来ないので 前に設定したpeEntry構造体のメンバ値を使用してRGB値を設定しています。
パレット後始末
  アプリケーション終了時には作成したDirectDrawPaletteオブジェクト(lpPalette)を解放しなければなりません。ですから自作関数EndDirectDrawの中に 「lpPalette->Release();」を追加する必要があります。まぁ、今まで通りマクロを使用する場合は「RELEASE(lpPalette);」ですが。