I noticed a very bad behaviour in Ogre using the Direct3D9 Render System.
Indeed, when I try to create my first RenderWindows, implementation will create the direct 3D device.
The issue happens if we have a material using a missing texture.
In OgreResource, a missing file will result in an unloaded resource. (see Resource::load())
In D3D9Device::createD3D9Device() the line 742, will try to create all TextureResouces.
See : D3D9Texture::createTextureResources(IDirect3DDevice9* d3d9Device)
For non-manual texture, the function prepareImpl() may raise an exception FileNotFoundException, that is not caught by the function. This result in CreateRenderWindow failing and raising a FileNotFoundException for the missing texture file.
I don't think this should happen. It doesn't with the OpenGL render system.
Shouldn't Ogre manage this uncaught exception the same way OgreResource does ?
I mean that if prepareImpl() raises this exception, the texture should remain unloaded until
we add the missing file to the resource location and load the resource later.
Right now as I can't modify Ogre source in my project, I resolved this issue in this very ugly way :
Code: Select all
try
{ // @HACK JYC 06/27/2012 -- void D3D9Texture::createTextureResources(IDirect3DDevice9* d3d9Device)
// In DirectX RenderSystem case, the creation of the D3D9Device will try
// to create Direct3DTextexture that raise an exception when file is
// missing, until ogre manage this issues, Just recreate the render windows :
// The device is now created, texture will not be created again (we won't
// raise this exception twice)
m_pRenderTarget = Ogre::Root::getSingletonPtr()->createRenderWindow(TmpStr , WndRect.Width(), WndRect.Height(), false, &Params);
}
catch ( Ogre::FileNotFoundException OgreFileNotFountException )
{
// Recreate the RenderWindows ( the exception is not raised twice )
m_pRenderTarget = Ogre::Root::getSingletonPtr()->createRenderWindow(TmpStr , WndRect.Width(), WndRect.Height(), false, &Params);
}Code: Select all
void D3D9Texture::createTextureResources(IDirect3DDevice9* d3d9Device)
{
D3D9_DEVICE_ACCESS_CRITICAL_SECTION
if (mIsManual)
{
preLoadImpl();
// create the internal resources.
createInternalResourcesImpl(d3d9Device);
// Load from manual loader
if (mLoader != NULL)
{
mLoader->loadResource(this);
}
postLoadImpl();
}
else if ( ResourceGroupManager::getSingleton().resourceExists( mGroup, mName ) )
{
prepareImpl();
preLoadImpl();
loadImpl(d3d9Device);
postLoadImpl();
}
// else Do not create the resource has the file is missing (it can only fail) !
}Let me know what do you think of this behaviour.
