読者です 読者をやめる 読者になる 読者になる

GameProgrammar's Night

ゲームプログラム系の覚え書き

Direct3D9でウインドウモード・フルスクリーンの動的切り替え手順

 そろそろXPのサポートも終わるのに今更DX9かよって感じですが……。

手順

  1. Direct3DのDEFAULT_POOLで作成した各種バッファをRelease(頂点とかテクスチャとか)
  2. D3DPRESENT_PARAMSを適切に設定する
    • ウインドウ/フルスクに合わせて、WindowedのTRUE/FALSE
    • ウインドウサイズが変わるなら、バックバッファの幅高さ
    • FullScreen_RefreshRateInHzは、ウインドウモードの時は0にしないといけないので忘れずに
  3. Direct3D9DeviceのResetメソッドを呼ぶ
  4. SetWindowLong関数でウインドウスタイルを変更
    • フルスクリーン時は、WS_POPUPに
  5. ウインドウサイズが変わるなら、SetWindowPos関数とか
  6. すべてのウインドウ設定変更が終わったら、ShowWindow関数でウインドウを再描画

 1~3はデバイスロストからの復帰と同じ手順ですので、自分のライブラリでは切り替えメソッドが呼ばれたら、内部的にはデバイスロスト扱いにしてしまいデバイスロスト復帰処理を実行させてます。
 はじめはウインドウ関係の設定をしてからResetをかけてたのですが、それだと反映されないウインドウ設定があるようなので、Resetかけてからウインドウ設定をいじった所、上手く行ったのでそうしています。

 なお、Resetはメッセージ処理と関係があるらしいので、メッセージ処理と同スレッドで実行しつつ、メッセージ処理も実行させないといけないそうです。つまり、

while(FAILED(pDevice->Reset(&d3dpp)));

 なんて書いてしまうと、いつまでもResetが成功せずにフリーズしてしまうことがありますので注意