Sign in to follow this  
damix911

Adding info in the alpha channel

Recommended Posts

Hi everybody! I would like to do alpha blending by loading alpha information from a separate image. I have a blood stain named "blood.jpg" and I want to make it transparent accordingly to the brightness of "blood-alpha.jpg", of the same size. That is, if a certain pixel is white in "blood-alpha.jpg" I want to set the corresponding pixel alpha in "blood.jpg" to transparent; instead, if a pixel is black I want to put the corresponding alpha to opaque. I'm currently using the following code, and it works; what I wanted to know is if it exists an automated way to do it, possibly which would also generate the mip-map chain (note that in this code I didn't create a mip-map chain); in case there isn't, feel free to use this code for your games :-D. Thanks to everybody!
INT texWidth = 512;
INT texHeight = 512;

IDirect3DTexture9 *ground;
D3DXCreateTextureFromFileEx(d3dDevice, "ground.jpg", texWidth, texHeight, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &ground);
IDirect3DTexture9 *blood;
D3DXCreateTextureFromFileEx(d3dDevice, "blood.jpg", texWidth, texHeight, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &blood);
IDirect3DTexture9 *bloodAlpha;
D3DXCreateTextureFromFileEx(d3dDevice, "blood-alpha.jpg", texWidth, texHeight, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &bloodAlpha);

D3DLOCKED_RECT bloodRect;
blood->LockRect(0, &bloodRect, NULL, D3DLOCK_DISCARD);
BYTE *bloodPtr = (BYTE *)bloodRect.pBits;
INT pitch = bloodRect.Pitch;
D3DLOCKED_RECT bloodAlphaRect;
bloodAlpha->LockRect(0, &bloodAlphaRect, NULL, D3DLOCK_DISCARD);
BYTE *bloodAlphaPtr = (BYTE *)bloodAlphaRect.pBits;

for (int i = 0; i < texHeight; i++)
{
	for (int j = 0; j < texWidth; j++)
	{
		INT index = (i * pitch) + (j * 4);

		INT b = (INT)bloodAlphaPtr[index + 0];
		INT g = (INT)bloodAlphaPtr[index + 1];
		INT r = (INT)bloodAlphaPtr[index + 2];

		INT avg = (INT)(((FLOAT)b + (FLOAT)g + (FLOAT)r) / 3);

		bloodPtr[index + 3] = (BYTE)avg;
	}
}

blood->UnlockRect(0);
bloodAlpha->UnlockRect(0);
bloodAlpha->Release();


[Edited by - damix911 on January 2, 2008 4:51:28 PM]

Share this post


Link to post
Share on other sites
Do you lock the textures during a Draw call or just once at initialization?

You have other options:

1) Use the tiff-format, it has a built-in alpha channel
2) the DDS format does also support alpha-channels and also stores mipmaps

If you use shaders you can read the alpha-texture in the pixel shader and combine it with the regular texture

one way:

float4 texture = tex2D(TextureSampler, TexCoords);
float4 alphaTex = tex2D(AlphaSampler, TexCoords);
float opacity = 0.3 * alphaTex.r + 0.59 * alphaTex.g + 0.11 * alphaTex.b; // just take the grayscale luma into account

return texture * opacity


or with a single texture with alpha channel:


float4 texture = tex2D(TextureSampler, TexCoords);

return texture.rgb * texture.a


regards

Share this post


Link to post
Share on other sites
Thank you for your examples! I'm quite new to DirectX and I still have to learn shaders. However yes, I'm doing the whole procedure just one time, before the message loop. So if I use TIFF or DDS, DirectX will be able to load the alpha channel automatically, and also mipmaps for DDS? This sounds quite interesting, at least for simple projects. And what about PNG?

Thank you again :-D

Share this post


Link to post
Share on other sites
Quote:
Original post by damix911
However yes, I'm doing the whole procedure just one time, before the message loop.


That's fine then, altough there's even another way I haven't thought of: without using shaders you might be able to modulate the texture with the alpha channel or a different texture by using the fixed function pipeline by setting the appropriate texture stage states. I started with shaders directly, so someone else might know how to do this.

Quote:
So if I use TIFF or DDS, DirectX will be able to load the alpha channel automatically, and also mipmaps for DDS? This sounds quite interesting, at least for simple projects. And what about PNG?


Yeah, DirectX can use the Mipmaps from DDS files. I'm not sure if you can generate the mipmaps at runtime from the DX API, I haven't done this yet (I always create my DDS files in photoshop). And yes, PNGs do support an alpha channel.

Share this post


Link to post
Share on other sites
Quote:
Original post by FoxHunter2
Yeah, DirectX can use the Mipmaps from DDS files. I'm not sure if you can generate the mipmaps at runtime from the DX API, I haven't done this yet (I always create my DDS files in photoshop). And yes, PNGs do support an alpha channel.


The D3DXCreateTextureFromFileEx function will generate mipmaps for if you specify D3DX_DEFAULT as the number of mipmaps to load from the file.

Also damix if you're going to work with .DDS in Photoshop, I suggest using Nvidia's plugin. It also has a nice normal-map generator.

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