Skip to main content
GameDev.net gamedev.net
🔒 Locked

TGAs and transparency

Started by Endar Feb 14, 2007 at 1:47 AM 15 replies 2.8k views
Original Post
Endar
Endar
I've been trying for some amount of time to get transparency working with D3D textures. I've tried several different ways and I am now down to a single question: Do tga files support transparency? Because I suppose I just naturally assumed that they did because you can save them as 32-bit. But, why would you allow to save as 32-bit if the maximum the format supported was RGB? What would be the point? I suppose there's the data alignment argument, but why not just do what the bitmap format does and align the whole row to a 4 byte boundary?
[size="2"][size=2]Mort, Duke of Sto Helit: NON TIMETIS MESSOR -- Don't Fear The Reaper
cobru
cobru
according to this link and a fast test done with GIMP (open transparent .png, save as .tga, open .tga), they support alpha channel.

I think you're doing something wrong in your DX code, it's not a problem of tga.. maybe if you post some snippet we could help you.
Q: How many programmers does it take to write a nice piece of software?A: MORE.
Sc4Freak
Sc4Freak
Yup, they definately support an alpha channel. I've used them several times before.

If you're using Photoshop, remember to check the option to save the alpha channel, and also make sure to save it as a 32-bit TGA when it prompts you to make a choice.
Stanza
Stanza
Yes, TGAs saved in 32-bit format will contain alpha in the high 8 bits of each byte. Whether that data is valid alpha depends upon the editor you're using.

Photoshop supports it, but some versions have required checking extra options while combining the layers and saving to TGA. I haven't touched Photoshop in years, so I don't know what applies to the newest versions.

Paint Shop Pro has correctly stored alpha in every version I've used, but I haven't touched the last couple versions. And the older versions I like always save the TGA in bottom-to-top ordering.

Other editors have been pretty iffy, either supporting only 24-bit TGA, or creating 32-bit but without storing alpha in those extra bits.

There have been problems with DirectX accessing the alpha channel when loading textures from TGA files. The image frequently would be loaded with alpha channel replaced by a constant value. Seems to depend upon what version you're using, and possibly the device drivers. I suggest storing the images in DDS or BMP format if you're wanting to load any that contain transparency (and for BMP, the alpha mask needs to be properly set in the BMP file header).

Note: I was in charge of the TGA file format for most of the last decade from when I was hired on at Truevision, so I do have some small understanding of the file format.
Endar
Endar
Could someone provide a tga image that they know for sure has transparency?

It'll be easier getting my engine working with transparency first.

This is how I'm attempting to load the ARGB data, using D3D:
video::CTexture* IImageResourceLoader::createTextureARGB(const std::string& name, const video::dimension2d& size,							const unsigned char* tex_data, unsigned int tex_data_size) const{	HRESULT res;	if( !tex_data ){		util::LogManager::log( boost::format("%1%: No texture data supplied while attempting to load texture \"%2%\"") %			__FUNCTION__ % name, util::MSGTYPE_ERROR);		return NULL;	}	// if the texture data size is given as 0, we have a problem	if( tex_data_size == 0 ){		util::LogManager::log( boost::format("%1%: Texture data size given as 0 while attempting to load texture \"%2%\"") %			__FUNCTION__ % name, util::MSGTYPE_ERROR);		return NULL;	}	unsigned int	height = (unsigned int)size.height, 					width = (unsigned int)size.width,					mipmap_levels = 1;	D3DFORMAT tex_format = D3DFMT_A8R8G8B8;	// use 'D3DXCheckTextureRequirements' to get the corrected options for the image	if( FAILED(res=D3DXCheckTextureRequirements(m_d3d9Device, 			&width,				// stores the corrected width			&height,			// stores the corrected height			NULL,				// stores the corrected number of mip map levels (doesn't matter at the moment)			0,					// usage - either 0 or D3DUSAGE_RENDERTARGET. This is not a render target.			&tex_format,		// stores the corrected format (should be ARGB)			D3DPOOL_MANAGED		// the memory pool we intend to store the texture in			) ) )	{		util::LogManager::log(boost::format("%1%: Attempt to get corrected texture options via 'D3DXCheckTextureRequirements' failed: "			"D3D error: \"%2%\"") % __FUNCTION__ % video::getDirect3DError(res), util::MSGTYPE_ERROR);		return NULL;	}	// create a texture object	IDirect3DTexture9* tex = NULL;	// load the file	if( FAILED(res=m_d3d9Device->CreateTexture(width, height, mipmap_levels, 0, tex_format, D3DPOOL_MANAGED, &tex, NULL)) ){		util::LogManager::log(boost::format("%1%: Error in creating texture object with size %2%x%3%: D3D error: \"%4%\"") %			__FUNCTION__ % width % height % video::getDirect3DError(res), util::MSGTYPE_ERROR);		return NULL;	}	// load the texture data into the first surface (mip map level) of the texture	IDirect3DSurface9* surface = NULL;	if( FAILED(res=tex->GetSurfaceLevel(0, &surface)) ){		util::LogManager::log(boost::format("%1%: Error in getting pointer to top mip map level of texture: D3D error: \"%2%\"") % __FUNCTION__ %			video::getDirect3DError(res), util::MSGTYPE_ERROR);		return NULL;	}	RECT rect;	// the dimensions of the source image	rect.left = 0;								// the x coord of the upper left rect corner	rect.top = 0;								// the y coord of the upper left rect corner 	rect.right = (unsigned int) size.width;		// the x coord of the lower right rect corner	rect.bottom = (unsigned int) size.height;	// the y coord of the lower right rect corner	// attempt to load the ARGB pixel data into the first mip map level of the texture	if( FAILED(res=D3DXLoadSurfaceFromMemory(surface,			// pointer to the mip map level to load the data into			NULL,				// pointer to the destination pallette - don't need this			NULL,				// specify the destination rectangle - don't need this			tex_data,			// pointer to the upper left corner of the source image 	// in memory - who knows if we're at the right corner!?!?!?!?			D3DFMT_A8R8G8B8,	// the pixel format of the source image			(unsigned int)size.width*4,		// the 'pitch' of the image - length of one row of the image, in bytes			NULL,				// the source pallette - don't need this			▭,				// the dimensions of the source image			D3DX_DEFAULT,		// how to filter the image			D3DCOLOR_ARGB(0,0,0,0)	// specify the color to use as transparent - I think this disables it			) ) )	{		util::LogManager::log(boost::format("%1%: Error in loading pixel data into first map map level (first surface) of newly created texture: "			"D3D error: \"%2%\"") % __FUNCTION__ % video::getDirect3DError(res), util::MSGTYPE_ERROR);		// we need to call surface->Release() when we have finished using it. Otherwise we will get a memory leak!!		surface->Release();		return NULL;	}	// we need to call surface->Release() when we have finished using it. Otherwise we will get a memory leak!!	surface->Release();	// now we just call 'D3DXFilterTexture' to create the rest of the mip map levels	if( FAILED(res=D3DXFilterTexture(tex,	// the texture we're creating the mip map levels for		NULL,	// the pallette - again, who cares? Not me.		0,		// the mip map level that is used to create the rest of the mip map levels - 0 is the top level		D3DX_DEFAULT	// the type of filtering to use when creating the rest of the mip map levels		) ) )	{		util::LogManager::log(boost::format("%1%: Error in creating the rest of the mip map levels using 'D3DXFilterTexture': D3D error: \"%2%\"") %			__FUNCTION__ % video::getDirect3DError(res), util::MSGTYPE_ERROR);		return NULL;	}	// else, D3D was successful in loading, so create the 'CTexture' object	video::CTexture* texture = new video::CTexture(name, size, tex_data, tex_data_size, tex, m_resourceManager);	return texture;}
[size="2"][size=2]Mort, Duke of Sto Helit: NON TIMETIS MESSOR -- Don't Fear The Reaper
Sc4Freak
Sc4Freak
That all seems unnecessarily complicated. Why go through all that trouble to create a texture, get its surface, load texture data from memory into the surface, release the surface, and generate mipmaps? D3DXCreateTextureFromFile() or D3DXCreateTextureFromFileInMemory() will do all this for you.
Endar
Endar
Because I want to greatest amount of extensibility in case I want to try to load a texture that D3D doesn't natively load.

I was using the ARGB data and create a TGA header and TGA footer for it, and then use D3DXCreateTextureFromFileInMemory, but it didn't work, so I tried this.
[size="2"][size=2]Mort, Duke of Sto Helit: NON TIMETIS MESSOR -- Don't Fear The Reaper
3dModelMan
3dModelMan
Just uploaded these.. http://www.matibee.co.uk/tgas/ all have alpha channel.

- Matt

Goober King
Goober King
As stated above they do. Use them extensivly in my stuff. However, there is more to getting alpha blended tga then checking save as 32-bit. Rembmber its alpha blending not color keying to arrive at the transparency. If you save as 32-bit in photoshop it will create the channel for you but fill it. So everything will be visible or invisible. You still need to edit the alpha channel directly to reflect what you want to see though. It doesn't automaticly assume white==Transparent. In the GIMP it works a little diffently and can be harder to figure out.
------------------------------------------------------------- neglected projects Lore and The KeepersRandom artwork
Endar
Endar
Quote:
Original post by Goober King
As stated above they do. Use them extensivly in my stuff. However, there is more to getting alpha blended tga then checking save as 32-bit. Rembmber its alpha blending not color keying to arrive at the transparency. If you save as 32-bit in photoshop it will create the channel for you but fill it. So everything will be visible or invisible. You still need to edit the alpha channel directly to reflect what you want to see though. It doesn't automaticly assume white==Transparent. In the GIMP it works a little diffently and can be harder to figure out.


Has anyone got a quick page that can show me? I've searched for a couple, but they use third-party plugins. I don't want to have to install a plugin to do what photoshop does natively.
[size="2"][size=2]Mort, Duke of Sto Helit: NON TIMETIS MESSOR -- Don't Fear The Reaper
Goober King
Goober King
Quote:
Original post by Endar
Quote:
Original post by Goober King
As stated above they do. Use them extensivly in my stuff. However, there is more to getting alpha blended tga then checking save as 32-bit. Rembmber its alpha blending not color keying to arrive at the transparency. If you save as 32-bit in photoshop it will create the channel for you but fill it. So everything will be visible or invisible. You still need to edit the alpha channel directly to reflect what you want to see though. It doesn't automaticly assume white==Transparent. In the GIMP it works a little diffently and can be harder to figure out.


Has anyone got a quick page that can show me? I've searched for a couple, but they use third-party plugins. I don't want to have to install a plugin to do what photoshop does natively.


Don't have a page but for a how to it depends a lot on what you are trying to do. I can tell you the best way if you post an example of what you got and how you want it to look.

The easy general answer is reopen a file you saved as 32-bit. Click the channels tab on your pallets(often by the layers) you should see a list of all 4 color channels. Red Green blue and Alpha. Click on the alpha channel and you can work on it as if it were a black and white image or in the quick mask mode. Ctrl+alt+4 should zip you right into alpha mode.

edit oops Ctrl+4 no alt key.

one more thing. If you have your image set up like it was color keyed you can magic wand or color select that color, switch to your alpha channel and press Ctrl+I(Invert).

[Edited by - Goober King on February 16, 2007 10:52:04 PM]
------------------------------------------------------------- neglected projects Lore and The KeepersRandom artwork
Endar
Endar
This is the image that I'm attempting to have alpha. I need the background to be transparent.

Goober King: I've got Photoshop Elements, but I couldn't find what you were talking about. I found nowhere that had RGB and alpha. I wasn't able to find how to edit the alpha channel.

Well, I created another layer, which was fully transparent, and I cut and paste the ship onto the transparent layer, and then I erased everything on the background layer. When I loaded it in my game, the whole quad was just black.

I really didn't think it would be this hard to just get some transparency going in a simple 2d game.
[size="2"][size=2]Mort, Duke of Sto Helit: NON TIMETIS MESSOR -- Don't Fear The Reaper
Mastaba
Mastaba
For really simple straight forward transparent TGA's try using Paint.NET to make them. Paint Shop Pro can also make them, but it requires you to create your alpha layer as a mask layer, and then save the mask layer to the alpha channel, before it will save the alpha component. Also, in Paint Shop Pro, if you simply load a transparent tga, it will not appear as transparent until you create a mask from the alpha channel. Paint.NET on the otherhand, does all that automatically, no goofy work arounds. Oddly enough, Paint Shop Pro works better with transparent png files. No funky mask work around stuff needed then for some reason.
xissburg
xissburg
I did not fully read all the posts so I'm not sure if someone already said this ... To create an alpha channel in Photoshop you must go to the Channels palette(if you dont find it, go to Window->Channels) and then at the bottom of this palette find the button that creates a new channel and click it. A new channel called 'Alpha1' will be created. Let the Aplha1 channel selected(and the anothers deselected) and paint your alpha. You can use almost any tools and paint in 256 gray tones(8 bits channel). Now when saving, select the 32 bit option.

Now in D3D, its just load your texture as any texture and then you turn on alpha blending and render. It works for me :P...hope it also works for you.
.
lubby
lubby
Its worth mentioning that certain versions of Photoshop out of the box actually changed the way they saved alpha channel >PS7. There is a tga export plugin available of the Adobe site which fixes this nastiness. Their release notes went something like this 'Removed alpha channel support from TGA file format in favor of transparency' ug, why... The fix/patch/plugin is available here.


Endar
Endar
I finally bought a DX book: "Introduction to 3D Game Programming with DirectX 9.0".

I basically just needed something relevant that would walk me through a bunch of things in relation to D3D, basically help me learn the API for the more basic things.

And it worked!!

I used the Direct X Texture tool to save the image as an ARGB image in the DDS format, which, as a bonus, is a DirectX image format, so it is very easily loaded. I don't touch it at all, and just pass it to DX.

So, I may be back later with more complaints, but as of now, transparency is working.
[size="2"][size=2]Mort, Duke of Sto Helit: NON TIMETIS MESSOR -- Don't Fear The Reaper

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.