Sign in to follow this  
Luth

ColorKey / Alpha when creating textures from a surface

Recommended Posts

Luth    130
I'm using the following two functions to load an image to a surface then cut it up into individual textures to use for a tile map. However, the problem is that no transparency information is carried through the process to the final end. Here's (most of) the code, and I'll explain the results below:
bool TextureTileMap::Load(const char* szFileName, u32 uiTileWidth, u32 uiTileHeight, u32 uiTileStart, u32 uiTileEnd)
{
	const D3DFORMAT SURFACE_FORMAT = D3DFMT_X8R8G8B8;
	const u32 COLOR_KEY	= 0xFFFF00FF;
	LPDIRECT3DSURFACE9	_pSurface;
	D3DXIMAGE_INFO		_srcInfo;
	LPDIRECT3DDEVICE9	_pD3D = Direct3D::InstancePtr()->GetDevice();

	string sFileName = TextureManager::InstancePtr()->GetTextureDirectory() + szFileName;


	// A quick hack to get the size of the image into srcInfo.
	if(FAILED(_pD3D->CreateOffscreenPlainSurface(1, 1, SURFACE_FORMAT, D3DPOOL_DEFAULT, &_pSurface, NULL)))
		return false;
	if(FAILED(D3DXLoadSurfaceFromFile(_pSurface, NULL, NULL, sFileName.c_str(),  NULL, D3DX_FILTER_NONE, COLOR_KEY, &_srcInfo)))
		return false;
	_pSurface->Release();

	// Create a surface to hold the entire file
	if(FAILED(_pD3D->CreateOffscreenPlainSurface(_srcInfo.Width, _srcInfo.Height,  SURFACE_FORMAT, D3DPOOL_SYSTEMMEM, &_pSurface, NULL)))
		return false;
	if(FAILED(D3DXLoadSurfaceFromFile(_pSurface, NULL, NULL, sFileName.c_str(),  NULL, D3DX_FILTER_NONE, COLOR_KEY, &_srcInfo)))
		return false;

	...

	for(u32 i = _start; i <= _end; ++i)
	{
		...
		Texture* pTex = CreateTextureFromSurface(_pSurface, &_rect);
		...
	}
}




Texture* CreateTextureFromSurface(LPDIRECT3DSURFACE9 pSurface, RECT* pSrcRect)
{
	u32 _uiTileWidth  = pSrcRect->right - pSrcRect->left;
	u32 _uiTileHeight = pSrcRect->bottom - pSrcRect->top;
	LPDIRECT3DDEVICE9 _pD3D = Direct3D::InstancePtr()->GetDevice();
	LPDIRECT3DTEXTURE9 pTexture;
	D3DSURFACE_DESC surfDesc;
	pSurface->GetDesc(&surfDesc);
	if(FAILED(D3DXCreateTexture(_pD3D, _uiTileWidth, _uiTileHeight, 1, 0, surfDesc.Format, D3DPOOL_DEFAULT, &pTexture)))
		return NULL;

	// Retrieve the surface image of the texture.
	LPDIRECT3DSURFACE9 pTexSurface;
	pTexture->GetSurfaceLevel(0, &pTexSurface);


	// Copy the image to the texture.
	if(FAILED(_pD3D->UpdateSurface(pSurface, pSrcRect, pTexSurface, NULL)))
	{
		pTexSurface->Release();
		return NULL;
	}
	pTexSurface->Release();

	return TextureManager::InstancePtr()->CreateTexture(pTexture, _uiTileWidth, _uiTileHeight);
}

With the functions as they are, any pixel matching COLOR_KEY (255, 0, 255) is drawn as opaque black. Any transparent pixel (0x00??????) gets drawn opaque white. Its only textures created with this method, however. Textures created with *TextureFromFileEx(...) display fine, both color key and 32 bit alpha. I've googled around for an hour or more, and tried a few things on my own, but I just don't know enough to trick it into working. Any help would be greatly appreciated.

Share this post


Link to post
Share on other sites
Luth    130
Don't s'pose anyone has another way of making tiles that keeps alpha and/or colorkey info intact? I'm not married to this method...

Share this post


Link to post
Share on other sites
TheAdmiral    1122
Maybe you'd have more success if the temporary surface had an alpha channel:
const D3DFORMAT SURFACE_FORMAT = D3DFMT_A8R8G8B8;

Admiral

Share this post


Link to post
Share on other sites
Luth    130
Ya know, I was making this same argument to a buddy of mine yesterday...

"Things get too big and complicated very quickly, but you've got to learn to stop and pay attention to the little things." Guilty of irony.

:(

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this