DeviceLostException

Started by
3 comments, last by bramsquad 17 years, 6 months ago
currently im writing this hobby game in C# using DX9 i have it working in full screen mode and all is well except for this one problem. I cant imagine this error happening often, but i dont really understand why it does.... if i click in any one of the corners, like (0,0), (0, 799), etc. i get an unhandled exception. DeviceLostException to be precise. the info on this says 'The device has been lost but cannot be reset at this time.' which says to me that even if i handle the exception, the program will have to terminate. is the only way to avoid this problem to programmatically make it so the user cannot move the mouse the these coordinates? here is my code... public static void Render() { DG_Device.Clear(ClearFlags.Target, System.Drawing.Color.Black, 1.0f, 0); DG_Device.BeginScene(); m_States[m_States.Count - 1](); DG_Device.EndScene(); DG_Device.Present(); } and the exception occurs on the line with 'DG_Device.Present();' btw, the code excecuted here 'm_States[m_States.Count - 1]();' just calls an update function (which will have a specific render function) to the state the game is at. (like titlescreen, save screen, etc.) thanks for you help, Josh
Advertisement
When you click on (0,0) or (0, 799), your application try’s to minimize. In directx when ever your render window needs to resize or something like that you need to reset all unmanaged resources.

You get device lost event. Right. In that event try to call .Dispose() method for any directx resources (textures, meshes, surfaces...) that were not created with Managed flag.

After that you will get device reset event.
In it you restore (reload) all those resources again.

Some MDX resources have .OnLostDevice() and .OnResetDevice() methods so it is enough to use them in those events. Not sure in which MDX version's.

This isn't perfect explanation but I think this is enough for beginners.
Hello,

In your code you can handle a DeviceLost exception by doing the following.
I always name my handle either Update() or ReloadResources() as in essence thats what is happening when you recover from a lost device.

But you should be able to setup an event to be fired like this:

this.graphicDevice.DeviceLost += new EventHandler(this.ReloadResources);


ReloadResources(Microsoft.DirectX.Direct3D.Device graphicDevice)
{
// Handle your device lost (reload your resources)
graphicDevice.Clear(etc..)

}

Another great thing to do while in the creation process is to run your application in windowed mode (becuase for me, its a pain going into full screen mode while im creating my application, that extra 2 seconds just bugs me for how many times I will run my app) and while in windowed mode you can setup a toggle for going to full screen (if you need to see the effect in full screen),
but if you do that you need to specify another event or the screen will be re-drawn incorrectly.

Here is the event:

this.graphicDevice.DeviceResizing += new System.ComponentModel.CancelEventHandler(this.graphicDevice_DeviceResizing);

void graphicDevice_DeviceResizing(object sender, System.ComponentModel.CancelEventArgs e)
{
e.Cancel = true;
}

Anyway if you need some more help just let me know:)
Thanks for the help...but I actually do need some more direction...i havent got it quite working but i think i understand it a lot better.

I think some of these ramblings maybe quite simplistic, but please bear with me, im fairly new to DX.

when i posted earlier code, i showed my state delagate system. my program works on delagates and each pointer points to its own respective update function. these functions more or less process mouse movement, key strokes, and eventually they render to the screen.

question being, is that all my textures, sprites, etc... are created in the constructor. so if i were to dispose of them would the device.Reset() call reinstantiate them, or would i have to create another instance of my class?

next about the toggling between full screen and windowed mode. here is some code i made (this is the part i think is a simple solution)

public static void ScreenFull()
{
presentParams.SwapEffect = SwapEffect.Discard;
presentParams.PresentationInterval = PresentInterval.One;

Format current = Microsoft.DirectX.Direct3D.Manager.Adapters[0].CurrentDisplayMode.Format;

if (Microsoft.DirectX.Direct3D.Manager.CheckDeviceType(0, Microsoft.DirectX.Direct3D.DeviceType.Hardware, current, current, false))
{
presentParams.Windowed = false;
presentParams.BackBufferFormat = current;
presentParams.BackBufferCount = 1;
presentParams.BackBufferWidth = ScreenWidth = 800;
presentParams.BackBufferHeight = ScreenHeight = 600;
}
else
{
//error handling (cant support full screen mode)
}

DG_Device.Dispose();
DG_Device = new DGDevice(0, Microsoft.DirectX.Direct3D.DeviceType.Hardware, m_GameWindow, CreateFlags.SoftwareVertexProcessing, presentParams);
DG_Device.RenderState.ReferenceAlpha = 0;
DG_Device.RenderState.AlphaFunction = Compare.NotEqual;
}

public static void ScreenWindowed()
{
presentParams.SwapEffect = SwapEffect.Discard;
presentParams.PresentationInterval = PresentInterval.One;
ScreenWidth = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width;
ScreenHeight = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height;
presentParams.Windowed = true;

DG_Device.Dispose();
DG_Device = new DGDevice(0, Microsoft.DirectX.Direct3D.DeviceType.Hardware, m_GameWindow, CreateFlags.SoftwareVertexProcessing, presentParams);
DG_Device.RenderState.ReferenceAlpha = 0;
DG_Device.RenderState.AlphaFunction = Compare.NotEqual;
}

now if i toggle it just locks up. i guess i dont quite know what else to do... i set different presentparams, dipose of the current graphic device, and create a new one...so what step am i missing?

thanks a lot for your help,

josh
oh, i forgot to say, i did incorperate your resizing event handler. so i dont think the problem with the toggle lies there.

This topic is closed to new replies.

Advertisement