ゲームプログラミング練習帳

GDIビットマップ(DDB)作成

Windowsの描画機能(GDI)には、GDIの描画結果を保持しておくためのビットマップ(ハンドル型HBITMAPで管理されるデバイス依存のビットマップ-DDB)があります。このビットマップを使うと、GDIの機能を使って描いた描画内容を画像として保存しておけるので、GDIでグラフを描いてウインドウなどに表示する場合に便利です。ビットマップを使わないと、ウインドウの再描画時(WM_PAINT処理時)に毎回GDIでグラフを描かないといけませんが、グラフをビットマップに描いておけば、そのビットマップを描画するだけですむからです。
こうした「ビットマップに一度描いてからそのビットマップを表示する」方式は、ダブルバッファと呼ばれ、処理の効率化と描画時のちらつきを抑えるのに効果的です。ゲームプログラミングでも、ゲームの画面は基本的にビットマップ(DDBとは限りませんが)に描かれますね。

DDBの作成と表示

DDBの作成は、簡単です。DDBを生成するAPI、CreateCompatibleBitmap()にデバイスコンテキストと大きさを渡すだけ。これで、指定したデバイスコンテキストと同じ(互換性のある)形式のビットマップを作ることができます。
例えば、ウインドウhwndに表示するための256*256ピクセルのDDBを作るなら、以下のようにします。

  hdc = GetDC(hwnd);

  hbmpTest = CreateCompatibleBitmap(hdc, 256, 256);

これで、ビットマップhbmpTestが生成されたので、次にこのビットマップに描画するためのデバイスコンテキストを作成します(このデバイスコンテキストは、画面ではなくメモリ上のビットマップに描画するためのデバイスコンテキストなので、メモリデバイスコンテキストと呼ばれることもあります)。このデバイスコンテキストも、ウインドウ(とDDB)と互換性のある形式で作成します。
DDBとDDBに描画するためのデバイスコンテキストができれば、後はウインドウのデバイスコンテキストは不要なので、解放しておきましょう。

  hdcTest = CreateCompatibleDC(hdc);

  ReleaseDC(hwnd, hdc);

これで、描画を行うメモリデバイスコンテキストとその描画結果を画像として保持するDDBができました。最後に、DDBをメモリデバイスコンテキストの操作対象に選択すれば、メモリデバイスコンテキストへの描画がDDBに反映されるようになります。

  hbmpTestOld = (HBITMAP)SelectObject(hdcTest, hbmpTest);

なお、ここでSelectObjectの戻り値(以前選択されていたHBITMAP)を保存しているのは、DDBを使い終わってDDBとメモリデバイスコンテキストを削除するときに、メモリデバイスコンテキストに「以前選択されていたHBITMAP」を選択することで、DDBの選択状態を解除するためです。

今回は、このメモリデバイスコンテキストに対して、適当なグラデーションをSetPixel()で描いてみました。

  for (i = 0;i < 256;i++) {
      for (j = 0;j < 256;j++) {
          SetPixel(hdcTest, j, i, RGB(128, j, i));
      }
  }

このDDBをウインドウに表示する処理は、DDBを選択したメモリデバイスコンテキストをウインドウのデバイスコンテキストにBitBlt()する形で行います。

  case WM_PAINT:

      hdc = BeginPaint(hwnd,&ps);

      /* DDBをウインドウ上に描画 */
      BitBlt(hdc, 0, 0, 256, 256, hdcTest, 0, 0, SRCCOPY);

      EndPaint(hwnd, &ps);

      return 0;
BitBlt
BOOL BitBlt(
  HDC hdcDest,
  int nXDest,
  int nYDest,
  int nWidth,
  int nHeight,
  HDC hdcSrc,
  int nXSrc,
  int nYSrc,
  DWORD dwRop
);
hdcDest描画対象のHDC
nXDest/nYDest描画位置
nWidth/nWidth描画サイズ
hdcDest描画元のHDC
nXSrc/nYSrc描画開始位置
dwRopラスタオペレーション

以上で、DDBの作成から表示までの一連の流れを処理することができました。最後に、使い終わったDDBとメモリデバイスコンテキストは、忘れずに削除しておきましょう。

  /* DDBの選択状態を解除 */
  SelectObject(hdcTest, hbmpTestOld);

  /* メモリデバイスコンテキスト削除 */
  DeleteDC(hdcTest);

  /* DDB削除 */
  DeleteObject(hbmpTest);

プログラム

DDBを作成し、表示するサンプルです。

プログラムソース表示 プログラムダウンロード


トップ 戻る