1.6.2 - Notify when D3D device lost/restored [SOLVED]

galaktor

10-11-2009 18:28:35

Hi

I'm having the "classical" problems of getting exceptions whenever the form containing ogre loses focus or something else gains full control over the render device. I read in many parts of the forum that there is a way to have a listener get called when device is lost or restored.

How can I do this? I could not find anyhting on RenderSystem or RenderWindow. I am using the 1.6.2 version from this forums.

Thank you

smiley80

10-11-2009 18:57:39

Subscribe to the EventOccurred event of RenderSystem:
myRenderSystem.EventOccurred += RenderSystem_EventOccurred;

And take care of lost/restored devices in the event handler:

void RenderSystem_EventOccurred(string eventName, Const_NameValuePairList parameters)
{
if (eventName == "DeviceLost")
{
}
else if (eventName == "DeviceRestored")
{
}
}

galaktor

11-11-2009 09:33:07

Cool, thanks. I already had that event registerred, but I did not know what string keys to use to check for the right event. Is there a list somewhere?

Anyway, cool. ;)

galaktor

11-11-2009 10:25:07

Is there any standard way to handle the following chicken-egg-problem?

When the device is lost, I don't call RenderOneFrame(). But if I don't call it, I won't get a "DeviceRestored" event.

Is there any way to poll the RenderSystem directly if the device has been restored, like a boolean property?

EDIT:
I read somewhere that prompting the user with a message box (and having the user click it) will automatically restore focus to the form and then the device will be restored. That is not working for me - how should I restore it in a correct manner?

smiley80

11-11-2009 11:09:02

Is there a list somewhere?
There are only those two.

When the device is lost, I don't call RenderOneFrame(). But if I don't call it, I won't get a "DeviceRestored" event.
RenderWindow.Update also tries to restore the device.

Is there any way to poll the RenderSystem directly if the device has been restored, like a boolean property?
D3D9RenderSystem (not wrapped) has a bool called 'isDeviceLost', but that is set to false just before the event is raised.

You can use the Activated event of the form to get noticed when it has the focus again.

galaktor

11-11-2009 17:41:05

Ok, so now I've got a flag "IsDeviceLost" that is set to "true" whenever I get that event from the RenderSystem. I only call RenderOneFrame() when "IsDeviceLost == false". When that happens (e.g. when I lock windows) the flag is set appropriately and everything looks good.

As soon as I return from the lock screen, I get the form's "Activate" event, where I call RenderWindow.Update() and set "IsDeviceLost = false"...resulting in the same evil D3D exceptions because the device was not reset.

Maybe the problem is, that I am not using the whole form as a render target, but just a panel within it?

smiley80

11-11-2009 19:46:30


As soon as I return from the lock screen, I get the form's "Activate" event, where I call RenderWindow.Update() and set "IsDeviceLost = false"...resulting in the same evil D3D exceptions because the device was not reset.

Only set 'IsDeviceLost' to false in the 'EventOccurred' handler when the 'DeviceRestored' event is fired.
And call RenderWindow.Update periodically while the device is not restored.


...or use OpenGL.

galaktor

12-11-2009 07:52:31

OpenGL is not an option right now since I am using Ogre in a cross-threaded environment - OpenGL only crashes then.

Thanks for the tip, I'll check it out later today.

PS
Thank you, smiley80 for being a very supportive Mogre board member!

galaktor

12-11-2009 08:25:26

I am still getting the invalid call excpetion from Ogre as soon as I call RenderWindow.Update() after the device is lost:

09:31:06: !!! Direct3D Device Lost!
09:31:21: Releasing D3D9 default pool texture: Ogre/ShadowTexture0
09:31:21: Released D3D9 default pool texture: Ogre/ShadowTexture0
09:31:21: Releasing D3D9 default pool texture: Ogre/ShadowTexture1
09:31:22: Released D3D9 default pool texture: Ogre/ShadowTexture1
09:31:22: D3D9TextureManager released:
09:31:22: 2 unmanaged textures
09:31:22: D3D9HardwareBufferManager released:
09:31:22: 14 unmanaged vertex buffers
09:31:22: 0 unmanaged index buffers
09:31:22: OGRE EXCEPTION(3:RenderingAPIException): Cannot reset device! Invalid call in D3D9RenderWindow::restoreLostDevice at ..\src\OgreD3D9RenderSystem.cpp (line 3447)


Any ideas?

smiley80

12-11-2009 10:15:58


09:31:22: D3D9TextureManager released:
09:31:22: 2 unmanaged textures
09:31:22: D3D9HardwareBufferManager released:
09:31:22: 14 unmanaged vertex buffers
09:31:22: 0 unmanaged index buffers

If you've created those, you have to recreate them.