Game Dev/Scrap

Device Lost Handling

AKer 2008. 7. 23. 15:19
반응형
원문 : 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