Microsoft Visual Studio .NET 2003 Microsoft DirectX 9.0 SDK (December 2004) |
■リストア処理 | Top Next |
Direct3Dデバイスは一度初期化したらずっと使えるわけではありません。例えばフルスクリーン アプリケーションでキーボード
フォーカスが消失するなどのイベントが発生してレンダリングできなくなると、デバイスは消失状態になります。この状態をデバイスロストといいます。
この後アプリケーションがフォーカスを受け取った後、Direct3Dデバイスをレンダリング可能な状態に戻す必要があります。この処理をリストアといいます。
Direct3Dデバイスがロストする条件には次のパターンがあります。
・フルスクリーンでキーボードのをウィンドウズキーを押したとき
・フルスクリーンでAlt+Tabを押してタスク切り替えを行ったとき
・ノートPCで電力管理イベントが発生したとき
・他のアプリケーションがフルスクリーンになったとき
1.IDirect3DDevice9 インターフェイス
常にリストアします。
2.D3DPOOL_DEFAULT メモリ クラスに配置されているすべてのリソース
D3DPOOL_DEFAULTに設定できるリソースの一覧(多分これで全部)です。
IDirect3DTexture9 インターフェイス | テクスチャーです。通常は、D3DPOOL_MANAGEDに設定します。ただし、レンダーターゲットや動的テクスチャーとして使用する場合はD3DPOOL_DEFAULTにする必要があります。 |
IDirect3DCubeTexture9 インターフェイス | キューブテクスチャーです。 |
IDirect3DVolumeTexture9 インターフェイス | ボリュームテクスチャーです。 |
IDirect3DVertexBuffer9 インターフェイス | 頂点バッファです。 |
IDirect3DIndexBuffer9 インターフェイス | インデックスバッファです。 |
3.IDirect3DSurface9 インターフェイス
IDirect3DDevice9::CreateRenderTarget メソッドとIDirect3DDevice9::CreateDepthStencilSurface メソッドで
作成したリソースと、サーフェイスの管理下にあるリソース(IDirect3DTexture9など)がD3DPOOL_DEFAULTで作成されている場合、サーフェイスもリストアします。
4.ID3DXEffect インターフェイス
シェーダーを使用するときに利用するインターフェイスです。ID3DXEffect::OnLostDeviceメソッドで開放し、
ID3DXEffect::OnResetDeviceメソッドでリストアします。D3DXCreateEffect...関数により再度作成する必要はありません。
5.IDirect3DStateBlock9 インターフェイス
レンダー ステートをカプセル化するインターフェースです。常にリストアします。
6.ID3DXRenderToSurface インターフェイス
レンダリングサーフェイス。常にリストアします。
7.IDirect3DSwapChain9 インターフェイス
スワップチェインインターフェースです。シーンを別々の設定のカメラで観察したときのレンダリング結果を表示する画面です。
明示的に使用したことがないのでよく知りませんが(笑)。
筆者が把握しているものでもこれだけあります。面倒ですがこれ全部リストアする必要があります。
---main.cpp---
//m_pd3dDeviceとm_d3dParametersは初期化済みする //LPDIRECT3DDEVICE9 m_pd3dDevice; //D3DPRESENT_PARAMETERS m_d3dParameters; //レンダリング可能状態か static BOOL RenderOK = TRUE; BOOL MainLoop() { HRESULT hr; //**************************************************************** //レンダリング可能状態のとき //**************************************************************** if( RenderOK == TRUE ) { //シーンのクリア m_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL, 0x0, 1.0f, 0L); m_pd3dDevice->BeginScene(); //**************************************************************** //ここで3Dオブジェクトをレンダリングする //**************************************************************** m_pd3dDevice->EndScene(); hr = m_pd3dDevice->Present( NULL, NULL, NULL, NULL ); //**************************************************************** switch( hr ) { //デバイスロストしたとき case D3DERR_DEVICELOST: RenderOK = FALSE; break; //内部ドライバーエラー case D3DERR_DRIVERINTERNALERROR: return FALSE; break; //メソッドの呼び出しが無効 case D3DERR_INVALIDCALL: return FALSE; break; } } //**************************************************************** //レンダリング不可能状態のとき //**************************************************************** else { //**************************************************************** //リストア可能か調査する //**************************************************************** hr = m_pd3dDevice->TestCooperativeLevel(); switch( hr ) { //デバイスは消失しているがリストア可能状態 case D3DERR_DEVICENOTRESET: //レンダリングターゲット・深度ステンシルサーフェイス・追加スワップチェーン・ステートブロック・D3DPOOL_DEFAULTリソースを開放する //アプリケーションごとに個別に処理する Cleanup(); //デバイスの復元を行う if( FAILED( hr = m_pd3dDevice->Reset( &m_d3dParameters ) ) ) return FALSE; //レンダリングターゲット・深度ステンシルサーフェイス・追加スワップチェーン・ステートブロック・D3DPOOL_DEFAULTリソースを初期化する //アプリケーションごとに個別に処理する Init(); //リストアが終了したのでレンダリング可能にする RenderOK = TRUE; break; } } return TRUE; }
Cleanup()とInit()は、それぞれ開放と初期化を行います。