When you create a resource that is not managed by the device, it must be destroyed and recreated when the D3D device is lost. Irrlicht provides no real notification that the device is lost. Irrlicht does return false from
beginScene() when something is wrong, but there is no way to tell what the problem was without writing D3D specific code.
What is needed is some sort of way to tell that the device reset is about to happen and when it is over. When this the pre-reset happens some resources would need to be released. After the reset has completed, the resources would need to be reallocated.
Unfortunately this is specific to D3D. There is no problem if the window size is fixed and not full screen. Obviously this is a way to work around the issue, but it is not a great solution.
The below test case will cause problems on a windows machine when you alt-tab out of the application.
Code: Select all
#include <irrlicht.h>
#pragma comment(lib, "Irrlicht.lib")
using namespace irr;
int main()
{
// problem occurs when using a resource that is not managed by the device
// and the resource is not released when the device is lost or reset. the
// device is reset when you alt-tab out of full screen mode or when the
// window is resized.
IrrlichtDevice *device = createDevice(video::EDT_DIRECT3D8, core::dimension2d<s32>(1024, 768), 16, true, false, false);
if (device == 0)
return 1;
// this is for the second issue mentioned below. change the createDevice
// call above so that the window is not fullscreen and comment this in...
//device->setResizeAble(true);
video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
driver->setAmbientLight(video::SColorf(.5f, .5f, .5f, 1.f));
smgr->loadScene("../../media/example.irr");
smgr->addCameraSceneNodeMaya();
video::ITexture* rtt = 0;
if (driver->queryFeature(video::EVDF_RENDER_TO_TARGET))
rtt = driver->createRenderTargetTexture( core::dimension2d<s32>(256, 256) );
while(device->run())
{
if (device->isWindowActive())
{
if (driver->beginScene(true, true, video::SColor(255, 32, 32, 32)))
{
smgr->drawAll();
driver->endScene();
}
}
}
if (rtt)
rtt->drop();
device->drop();
return 0;
}
There is another small, but related bug in here. In
CD3D?Driver::reset(), the
DeviceLost flag should get set when the
pID3DDevice->Reset() call fails with D3DERR_DEVICELOST. If this is not set, I get a crash after resizing the Irrlicht window with the above test case.