반응형
원문 : 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:
vector m_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 |