Page 1 of 1

[BUG] CreateRenderWindow with DirectX RenderSystem.

Posted: Wed Jun 27, 2012 4:44 pm
by jycorbel
Hello,

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);
	}
But I would propose to do this fix in Ogre file OgreD3D9Texture.cpp :

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.

Re: [BUG] CreateRenderWindow with DirectX RenderSystem.

Posted: Wed Jun 27, 2012 6:56 pm
by CABAListic
Generally it is recommended to create the primary render window early on, before doing anything with resources. If you don't want to show a windows immediately, create it with the hidden flag.

Still, you are right that this particular exception should not be thrown by createRenderWindow, so it should be caught and handled inside the call.

Re: [BUG] CreateRenderWindow with DirectX RenderSystem.

Posted: Tue Jul 03, 2012 4:21 pm
by jycorbel
Actually, we create an hidden windows when our application starts.

I even not be able to really understand why this texture are created in the first place. But we do create the scene before the render windows.
I hope this will soon be fixed by ogre team to remove my ugly hack. But in a mean time it's not an issue for us anymore.

Regards,
Jean-Yves CORBEL
Developper at Ice-Dev.

Re: [BUG] CreateRenderWindow with DirectX RenderSystem.

Posted: Tue Jul 03, 2012 4:55 pm
by al2950
I believe this is related to a very similar bug which is in mantis (http://www.ogre3d.org/mantis/view.php?id=529), but I think its priority should be changed as its causes a crash, I looked at fixing it but was not sure the best place to catch the exception, also not sure if it happens in other render systems (ie openGL)

Re: [BUG] CreateRenderWindow with DirectX RenderSystem.

Posted: Thu Jul 05, 2012 9:11 am
by jycorbel
We do not have the issue using OpenGL.

In this case the resource can't be prepare and we'll get a yellow/black texture (see picture). It's obvious resource is missing but it won't crash Ogre. Consequently Direct3D9 and OpelGL Render System have different behaviour that should be normalised. According to me, Ogre shouldn't crash.
In OpenGL, a missing resource makes a black and yellow stripped texture.
In OpenGL, a missing resource makes a black and yellow stripped texture.
OpenGLMissingResource.png (39.2 KiB) Viewed 3538 times
The crash in Direct3D9 is due to the attempt to create the Direct3DTexture, it's very API specific. My fix proposition do not use exception catching as it verify Ogre Resource BEFORE getting into trouble.
=> This can be criticised as we research twice the resource ( resourceExists + openResource ), but I think it's cleaner, isn't it ?