반응형
원문 : http://www.gpgstudy.com/gpgiki/DxDeviceLostHandling
//**** 디바이스 리소스 인터페이스.. // 디바이스 의존적인 리소스들의 추상클래스. struct IDeviceRes { virtual void Invalidate() = 0; virtual bool SetValidate() = 0; }; //**** 텍스쳐 클래스 class CTextureRes : public IDeviceRes { public: virtual void Invalidate() { 텍스쳐 해제; } virtual bool SetValidate() { 텍스쳐 다시 로드; } bool Load(); void Unload(); protected: char m_szFileName[256]; LPDIRECT3DTEXTURE9 m_pTexture; }; //**** 텍스쳐를 관리할 클래스(클라이언트에서 접근하여 사용) class CDataContainer { public: LoadTexture( const char* szFileName ) { // 1. 텍스쳐 로딩 // 2. 만약 텍스쳐가 VRam에 잡혔다면..(D3DPOOL_DEFAULT) // 2.1 랜더러의 의 VRam리스트에 등록(m_pRenderer->m_VRamRes) // 3. 텍스쳐가 다른모드로 생성되었다면..(D3DPOOL_MANAGED or etc..) // 3.1 랜더러의 의 Managed리스트에 등록(m_pRenderer->m_ManagedRes) } UnloadTexture( const char* szFileName ) { // 랜더러의 디바이스 목록에서 지운다. m_pRenderer->Unregist( szFileName ); } protected: vectorm_TextureContainer; CRenderer* m_pRenderer; } //**** 문제의 랜더러 클래스 class CRenderer { public: // 디바이스가 해제 됬거나 해제 하라. // - 이 함수는 외부에서 임의로 호출이 가능하다. void InvalidateDevice( HRESULT hrDeviceState ) { if ( FAILED( hrDeviceState ) { if ( D3DERR_DEVICENOTRESET == hrDeviceState ) { // 1. m_VRamRes 리소스만 해제한다. // for_each(m_VRamRes의 시작에서 끝까지) { m_VRamRes[i]->Invalidate(); } } else if ( D3DERR_DEVICELOST == hrDeviceState ) { // 1. m_VRamRes과 m_ManagedRes들에 대해서 해제한다.(전 리소스들에 대해 수행) // for_each(m_VRamRes의 시작에서 끝까지) { m_VRamRes[i]->Invalidate(); } // for_each(m_ManagedRes의 시작에서 끝가지) { m_ManagedRes[i]->Invalidate(); } // 2. 디바이스를 릴리즈한다. } } m_hrDeviceState = hrDeviceState; // 디바이스 상태값 업데이트 } // 디바이스가 활성화하라. // - 이 함수도 외부에서 임의로 호출이 가능하다. bool SetValidateDevice() { if ( FAILED(m_hrDeviceState) ) { if ( D3DERR_DEVICENOTRESET == m_hrDeviceState ) { //**** 디바이스를 복구할수 있다. // 1. IDrect3DDevice::Reset()한다. // 2. 랜더 스테이트 / 뷰행렬 셋팅 // 3. m_VRamRes 리소스들을 다시 로딩한다. // for_each(m_VRamRes의 시작에서 끝까지) { m_VRamRes[i]->SetValidate(); } } else if ( D3DERR_DEVICELOST == m_hrDeviceState ) { //**** m_VRamRes 복구할수 없다. // 1. 디바이스를 재생성한다. // 2. 랜더 스테이트 / 뷰행렬 셋팅 // 3. m_VRamRes / m_ManagedRes 리소스를 로딩한다. // for_each(m_VRamRes의 시작에서 끝까지) { m_VRamRes[i]->SetValidate(); } // for_each(m_ManagedRes의 시작에서 끝가지) { m_ManagedRes[i]->SetValidate(); } } // 검증해본다. m_hrDeviceState = m_pDevice->TestCooperativeLevel(); return SUCCEEDED(m_hrDeviceState); } return true; } // 랜더링한다. void RenderAll() { //**** 디바이스가 유효한 상태가 아니라면 그냥 리턴. if ( FAILED(m_hrDeviceState) ) return; // ... //**** 모든 그래픽들에 대한 랜더링을 한다. // ... //**** 백버퍼 플리핑. m_hrDeviceState = m_pDevice->Present( NULL, NULL, NULL, NULL ); if ( FAILED(m_hrDeviceState) ) { // 디바이스에 뭔가 이상이 있다면,, InvalidateDevice( m_hrDeviceState ); // 외부에 알려준다. 아마 누군가에게 알려줄 필요가 있을껏이다. // CApp나 혹은 다른 누군가에게.. } } protected: //**** properties // 디바이스 의존적인 메모리 관리 vector m_VRamRes; // POOL_DEFAULT vector m_ManagedRes; // MANAGED or etc HRESULT m_hrDeviceState; // 현재의 디바이스 상태값 LPDIRECT3DDEVICE9 m_pDevice; };
반응형
'Game Dev > Scrap' 카테고리의 다른 글
Starcraft 2 Effects & Techniques (0) | 2008.08.20 |
---|---|
The Function Pointer Tutorial (0) | 2008.08.11 |
Resource Management Best Practices (0) | 2008.07.23 |
Synchronized block in C++ (0) | 2008.06.09 |