DirectX:Direct3D:Tutorials:VB:DX8:Device Restoration

From GPWiki

Files:GUITutorial_warn.gif The Game Programming Wiki has moved! Files:GUITutorial_warn.gif

The wiki is now hosted by GameDev.NET at wiki.gamedev.net. All gpwiki.org content has been moved to the new server.

However, the GPWiki forums are still active! Come say hello.

First you want to make your declarations:

Private D3DParams As D3DPRESENT_PARAMETERS  'Holds the d3d parameteres 

This will hold the information needed to restore the Direct3D device. We want to set it up like so during the DirectX initialization:

D3DParams = D3DWindow

D3DWindow variable is your "D3DPRESENT_PARAMETERS" variable. To see how it is set up, it may be something like this:

'Full Screen Mode
If ScreenStyle = 0 Then
 
    DispMode.Format 		= D3DFMT_R5G6B5
    DispMode.Width 		= GameWidth
    DispMode.Height 		= GameHeight
    D3DWindow.SwapEffect 	= D3DSWAPEFFECT_FLIP
    D3DWindow.BackBufferCount 	= 1
    D3DWindow.BackBufferFormat 	= DispMode.Format
    D3DWindow.BackBufferHeight 	= GameHeight
    D3DWindow.BackBufferWidth 	= GameWidth
    D3DWindow.hDeviceWindow 	= frmMain.hWnd
 
'Windowed Mode
ElseIf ScreenStyle = 1 Then
 
    D3D.GetAdapterDisplayMode D3DADAPTER_DEFAULT, DispMode  	'Get Current Display Mode
    D3DWindow.Windowed 		= 1  				'Tell DX To Use Windowed Mode
    D3DWindow.SwapEffect 	= D3DSWAPEFFECT_COPY
    D3DWindow.BackBufferFormat 	= DispMode.Format   		'Use Retrieved Format
    frmMain.Width 		= GameWidth * 15
    frmMain.Height 		= GameHeight * 15
 
Else
 
    Engine_Deinit
 
End If

Note that your program will probably look different then this, but you will probably have a lot of those same variables, depending on if you are using FullScreen or Windowed mode. Now that you have D3DParams set, time to create your render state variables. You will most likely (if your program runs) have this already in your code, but you want to make it accessable through a sub for retrieval multiple times (for device restoration and engine initialization). I did this like so:

D3DDevice.SetVertexShader FVF  						'Set The Vertex Shader
D3DDevice.SetRenderState D3DRS_LIGHTING, False  			'Disable Hardware Lighting (Using Vertex Lighting)
D3DDevice.SetRenderState D3DRS_SRCBLEND, D3DBLEND_SRCALPHA		'Set The Source Blending Method
D3DDevice.SetRenderState D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA  	'Set The Destination Blending Method
D3DDevice.SetRenderState D3DRS_ALPHABLENDENABLE, True   		'Enable Alphablending
D3DDevice.SetRenderState D3DRS_POINTSPRITE_ENABLE, 1    		'For The Particle Engine
D3DDevice.SetRenderState D3DRS_POINTSCALE_ENABLE, 0     		'Also For The Particle Engine
D3DDevice.SetTextureStageState 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE   	'Allows ARGB To Work 

The details on that are not important, as long as you get all your "SetRenderState" and other such variables in there. Adding extra wont hurt, if you arn't sure if they are needed or not, just a like extra 2ms taken to restore the device. :D

Now for your rendering code. EVERY TIME before you start your rendering (D3DDevice.BeginScene), you want to add this:

'Check if we have the device
If D3DDevice.TestCooperativeLevel <> D3D_OK Then
    
    'Do a loop while device is lost
    Do While D3DDevice.TestCooperativeLevel = D3DERR_DEVICELOST
        
        'Let windows do it's stuff
        DoEvents
        
    Loop
    
    'Reset the device
    D3DDevice.Reset D3DParams
    
    'Reset the render states
    Engine_Init_D3DDevice
    
End If

As you recall, your D3DParams variable is in there to reset the device. Engine_Init_D3DDevice is the sub called to how you reset your RenderStates (Name of the sub is not important, just that in this case). That's it! :) But wait, DirectInput mouse in use? Keep reading, sucker!

Before you check your mouse device at all, such as using "DIMouse.GetDeviceData", you want to make sure you still have the advice. You can simply do this like so:

'Check if the device is obtained
If D3DDevice.TestCooperativeLevel <> D3D_OK Then Exit Sub

If you dont have the advice, no big, skip the mouse, they're overrated! It is pretty useless to add all the initialization code in here like when trying to render, so we just exit if it fails. Simple enough? Damn straight it is!

That's all there is needed for DirectX 8 device restoration! Now lets change the fact 99% of DirectX 8 programs crash when you alt+tab! :x

-Tutorial by Spodi, post by Sion since Spodi was confused :)