DirectX編・・・。
DirectX (ダイレクトエックス) ダウンロード/総合情報 - Microsoft
DirectXは、Microsoftが開発したマルチメディアAPI・・・。
ゲーム開発における、グラフィック、サウンド、入出力の実装などに役立っている・・・。
最新はDirectX12だが、ここではとってもレガシーなDirectX7から扱っていく・・・少しだけ・・・。
DirectX7にはDirectDrawというとってもレガシーな2D処理API群があったので、それを使って画像を表示してみる・・・。
ここでの実行環境はWIndows7なので、このOSでの最終バージョンは、
Download DirectX Software Development Kit from Official Microsoft Download Center
DXSDK_Jun10.exeである・・・。
しかし、このバージョンはDirectDraw非対応になってしまったので、DirectDrawが使えるのは、
Download DirectX Software Development Kit from Official Microsoft Download Center
DXSDK_Feb10.exeなので、こっちをダウンロードしてインストール・・・。
また、インストール中にエラーが出ることがある・・・。
DirectX SDKインストール時に”S1023エラー”が出る時の対処法
こんなのが出たので、再配布パッケージを削除してから再インストールするなど・・・。
インストールしたら、
[ツール]-[オプション]から、
インクルードパスが通ってるか確認・・・。
ライブラリパスも・・・。
上に追加されてるとおもうので下に寄せとく・・・。
(他のライブラリとのビルド順調整のつもり・・・。)
Win32の空のプロジェクトを作成したら、
ddraw.libとdxguid.libをリンク・・・。
test.bmpを置く・・・。
でIDirectDrawSurface7.cppを追加して、コードを書いてく・・・。
ddraw.hをインクルード・・・。
DirectXはCOMベースのライブラリなので、ポインタを指定するとReleaseメソッドが呼ばれてポインタをNULLにするようなマクロSAFE_RELEASEを用意しておくのが慣習・・・。
たくさん、変数やらオブジェクトやらあるが、都度説明・・・。
まずは、
高速描画を実現するため、PeekMessageによるメインループ構造にする・・・。
メッセージが来ていない時に、DirectXによる描画処理を行う・・・。
(ゲーム開発ではよく使われている慣習・・・。)
まずはiPhaseが0の時(一回しか実行されない)は、DirectXによる描画の準備を行う・・・。
DirectDrawCreateExでDirectDrawオブジェクトを生成する・・・。
戻り値はHRESULT型なので、FAILEDマクロで判定して、失敗ならbreakして終了処理に向かう・・・。
lpDDの型はLPDIRECTDRAW7となっているが、DirectDrawCreateでLPDIRECTDRAWなポインタを指定するなどしても作成はできる・・・。
ただし、LPDIRECTDRAW7とは違うものなので、より新しいの"7"の付いてるほうにしたほうがいいだろう・・・。
lpDD->SetCooperativeLevelで協調レベル設定・・・。
協調レベルについては、
協調レベル
こういうものらしい・・・。まあ、今回は普通のウィンドウアプリなのでDDSCL_NORMALを指定・・・。
クリッパーは表示できる範囲を指定するもので、オブジェクトポインタがlpClipに入ったら、lpClip->SetHWndでウィンドウハンドルを指定する・・・。
続いて、ウィンドウに表示される画面、プライマリーサーフェイスを作る・・・。
まず、プライマリサーフェイスディスクリプタで設定する・・・。
DDSCAPS_PRIMARYSURFACEでプライマリーサーフェイスであることを指定・・・。
DDSURFACEDESC2を使っているが、DDSURFACEDESCと間違えないように・・・。
でddsdを使って、lpDD->CreateSurfaceでプライマリーサーフェイスlpDDSPrimaryを作る・・・。
lpDDSPrimary->SetClipperでlpClipを指定・・・。
さて、続いて、表示する画像test.bmpを貼り付けたサーフェイスを作成する・・・。
まず、test.bmpをロードする・・・。
メモリデバイスコンテキストhMemDCを作成・・・。
SelectObjectでhMemDCとhBitmapを紐づけ・・・。
画像の幅と高さを知りたいので、GetObjectでBITMAPオブジェクトbitmap取得・・・。
サーフェイスディスクリプタを設定・・・。
システムメモリでオフスクリーン(表示されない)なサーフェイスで、ビットマップの幅と高さに合わせたものとして作成・・・。
lpDD->CreateSurfaceでサーフェイス作成・・・。
lpDDSBitmap->GetDCで、このサーフェイスのデバイスコンテキストを取得・・・。
BitBltでメモリデバイスコンテキストから、ビットマップサーフェイスのデバイスコンテキストにビット転送・・・。
これでビットマップサーフェイスに画像が映る・・・。
lpDDSBitmap->ReleaseDCでビットマップサーフェイスのデバイスコンテキストを解放・・・。
hDDSBitmapDCはもうNULLにしちゃう・・・。
(これをやっても、プライマリーサーフェイスに描画した時、画像は消えていない・・・。)
iPhaseを1にする・・・。
これでここはもう通らない・・・。
次にここに来る・・・。
ここでサーフェイスを描画する・・・。
GetWindowRectでウィンドウ矩形を取得し、ウィンドウタイトルとか境界線とかの分を調整したら、lpDDSPrimary->BltでlpDDSPrimaryの上にlpDDSBitmapを描画する・・・。
IDirectDrawSurface7::Blt method (Windows)
でこれを繰り返してる・・・。
ウィンドウの閉じるボタンなどで、メインループを抜けたら、
作成した順とは逆にSAFE_RELEASEなどで削除・解放をしていく・・・。
これで実行すると、
test.bmpが表示される・・・。
Sample/dx/IDirectDrawSurface7/Blt/src/IDirectDrawSurface7 at master · bg1bgst333/Sample · GitHub