CreateRenderTargetTexture causes problems to OnResize

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
thomascheah
Posts: 77
Joined: Sat Jul 08, 2006 5:55 am
Location: Cyberjaya, Malaysia

CreateRenderTargetTexture causes problems to OnResize

Post by thomascheah »

Hi,

Before I decided to post this to the bugs forum, let me double confirm this with some people around here. I had stripped down my code to the core of the problem to ease testing.

Explanations:

1. It seems that whenever a render target texture is created, not even start using it yet, followed by OnResize, the Direct3D device will gone crazy.

2. If you take the following code, and comment out the statement that contains createRenderTargetTexture or OnResize, things will be fine.

3. This problem occurs ONLY in Direct3D drivers. On Direct3D 9, you will see Resetting Device Failed (though no indication on Device Lost, thus no idea on the failure), on Direct3D 8, the program will crash.

4. I am running on Irrlicht 1.3.1


Why am I doing this?

Simple, my program runs in a windowed mode. And I call OnResize whenever the window is resized to make sure that the backbuffer is created with the new window size. Without calling OnResize, the output will be pixelated or blurry which is not desirable. And my program needs to use Render Target in certain functionalities as well. Thus, bumped into this problem. :(

Any help or workaround or source modifications will be appreciated.

Code: Select all

#include <irrlicht.h>
#include <iostream>

using namespace irr;
#pragma comment(lib, "Irrlicht.lib")

int main()
{
	video::E_DRIVER_TYPE driverType = video::EDT_DIRECT3D9;
	IrrlichtDevice *device =
		createDevice(driverType, core::dimension2d<s32>(640, 480),
		16, false, false);

	if (device == 0)
		return 1;

	video::IVideoDriver* driver = device->getVideoDriver();
	video::ITexture* rt = 0;
	
	// Comment one of the following 2 lines and things will be ok.
	rt = driver->createRenderTargetTexture(core::dimension2d<s32>(256,256));
	driver->OnResize(core::dimension2d<s32>(1000, 1000));

	while(device->run())
	if (device->isWindowActive())
	{
		driver->beginScene(true, true, 0);
		device->getSceneManager()->drawAll();                 
		driver->endScene();
	}

	if (rt)
	{
		rt->drop();
	}

	device->drop();
	return 0;
}
Objective World Pvt. Ltd.
"Turning Knowledge Into Wisdom."
http://www.objectiveworld.com
thomascheah
Posts: 77
Joined: Sat Jul 08, 2006 5:55 am
Location: Cyberjaya, Malaysia

Post by thomascheah »

Hmmm.... wonder if anybody had tried out the code above and verify the problem?
Objective World Pvt. Ltd.
"Turning Knowledge Into Wisdom."
http://www.objectiveworld.com
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

No, not yet, due to lack of win32 machines. But there will be a fix for arbitrary RTT sizes for Irrlicht 1.5 which should fix the problem with larger RTTs. But win32 device handling seems to require some care, too.
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

Yeah, this issue has come up before.

http://irrlicht.sourceforge.net/phpBB2/ ... hp?t=11213

The arbitrary rtt size support won't fix the problem. The rtt needs to be released and re-created. You should be able to check the return value of beginScene() and if that fails you will want to deallocate the render target. I think you may have to wait until after the next call to beginScene() to recreate the render target, but I can't remember.

Travis
thomascheah
Posts: 77
Joined: Sat Jul 08, 2006 5:55 am
Location: Cyberjaya, Malaysia

Post by thomascheah »

Vitek, that does not quite work. Whenever you have a lock/unlock statement on the RTT before dropping it, and later when OnResize is called, the beginScene will go mad again. :(

Without the lock/unlock then it works fine. Not sure what is causing this within the lock/unlock method. (FYI, I need to grab some pixels on the RTT to save it on a file.)

To illustrate this problem, try the follwing code revised from above

Code: Select all

#include <irrlicht.h>
#include <iostream>

using namespace irr;
#pragma comment(lib, "Irrlicht.lib")

int main()
{
	video::E_DRIVER_TYPE driverType = video::EDT_DIRECT3D9;
	IrrlichtDevice *device =
		createDevice(driverType, core::dimension2d<s32>(640, 480),
		16, false, false);

	if (device == 0)
		return 1;

	video::IVideoDriver* driver = device->getVideoDriver();
	video::ITexture* rt = 0;
	int count = 0;

	
	while(device->run())
	if (device->isWindowActive())
	{
		driver->beginScene(true, true, 0);
		device->getSceneManager()->drawAll();                 
		driver->endScene();

		// To simulate some event in the application.
		if (++count == 500)
		{
			rt = driver->createRenderTargetTexture(core::dimension2d<s32>(256,256));
			// Comment the following 2 lines and things will be ok. 
			rt->lock();
			rt->unlock();

			// Drop the RTT and call to OnResize to simulate the event when window is resizing.
			rt->drop();
			rt = 0;
			driver->OnResize(core::dimension2d<s32>(1000, 1000));
		}
	}

	if (rt)
	{
		rt->drop();
	}

	device->drop();
	return 0;
}
Objective World Pvt. Ltd.
"Turning Knowledge Into Wisdom."
http://www.objectiveworld.com
thomascheah
Posts: 77
Joined: Sat Jul 08, 2006 5:55 am
Location: Cyberjaya, Malaysia

Post by thomascheah »

Hmm... I wonder when this problem will be fixed? (Or will it ever be fixed.)
Objective World Pvt. Ltd.
"Turning Knowledge Into Wisdom."
http://www.objectiveworld.com
thomascheah
Posts: 77
Joined: Sat Jul 08, 2006 5:55 am
Location: Cyberjaya, Malaysia

Post by thomascheah »

No comments, anyone? Hmmm....
Objective World Pvt. Ltd.
"Turning Knowledge Into Wisdom."
http://www.objectiveworld.com
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Try to remove it from the texture cache also, otherwise the texture is not really deleted.
thomascheah
Posts: 77
Joined: Sat Jul 08, 2006 5:55 am
Location: Cyberjaya, Malaysia

Post by thomascheah »

Thanks Hybrid, but no luck either. I tried to call remove texture before dropping it, like the followings

Code: Select all

if (++count == 500) 
{ 
 rt = driver->createRenderTargetTexture(core::dimension2d<s32>(256,256)); 

 // Comment the following 2 lines and things will be ok. 
 rt->lock(); 
 rt->unlock(); 

 // Drop the RTT and call to OnResize to simulate the event when window is resizing. 
 driver->removeTexture(rt);
 rt->drop(); 		 
 rt = 0; 
 driver->OnResize(core::dimension2d<s32>(1000, 1000)); 
} 
I still get these during BeginScene and EndScene after OnResize,

DIRECT3D9 clear failed.
DIRECT3D9 begin scene failed.
DIRECT3D9 end scene failed.
Objective World Pvt. Ltd.
"Turning Knowledge Into Wisdom."
http://www.objectiveworld.com
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Hmm, this sounds more like a bug in the lock or unlock method. I guess we should check the proper release of all surfaces in those methods.
thomascheah
Posts: 77
Joined: Sat Jul 08, 2006 5:55 am
Location: Cyberjaya, Malaysia

Post by thomascheah »

Any quick patch to this? 8)
Objective World Pvt. Ltd.
"Turning Knowledge Into Wisdom."
http://www.objectiveworld.com
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

I couldn't find any left-in thing at a first glance, but who knows what d3d requires the user to do after each step?
Yoran
Site Admin
Posts: 96
Joined: Fri Oct 07, 2005 8:55 am
Location: The Netherlands
Contact:

Post by Yoran »

For everyone still using nadro's large rtt patch:
i found a small bug, with large consequences.
void CD3D9Texture::updateDepthBuffer( )

Code: Select all

// replace old ZBuffer
       if( newZBuf )
            {
                Driver->setDepthBuffer( newZBuf );
                newZBuf->Release();
                //db->Release(); FIX by Yoran, texture->drop() fails if db is released twice! therefore resetting d3d9 device fails
            }
This causes onresize to fail
Post Reply