Thread: Reloading Meshes on Device Reset

  1. #1
    Registered User
    Join Date
    Jun 2003
    Posts
    361

    Reloading Meshes on Device Reset

    Hullo hullo,

    After doing an Alt-Tab out of a DX program while its running, and then trying to refocus back onto the window, DX likes to do some crazy things and some resources need to be reset.

    The two I've learned this about so far are the ID3DXFont object and the camera; which need to be released/reset. The code I have for this looks like this:
    Code:
    bool cDX::D3DHasFocus(void)
    {
    	long Attempt;
    	      
    	Attempt = D3DDevice->TestCooperativeLevel();
    
    	if(SUCCEEDED(Attempt))
    		return true;
    
    	if(Attempt == D3DERR_DEVICELOST)
    	{
    		Font->LostFocus();
    	}
    	else if(Attempt == D3DERR_DEVICENOTRESET)
    	{
    		if(SUCCEEDED(D3DDevice->Reset(&PP)))
    		{
    			Font->GotFocus();
    			Camera->Init(D3DDevice, (float)PP.BackBufferWidth, (float)PP.BackBufferHeight);
    		}
    	}
    
    	return false;
    }
    
    //Note, Position, Look, Up, and Right are initialised in the Class constructor to avoid them
    //being reset each to their hard-coded values upon re-focussing.
    void cCamera::Init(IDirect3DDevice9* D3DDevice, float ScreenWidth, float ScreenHeight)
    {
    	float AspectRatio = (ScreenWidth / ScreenHeight);
    	D3DXMATRIX  matView;
    	D3DXMATRIX	matLens;
    	D3DXMATRIX	matWorld;
    
    	D3DXMatrixLookAtLH(&matView, &Position, &Look, &Up);
    	D3DDevice->SetTransform(D3DTS_VIEW, &matView);
    
    	D3DXMatrixPerspectiveFovLH(&matLens, D3DX_PI/4, AspectRatio, 1.0f, 2000.0f);
    	D3DDevice->SetTransform(D3DTS_PROJECTION, &matLens);
    
    	D3DXMatrixIdentity(&matWorld);
    	D3DDevice->SetTransform(D3DTS_WORLD, &matWorld);
    }
    
    void cFont::LostFocus(void)
    {
    	FontDevice->OnLostDevice();
    }
    
    void cFont::GotFocus(void)
    {
    	FontDevice->OnResetDevice();
    }
    Now, the problem I'm having is with my meshes. If I Alt-Tab out, then open the window back up, my program is telling me I'm still rendering 125 objects, but anything that WAS being rendered beforehand just isn't anymore.

    I'm assuming the problem lies somewhere in having to release/reset an object related to these meshes. But I don't really see anything too unique to my mesh class (it consists of a D3DDevice passed from my DX class, but I doubt it has anything to do with that since it's always pointing to the same thing).

    So I guess I'm just wondering what exactly has to be reset in order to render these meshes again. Any help is appreciated.
    Pentium 4 - 2.0GHz, 512MB RAM
    NVIDIA GeForce4 MX 440
    WinXP
    Visual Studio .Net 2003
    DX9 October 2004 Update (R.I.P. VC++ 6.0 Compatability)

  2. #2
    vae victus! skorman00's Avatar
    Join Date
    Nov 2003
    Posts
    594
    When you reset the device, DirectX releases all of the resources that were being used. You can either create your own manager that will reload the used meshes when you reset the device, or you can let DirectX handle it by loading your meshes with the D3DXMESH_MANAGED option. Same goes for textures and vertex buffers, but they use D3DPOOL_MANAGED if my memory serves me. I'm pretty sure D3DXMESH_MANAGED == D3DPOOL_MANAGED, but it's nice to use the more descriptive flags when able.

  3. #3
    Registered User
    Join Date
    Jun 2003
    Posts
    361
    Hm, which call would you be referring to for that flag?

    My CloneMeshFVF() uses the D3DXMESH_MANAGED flag already, while my D3DXLoadMeshFromX() call uses a D3DXMESH_SYSTEMMEM call.

    I didn't notice the CloneMeshFVF() line at first, and strangely when I changed D3DXMESH_SYSTEMMEM to D3DXMESH_MANAGED my program still compiled and ran just fine. Probably some lucky number work going on behind the scenes there.

    Currently I use a linked list of meshes. Would creating my own manager pretty much entail deleting that linked list, removing all the meshes/cleaning all the memory, then loading every mesh in once again?
    Pentium 4 - 2.0GHz, 512MB RAM
    NVIDIA GeForce4 MX 440
    WinXP
    Visual Studio .Net 2003
    DX9 October 2004 Update (R.I.P. VC++ 6.0 Compatability)

  4. #4
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Yes that is a good design actually. You can simply move through the list and re-load as necessary.

    It's a major pain in the arse working in a cooperative pre-emptive mult-tasking environment because someone or something can pre-empt your game and do something else. But by standards you cant call it Windows compatible unless you can ALT-TAB and abide by other standards set by MS. Not that we really care.


  5. #5
    vae victus! skorman00's Avatar
    Join Date
    Nov 2003
    Posts
    594
    I agree with Bubba, alt + tabing is always nice to have. Don't forget alt + enter!

    Those were the calls I was referring to, if you have D3DXLoadMeshFromX with D3DXMESH_MANAGED as one of the options parameter, you should be fine. And yes, making your own manager would entail just what you described. That would be exactly what Direct3D does when everything is created with the XXX_MANAGED flag, but you can do a better job. In managed mode, Direct3D will swap data between memory on the video card and system memory based on how it's been culling over the past few frames, and draw order.

  6. #6
    Registered User
    Join Date
    Apr 2002
    Posts
    1,571
    You might want to look into using the Observer design pattern for releasing/restoring resources when a device is lost/reset.
    Last edited by MrWizard; 05-30-2005 at 01:13 PM.
    "...the results are undefined, and we all know what "undefined" means: it means it works during development, it works during testing, and it blows up in your most important customers' faces." --Scott Meyers

  7. #7
    Registered User
    Join Date
    Jun 2003
    Posts
    361
    Cool thanks guys, that's what I was hoping to hear I'll get started on this here then inbetween work.

    I've never come across an Observer design pattern...let alone any design pattern ...But I'll look into what it is. Thanks for the lead MrWizard.
    Pentium 4 - 2.0GHz, 512MB RAM
    NVIDIA GeForce4 MX 440
    WinXP
    Visual Studio .Net 2003
    DX9 October 2004 Update (R.I.P. VC++ 6.0 Compatability)

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problems with GetAsyncKeyState
    By blurrymadness in forum C++ Programming
    Replies: 13
    Last Post: 04-21-2007, 06:13 PM
  2. Replies: 1
    Last Post: 07-31-2006, 02:57 PM
  3. Device Driver: sysfs confusion
    By filker0 in forum Linux Programming
    Replies: 0
    Last Post: 12-02-2005, 11:36 AM
  4. Replies: 4
    Last Post: 06-30-2004, 03:11 PM
  5. Device problem
    By John22 in forum C Programming
    Replies: 0
    Last Post: 12-19-2002, 12:02 PM