Sign in to follow this  

Device recreation design (OOP)

This topic is 4855 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi! As everybody knows you need to call OnLostDevice() and OnResetDevice() on certain interfaces (such like ID3DXSprite). Right now I have 2 functions in my base renderer named LostDevice/ResetDevice where all interfaces are being restored, it would look as follows:
void CBaseRenderer::LostDevice()
{
    if(pSprite) pSprite->OnLostDevice();
    if(pFont) pFont->OnLostDevice();
}
Now the more objects I create, the more often I need to check to include these lines in my LostDevice() function in order to reset my device correctly. Now my thoughts: Wouldn't it be possible to send a kind of message to all objects/classes so that they would recreate themselves? Say I'm doing it this way (pseudocode):
void CBaseRenderer::LostDevice()
{
    MessageToAllInterfaces(DEVICE_LOST);
}
and my wrapped interfaces would have kind of a message map:
void CMySprite::OnMessage(WPARAM message)
{
    if(message == DEVICE_LOST) pSprite->OnLostDevice();
}
Would this be possible in any way at all? thanks for your thoughts and suggestions

Share this post


Link to post
Share on other sites
What about

class IVolatileResource
{
public:
virtual void OnDeviceLost() = 0;
virtual void OnDeviceReset() = 0;

IVolatileResource()
{
Render->AddVolatileResource(this);
}
virtual ~IVolatileResource()
{
Render->RemoveVolatileResource(this);
}
};


And derive all your objects that contain direct3d objects in them from this class. Have your CBaseRender class have this somewhere:

class CBaseRender
{
protected:
std::list < IVolatileResource * > m_VolatileResources;

public:
void AddVolatileResource(IVolatileResource * Resource);
void RemoveVolatileResource(IVolatileResource * Resource);

...

void LostDevice()
{
for(std::list < IVolatileResource * >::iterator i = m_VolatileResources.begin(); i != m_VolatileResources.end(); ++i)
(*i)->OnDeviceLost();
}
void ResetDevice()
{
for(std::list < IVolatileResource * >::iterator i = m_VolatileResources.begin(); i != m_VolatileResources.end(); ++i)
(*i)->OnDeviceReset();
}
};


I realize this isn't such a good solution since you can't change what ID3DXSprite derive from and such, but you can derive your classes that contain them from it, and do your device management in 'batches':

class CLevel : public IVolatileResource // will be notified when device is lost and reset
{
ID3DXSprite * m_SpriteEngine;
ID3DXFont * m_Font;

...

CLevel()
{
// create ID3DXSprite and ID3DXFont
}

void OnDeviceLost()
{
m_SpriteEngine->OnLostDevice();
m_Font->OnLostDevice();
}

void OnDeviceReset()
{
m_SpriteEngine->OnResetDevice();
m_Font->OnResetDevice();
}
};


It was much easier for me to do it this way since my renderer was abstracted, and I could derive each and every vertex buffer and texture from IVolatileResource, and add it to the volatile resource list when needed (the resource is in the default pool).

Edited by Coder: Code was too wide. Used source tags

[Edited by - Coder on August 28, 2004 3:32:28 AM]

Share this post


Link to post
Share on other sites
this is the code that MS application wizard done:
Quote:

if( m_bDeviceLost )
{
// Test the cooperative level to see if it's okay to render
if( FAILED( hr = m_pd3dDevice->TestCooperativeLevel() ) )
{
// If the device was lost, do not render until we get it back
if( D3DERR_DEVICELOST == hr )
return S_OK;

// Check if the device needs to be reset.
if( D3DERR_DEVICENOTRESET == hr )
{
// If we are windowed, read the desktop mode and use the same format for
// the back buffer
if( m_bWindowed )
{
D3DAdapterInfo* pAdapterInfo = m_d3dSettings.PAdapterInfo();
m_pD3D->GetAdapterDisplayMode( pAdapterInfo->AdapterOrdinal, &m_d3dSettings.Windowed_DisplayMode );
m_d3dpp.BackBufferFormat = m_d3dSettings.Windowed_DisplayMode.Format;
}

if( FAILED( hr = Reset3DEnvironment() ) )
return hr;
}
return hr;
}
m_bDeviceLost = false;
}


the core of this source is TestCooperativeLevel() that can give you D3DERR_DEVICELOST.

I hope that this help you... byezz

Share this post


Link to post
Share on other sites
/*
* Class : DX9Object
*
* Desc : base class for all dx9 objects. manipulates
* recreation of device related structures
**/

class CORE_API DX9Object {
protected:
/* Local flags */
bool m_bInitialized;
bool m_bRestored;
private:
/* Linked list of all objects */
static LNode<DX9Object> *pDX9Objects;

/* Ptr to current object in lit */
LNode<DX9Object> *pCurrent;

/* Are objects intialized */
static bool bObjectsInited;
/* Are objects restored */
static bool bObjectsRestored;
public:
/* Default ctor */
DX9Object();
/* Destructor */
virtual ~DX9Object();

/*
* DX9Object iface
**/

virtual HRESULT Initialize() = 0;
virtual HRESULT Delete() = 0;
virtual HRESULT Restore() = 0;
virtual HRESULT Invalidate() = 0;

/*
* Static iface for resetting al objects
**/


static HRESULT InitializeDeviceObjects();
static HRESULT DeleteDeviceObjects();
static HRESULT RestoreDeviceObjects();
static HRESULT InvalidateDeviceObjects();

/* are all objects initialized and restored */
static bool GetStatus();
};

This is how I do it.

[Edited by - Coder on August 28, 2004 3:56:29 PM]

Share this post


Link to post
Share on other sites
I don't know if unmanaged DX has this, but in managed DX you can select a "pool" for your resources to be created in. There's a pool called Managed that copies your resources to the appropriate location for device access when necessary, but the resources are also backed by system memory and recreated automatically on a device reset.

Share this post


Link to post
Share on other sites

This topic is 4855 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this