[DirectX9] Working 3D textures / Cube Maps

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
MasterD
Posts: 153
Joined: Sun Feb 15, 2004 4:17 pm
Location: Lübeck, Germany
Contact:

[DirectX9] Working 3D textures / Cube Maps

Post by MasterD »

Heres a little snippet for some 3D texture support.

Also it does not fit into the concept of irrlicht 2D-images / textures, it works with (pixel-)shaders. This modification is not intended to have modify able 3D textures! (ITexture::lock() returns 0)

It is not implemented with Dx8, and irrlicht is not even compiled with Dx8 support, because of compile errors when compiling both (see C3DTexture.h modification info).

The procedure is not like for the other textures, where first an IImage is generated. It bypasses some steps and directly loads the file using a D3DX call.

Changed files:
CNullDriver.h /.cpp
CD3D9Driver.h /.cpp
CD3D9Texture.h / .cpp
IrrCompileConfig.h // to disable Dx8 support

I know, this is no clean code, but its working code, which works for me so far, since I desperatly need 3D textures :)

EDIT: For usage: just call Drv->getTexture("MyVolumeTexture.dds"), add it to a SMaterial and within the pixelshader use sampler3D tex0 (1,2,3) and a lookup with col = tex3D(tex0, texCoord)

EDIT2: This modification is based on Irrlicht 1.4.

Changes to CNullDriver.h:

Code: Select all

/**** BELOW createDeviceDependentTexture(..) */
//! returns a device dependent texture from a file
//! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES
virtual video::ITexture* createDeviceDependentTextureFromFile(const char* filename);
Changes to CNullDriver.cpp:

Code: Select all

/**** WITHIN CNullDriver::loadTextureFromFile */
// After if(image){...}
    else
	{
		if(!hashName)
			os::Printer::log("Loading texture from filename failed: NULL");
		else
		{
			// hashName == filename
			texture = createDeviceDependentTextureFromFile(hashName);
		}
	}

/**** NEW (e.g. at end of file [WITHIN namespace's] */
//! returns a device dependent texture from a loaded file
//! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES
video::ITexture* CNullDriver::createDeviceDependentTextureFromFile(const char* fileName)
{
    return 0;
}
Changes to CD3D9Driver.h:

Code: Select all

/**** AFTER createDeviceDependentTexture(..) */
		//! returns a device dependent texture from a file
		//! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES
		virtual video::ITexture* createDeviceDependentTextureFromFile(const char* filename);
Changes to CD3D9Driver.cpp:

Code: Select all

/**** AFTER createDeviceDependentTexture(..) */
video::ITexture* CD3D9Driver::createDeviceDependentTextureFromFile(const char* filename)
{
	return new CD3D9Texture(filename, this, TextureCreationFlags, filename);
}
Changes to CD3DTexture.h:

Code: Select all

/**** ADD NEW CONSTRUCTOR */
//! constructor for volumetric textures
	CD3D9Texture(const char* filename, CD3D9Driver* driver,
		u32 flags, const char* name);

/**** CHANGE FROM */
	IDirect3DTexture9* getDX9Texture() const;
/**** CHANGE TO  (IDirect3DBaseTexture9 is the base for both 2D and 3D textures) */
	IDirect3DBaseTexture9* getDX9Texture() const;

/**** ADD private MEMBER */
	IDirect3DVolumeTexture9* VolumeTexture;
Changes to CD3DTexture.cpp:
As a code comment within this file says, there are errrors when using D3DX functions + Dx9 + Dx8, therefore Dx8 support is disabled within IrrCompileConfig.h.
Since Dx8 support is disabled, we can use D3DX mipmap creation features and the D3DX lib gets linked through the first change.

Code: Select all

/**** UNCOMMENT */
#define _IRR_USE_D3DXFilterTexture_

/**** MODIFY both existent constructors, so that new member gets initialized proper, e.g. add to initialization list:
VolumeTexture(0)

/**** ADD new constructor
//! constructor for volumetric textures
CD3D9Texture::CD3D9Texture(const char * fileName, CD3D9Driver* driver,
						   u32 flags, const char* name) : 
		ITexture(name), Image(0), Texture(0), RTTSurface(0), Driver(driver),
		TextureSize(0,0), ImageSize(0,0), Pitch(0),
		HasMipMaps(false), HardwareMipMaps(false), IsRenderTarget(false), VolumeTexture(0)
{
	#ifdef _DEBUG
	setDebugName("CD3D9Texture");
	#endif

	const bool generateMipLevels = Driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS);

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

	HRESULT hr = D3DXCreateVolumeTextureFromFile(
		Device,
		fileName,
		&VolumeTexture);
	
	if(FAILED(hr))
	{
		os::Printer::log("D3D9Texture: Failed to load volume texture from file", fileName, ELL_ERROR);
	}
}

/**** MODIFY destructor, add */
	if (VolumeTexture)
		VolumeTexture->Release();

/**** CHANGE from */
IDirect3DTexture9* CD3D9Texture::getDX9Texture() const
{
	return Texture;
}

/**** CHANGE to */
IDirect3DBaseTexture9* CD3D9Texture::getDX9Texture() const
{
	if(!Texture && VolumeTexture)
	{
		return VolumeTexture;
	}
	else
		return Texture;
}

Change IrrCompileConfig.h:

Code: Select all

/**** COMMENT / DELETE */
#define _IRR_COMPILE_WITH_DIRECT3D_8_
Last edited by MasterD on Thu Oct 23, 2008 1:32 pm, edited 3 times in total.
YASS - Yet another Space Shooter
under Devolpment, see http://yass-engine.de
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

Hey this is pretty wicked, I didn't know D3D9 had built in support for reading textures directly from files. I imagine adding wouldn't require much extra work on this (Or we can just use 6-layer volume textures as "cube maps").

So what kinda volume texture effects do you have planned for YASS? :wink:
ShadowMapping for Irrlicht!: Get it here
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
MasterD
Posts: 153
Joined: Sun Feb 15, 2004 4:17 pm
Location: Lübeck, Germany
Contact:

Post by MasterD »

Well, me neither, but thats propably due to the case, that I have no idea of D3D programming ;)

And for YASS, make a guess! ;)
this or maybe that

But I didn't get, what you wanted to say with:
I imagine adding wouldn't require much extra work on this (Or we can just use 6-layer volume textures as "cube maps").
YASS - Yet another Space Shooter
under Devolpment, see http://yass-engine.de
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

LOL, posting before bed is not always a good idea. :P

I was talking about cubemaps.
ShadowMapping for Irrlicht!: Get it here
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
MasterD
Posts: 153
Joined: Sun Feb 15, 2004 4:17 pm
Location: Lübeck, Germany
Contact:

Post by MasterD »

Now I see :)

Cubemaps as 6-layered volume texture could work, but I don't know if there might be issues regarding mipmap generation.
YASS - Yet another Space Shooter
under Devolpment, see http://yass-engine.de
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

Yes, IIRC volume textures get their mipmaps generated in all three dimensions (So 6x512x512 can go down to 3x256x256), so the cube will be missing some faces. Offcourse in most cases I can imagine cubmaps being used I would probably disable mipmap generation anyway (Stuff like shadowmaps, skycube dynamic reflections, etc).

Oh wait that brings me to another point, how hard would it be to add render to volume texture support? (If thats even possible, it might be a fairly new thing)
ShadowMapping for Irrlicht!: Get it here
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
MasterD
Posts: 153
Joined: Sun Feb 15, 2004 4:17 pm
Location: Lübeck, Germany
Contact:

Post by MasterD »

I just wanted to remark, that with nearly the same solution as above, cube maps are also possible.

I'm currently don't using volume textures anymore, since the scattering effect using volume textures was not doable by me (to dump :x ). So I'm just using O'Neil's GPU Gems 2 shader implementation, which rocks :)

For Cube Maps you just have to replace the variable type
IDirect3DVolumeTexture9 by IDirect3DCubeTexture9

and the appropriate call to create

HRESULT hr = D3DXCreateCubeTextureFromFile(
Device,
fileName,
&CubeTexture);

But as the Irrlicht texture concept is 2D, I don't know how to enable render-to-texture on the cube maps being built this way. This would propably require some ICubeTexture thingy, so a more in-depth change of the architecture maybe.

And with the render-to-volume support: not a single idea :wink:
YASS - Yet another Space Shooter
under Devolpment, see http://yass-engine.de
MasterD
Posts: 153
Joined: Sun Feb 15, 2004 4:17 pm
Location: Lübeck, Germany
Contact:

Current SVN Version

Post by MasterD »

With the current SVN version (starting from Rev. 1623) this solution isn't working directly, CD3D9Driver must be fixed:

in CD3D9Driver::reset()

use IDirect3DBaseTexture9 instead of IDirect3DTexture9
YASS - Yet another Space Shooter
under Devolpment, see http://yass-engine.de
dlangdev
Posts: 1324
Joined: Tue Aug 07, 2007 7:28 pm
Location: Beaverton OR
Contact:

Post by dlangdev »

Nice work there.

For cubemaps, I think the humus project can help....

http://www.humus.name/index.php?page=3D

I'll take a stab at HDR and Cubemaps using the humus framework3 codebase, see if they can ported over.
Image
MasterD
Posts: 153
Joined: Sun Feb 15, 2004 4:17 pm
Location: Lübeck, Germany
Contact:

Post by MasterD »

Whoa, that humus stuff is pretty advanced :), but I'm sorry, what do you want to implement/port? Is it HDR? Then there is at least 16Bit Floating point textures needed (+RTT support for these), imho, but I hadn't looked at that stuff in depth. However, keep me updated, if you pursue this plan.
YASS - Yet another Space Shooter
under Devolpment, see http://yass-engine.de
dlangdev
Posts: 1324
Joined: Tue Aug 07, 2007 7:28 pm
Location: Beaverton OR
Contact:

Post by dlangdev »

Hey, I just patched the 1.4.2 code. Looks good so far.

Can you tell what's the bug in there?

You know, this could be start of where the port will be heading.

Anyway, I'm going to write a test program later.

Thanks for the patch.
Image
dlangdev
Posts: 1324
Joined: Tue Aug 07, 2007 7:28 pm
Location: Beaverton OR
Contact:

Post by dlangdev »

Here it is, the colormap of the wall came from a DDS file.

Code: Select all

video::ITexture* colorMap = driver->getTexture("../../media/Mars.dds");
Nice.

Image

That means I can now play with cubemaps.

Yay!

Thanks, bro. That's an awesome code you posted.
Image
dlangdev
Posts: 1324
Joined: Tue Aug 07, 2007 7:28 pm
Location: Beaverton OR
Contact:

Post by dlangdev »

Modded files are here. Extract and drop them in the correct directory.

https://sourceforge.net/project/showfil ... _id=637342

Note:

1) You must be using version 1.4.2
2) You know where these files are located.
3) Don't even download this package if you don't have experience.
4) Download it knowing there is no user support for this modded code.
Image
dlangdev
Posts: 1324
Joined: Tue Aug 07, 2007 7:28 pm
Location: Beaverton OR
Contact:

Post by dlangdev »

Here's another screenshot using the DDS texture file taken from Humus project.

Image
Image
dlangdev
Posts: 1324
Joined: Tue Aug 07, 2007 7:28 pm
Location: Beaverton OR
Contact:

Post by dlangdev »

Good news, I got to test an HDR file loading to a buffer which was then copied (memset) over to a texture.

I thought doing that would make the skybox show-up in HDR, but it turns out I need to write a an effect for moving the vertices and pixels the HDR way.

Anyway, it's not done yet, still coding the HDR renderer at the moment.

I took a snapshot of the directory, zipped it and posted it here for reference.

https://sourceforge.net/project/showfil ... _id=297414
Image
Post Reply