デバイスをロストした時の処理

フルスクリーンモードのときにAlt+Tab等でウィンドウを切り替えた時など、
Direct3Dの関数が D3DERR_DEVICELOST を返して失敗するようになります。
この状態から復帰するには以下のようにします。

  • IDirect3DDevice9::Present() を呼び出したとき D3DERR_DEVICELOST が返されます。
  • IDirect3DDevice9::TestCooperativeLevel() の返り値を見て D3DERR_DEVICENOTRESET が返されるまで待ちます。
  • IDirect3DDevice9 を使用して作成したリソース ( IDirect3DTexture9,IDirect3DVertexBuffer9 等 )を開放します。
  • IDirect3DDevice9::Reset() を呼び出します。
  • IDirect3DDevice9::Reset() を呼び出す前に開放したものを再度作成します。
  • IDirect3DDevice9::Reset() を呼び出すとレンダーステート等もリセットされているので設定しなおします。

ソースコードはこんな感じです。

HRESULT result = mDevice->TestCooperativeLevel();
if( result != D3D_OK ){
    if( result == D3DERR_DEVICENOTRESET ){
        mVertexBuffer->Release();
        mDevice->Reset( &mPresentParameters );
        mDevice->CreateDevice( ... );
        mDevice->SetRenderState( ... );
    }
}


ちなみにフルスクリーンモードからウィンドウモードに切り替えたいときも似たような処理を行います。
手順は以下の通りです。

  • IDirect3DDevice9::Reset() に渡す D3DPRESENT_PARAMETERS の Windowed を TRUE, または FALSE に設定します。
    IDirect3D::CreateDevice() を呼び出したときの D3DPRESENT_PARAMETERS を保存しておくと良いです。
    ちなみにフルスクリーンモードに切り替えるときはデバイスがサポートしている画面サイズを
    D3DPRESENT_PARAMETERS の BackBufferWidth, BackBufferHeight に設定します。
    デバイスがサポートしていない画面サイズを設定するとリセットが失敗します。
  • IDirect3DDevice9 を使用して作成したリソース ( IDirect3DTexture9,IDirect3DVertexBuffer9 等 )を開放します。
  • IDirect3DDevice9::Reset() を呼び出します。
  • IDirect3DDevice9::Reset() を呼び出す前に開放したものを再度作成します。
  • レンダーステート等を再設定します。

そのうちきちんと整理してソースをアップしたいと思います。

コメントする

post date*

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

トラックバックする

トラックバック用URL:

アニメーションが親切に解説されております

レンダリング、ライティングの基本が分かります

図版が見やすい美術解剖書です