Floating Point Render Target Texture Support [DX9]

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Post Reply
Nadro
Posts: 1648
Joined: Sun Feb 19, 2006 9:08 am
Location: Warsaw, Poland

Floating Point Render Target Texture Support [DX9]

Post by Nadro »

Hi. I done floating point render target support for Irrlicht [Now for DirectX9 only, but I'm working on it for OpenGL]

I add 6 new color format:

Code: Select all

ECF_R16F
ECF_G16R16F
ECF_A16B16G16R16F
ECF_R32F
ECF_G32R32F
ECF_A32B32G32R32F
You have to update this Irrlicht parts for usage fp textures:

Code: Select all

		             *** Irrlicht Include ***

---------------------------------------- IImage.h ----------------------------------------
enum ECOLOR_FORMAT
{
	//! 16 bit color format used by the software driver, and thus preferred
	//! by all other irrlicht engine video drivers. There are 5 bits for every
	//! color component, and a single bit is left for alpha information.
	ECF_A1R5G5B5 = 0,

	//! Standard 16 bit color format.
	ECF_R5G6B5,

	//! 24 bit color, no alpha channel, but 8 bit for red, green and blue.
	ECF_R8G8B8,

	//! Default 32 bit color format. 8 bits are used for every component:
	//! red, green, blue and alpha.
	ECF_A8R8G8B8,

	// ** Floating Point ***

	//! 16 bit float format using. 16 bits for red:
	ECF_R16F,

	//! 32 bit float format using. 16 bits for red and 16 bits for green:
	ECF_G16R16F,

	//! 64 bit float format. 16 bits are used for every component:
	//! red, green, blue and alpha.
	ECF_A16B16G16R16F,

	//! 32 bit float format using. 32 bits for red:
	ECF_R32F,

	//! 64 bit float format using. 32 bits for red and 32 bits for green:
	ECF_G32R32F,

	//! 128 bit float format. 32 bits are used for every component:
	//! red, green, blue and alpha.
	ECF_A32B32G32R32F,

	//! Unknown color format:
	ECF_UNKNOWN,
};
------------------------------------------------------------------------------------------
********************************************************************

------------------------------------- IVideoDriver.h -------------------------------------
virtual ITexture* createRenderTargetTexture(const core::dimension2d<s32>& size, const c8* name = 0, ECOLOR_FORMAT format = ECF_UNKNOWN) = 0;
------------------------------------------------------------------------------------------
********************************************************************

		             *** Irrlicht Source ***

------------------------------------- CNullDriver.h -------------------------------------
virtual ITexture* createRenderTargetTexture(const core::dimension2d<s32>& size, const c8* name = 0, ECOLOR_FORMAT format = ECF_UNKNOWN);
------------------------------------------------------------------------------------------
********************************************************************

------------------------------------ CNullDriver.cpp ------------------------------------
ITexture* CNullDriver::createRenderTargetTexture(const core::dimension2d<s32>& size, const c8* name, ECOLOR_FORMAT format)
{
	return 0;
}
------------------------------------------------------------------------------------------
********************************************************************

------------------------------------ CD3D9Driver.h ------------------------------------
virtual ITexture* createRenderTargetTexture(const core::dimension2d<s32>& size, const c8* name = 0, ECOLOR_FORMAT format = ECF_UNKNOWN);
------------------------------------------------------------------------------------------
********************************************************************

----------------------------------- CD3D9Driver.cpp -----------------------------------
ITexture* CD3D9Driver::createRenderTargetTexture(const core::dimension2d<s32>& size, const c8* name, ECOLOR_FORMAT format)
{
	return new CD3D9Texture(this, size, name, format);
}
------------------------------------------------------------------------------------------
********************************************************************

------------------------------------ CD3D9Texture.h -----------------------------------
//! rendertarget constructor
CD3D9Texture(CD3D9Driver* driver, core::dimension2d<s32> size, const char* name, ECOLOR_FORMAT format = ECF_UNKNOWN);
------------------------------------------------------------------------------------------
void createRenderTarget(ECOLOR_FORMAT format);
------------------------------------------------------------------------------------------
********************************************************************

----------------------------------- CD3D9Texture.cpp ----------------------------------
//! rendertarget constructor
CD3D9Texture::CD3D9Texture(CD3D9Driver* driver, core::dimension2d<s32> size, const char* name, ECOLOR_FORMAT format)
: ITexture(name), Texture(0), RTTSurface(0), Driver(driver),
	TextureSize(size), ImageSize(size), Pitch(0),
	HasMipMaps(false), HardwareMipMaps(false), IsRenderTarget(true)
{
	#ifdef _DEBUG
	setDebugName("CD3D9Texture");
	#endif

	Device=driver->getExposedVideoData().D3D9.D3DDev9;
	if (Device)
		Device->AddRef();

	createRenderTarget( format );
}
------------------------------------------------------------------------------------------
void CD3D9Texture::createRenderTarget(video::ECOLOR_FORMAT format)
{
	TextureSize.Width = getTextureSizeFromImageSize(TextureSize.Width);
	TextureSize.Height = getTextureSizeFromImageSize(TextureSize.Height);

	D3DFORMAT d3DFormat = D3DFMT_A8R8G8B8;

	if( format == ECF_UNKNOWN )
	{
		// get backbuffer format to create the render target in the
		// same format
		IDirect3DSurface9* bb;	

		if (!FAILED(Device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &bb)))
		{
			D3DSURFACE_DESC desc;
			bb->GetDesc(&desc);
			d3DFormat = desc.Format;

			if (d3DFormat == D3DFMT_X8R8G8B8)
				d3DFormat = D3DFMT_A8R8G8B8;

			bb->Release();
		}
		else
		{
			os::Printer::log("Could not create RenderTarget texture: could not get BackBuffer.",
				ELL_WARNING);
			return;
		}
	}
	else
	{
		d3DFormat = getD3DFormatFromColorFormat( format );
	}

	if( d3DFormat != D3DFMT_UNKNOWN )
	{
		// create texture
		HRESULT hr;

		hr = Device->CreateTexture(
			TextureSize.Width,
			TextureSize.Height,
			1, // mip map level count, we don't want mipmaps here
			D3DUSAGE_RENDERTARGET,
			d3DFormat,
			D3DPOOL_DEFAULT,
			&Texture,
			NULL);

		// get irrlicht format from D3D format
		ColorFormat = getColorFormatFromD3DFormat(d3DFormat);

		if (FAILED(hr))
		os::Printer::log("Could not create render target texture");
	}
	else
	{
		os::Printer::log( "Can not create render target of format D3DFMT_UNKNOWN" );
	}
}
------------------------------------------------------------------------------------------
D3DFORMAT CD3D9Texture::getD3DFormatFromColorFormat(ECOLOR_FORMAT format) const
{
	switch(format)
	{
		case ECF_A1R5G5B5:
			return D3DFMT_A1R5G5B5;
		case ECF_R5G6B5:
			return D3DFMT_R5G6B5;
		case ECF_R8G8B8:
			return D3DFMT_R8G8B8;
		case ECF_A8R8G8B8:
			return D3DFMT_A8R8G8B8;

		// ** Floating Point ***

		case ECF_R16F:
			return D3DFMT_R16F;
		case ECF_G16R16F:
			return D3DFMT_G16R16F;
		case ECF_A16B16G16R16F:
			return D3DFMT_A16B16G16R16F;
		case ECF_R32F:
			return D3DFMT_R32F;
		case ECF_G32R32F:
			return D3DFMT_G32R32F;
		case ECF_A32B32G32R32F:
			return D3DFMT_A32B32G32R32F;
	}
	return D3DFMT_UNKNOWN;
}
------------------------------------------------------------------------------------------
********************************************************************
You have to update createRenderTargetTexture function for all Your driver eg. Software Driver, OpenGL.

Simple usage:

Code: Select all

ITexture* rt = driver->createRenderTargetTexture(core::dimension2d<s32>(256,256),0,video::ECF_A16B16G16R16F);
I tested it on shadow mapping example and works fine:) This is code for Irrlicht 1.4 but it's easy to implementation for SVN revision. Maybe Irrlicht Team can merge it with Irrlicht core on SVN, when I add OpenGL support? Floating point is very useful for creating shaders eg. HDR, Shadow Mapping etc.
Library helping with network requests, tasks management, logger etc in desktop and mobile apps: https://github.com/GrupaPracuj/hermes
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

Cool :D

Before I was using this snippet to store 32bit floating point info in a texture:

Code: Select all

/// Packing a [0-1] float value into a 4D vector where each component will be a 8-bits integer
vec4 packFloatToVec4i(const float value)
{
	const vec4 bitSh = vec4(256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0);
	const vec4 bitMsk = vec4(0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0);
	vec4 res = fract(value * bitSh);
	res -= res.xxyz * bitMsk;
	return res;
}

float unpackFloatFromVec4i(const vec4 value)
{
	const vec4 bitSh = vec4(1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0, 1.0);
	return(dot(value, bitSh));
}
Anyway, thanks :D
ShadowMapping for Irrlicht!: Get it here
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

The problem (and why it was not yet integrated into Irrlicht) is that no one will stop you from creating IImages with these values. But no method in Irrlicht will cope with it. Moreover, you cannot lock textures of this format for access (at most downsampled versions might be available). Due to the current way SColor, IImage, and ITexture are implemented, there is no easy way to overcome this limitation.
Nadro
Posts: 1648
Joined: Sun Feb 19, 2006 9:08 am
Location: Warsaw, Poland

Post by Nadro »

Floating point textures is usage for Shaders [HDR, Deferred Shading, Shadow Mapping etc...], so You don't need use lock texture, convert it to another etc. Users need standard floating point operation - write Render to Height Precision Texture, so this tip solved this problem in 100% In future We can odd full support operations on FP Texture Format eg. lock but now We need add simple support for this texture in Irrlicht :)
Library helping with network requests, tasks management, logger etc in desktop and mobile apps: https://github.com/GrupaPracuj/hermes
Nadro
Posts: 1648
Joined: Sun Feb 19, 2006 9:08 am
Location: Warsaw, Poland

Post by Nadro »

If You need integrated MRTs with Floating Point Textures and support this in OpenGL and DirectX9 You should go to this topic:
http://irrlicht.sourceforge.net/phpBB2/ ... hp?t=25496
Library helping with network requests, tasks management, logger etc in desktop and mobile apps: https://github.com/GrupaPracuj/hermes
Post Reply