Possible to determine if a texture has any alpha pixels?

Started by
7 comments, last by andur 15 years, 6 months ago
Is it possible using DirectX to determine if a loaded texture has any alpha pixels? I've tried to use LockRect() and then scan the pixel data for pixels with alpha, but since I load my textures with D3DPOOL_DEFAULT, I'm unable to do that. Any help would be greatly appreciated. Thanks!
Advertisement
Well, a first step would be to check the format of the image and ensure that there is an alpha channel. Beyond that, you would have to check pixel by pixel on a locked texture, or check pixel by pixel when you first load in your texture (if you do that by hand). There isn't any built in function for doing this.
How do I check the texture pixel by pixel? Like I mentioned before, I tried using LockRect(), but can't since I load my textures with D3DPOOL_DEFAULT. Is there another way?

Also, how can I tell if a texture even has an alpha channel in the first place?
Quote:Original post by Carnevil_
How do I check the texture pixel by pixel? Like I mentioned before, I tried using LockRect(), but can't since I load my textures with D3DPOOL_DEFAULT. Is there another way?

You can try IDirect3DDevice9::UpdateSurface to copy it to system memory, then lock it.

Quote:
Also, how can I tell if a texture even has an alpha channel in the first place?

Look at the surface format.
NextWar: The Quest for Earth available now for Windows Phone 7.
Great! I have it working! Thanks for all of your help! :)

BTW, I'm having to load the texture a second time, with the second time being into system memory. It'd be faster if I could just copy it over, but I'm having trouble getting UpdateTexture() to work. That's something I ought to be able to figure out on my own.

Thanks again!
You can check this without going to the CPU side. Render the texture at 1:1 size to a render target (such as the back buffer) with an alpha test enabled, D3DRS_ALPHAFUNC set to D3DCMP_NOTEQUAL or D3DCMP_LESS and D3DRS_ALPHAREF set to 255. Before you render, set up an occlusion query (see "Queries (Direct3D 9)" in the SDK docs). The result of the query will tell you exactly how many texels in your texture have an alpha that's not opaque.

It's a little bit more complicated than checking on the CPU, though it's simpler if you want to support multiple texture formats, such as compressed textures, but it's more efficient.
Why aren't you loading those textures into the managed pool? Unless you're using them as render targets, or doing other things that require them to be in the default pool then the managed pool is the best place for them. That's because the managed pool automatically handles the limited supply of video memory for you, and simplifies lost device handling.

In addition you probably want to preprocess your textures with a tool before you load them into a game. The simplest option is to convert textures with alpha channels into DXT5, and ones without into DXT1. You can then simply check what format the texture is in at runtime to see if it has alpha in it. It will also improve performance, and save memory. Texconv.exe that comes with the DirectX SDK can be used to do the conversion, or you can write your own tool using the D3DXSaveTextureToFile() and D3DXCreateTextureFromFileEx() functions.
Quote:Original post by Adam_42
You can then simply check what format the texture is in at runtime to see if it has alpha in it.

Note that DXT1 supports 1 bit alpha, so you can't tell from the format if it's used or not.
Quote:Original post by Adam_42
Why aren't you loading those textures into the managed pool? Unless you're using them as render targets, or doing other things that require them to be in the default pool then the managed pool is the best place for them. That's because the managed pool automatically handles the limited supply of video memory for you, and simplifies lost device handling.

In addition you probably want to preprocess your textures with a tool before you load them into a game. The simplest option is to convert textures with alpha channels into DXT5, and ones without into DXT1. You can then simply check what format the texture is in at runtime to see if it has alpha in it. It will also improve performance, and save memory. Texconv.exe that comes with the DirectX SDK can be used to do the conversion, or you can write your own tool using the D3DXSaveTextureToFile() and D3DXCreateTextureFromFileEx() functions.


Agreed, unless you have a specific reason to be loading things into the default pool, the managed pool is almost certainly the better choice.

The preprocess step can be easily used to flag whether or not a texture has an alpha channel as you scan through it and save that information out, so it doesn't have to be done every time you run your game / load a level. The preprocess step certainly doesn't matter if you take the easy way and load textures into the managed pool to analyze them.

Auto-converting things into DXT textures isn't always appropriate. Some textures, notably those with gradients, sometimes get really terrible looking with DXT compression. Lightmaps in particular seem to suffer from this. However, that's an entirely different topic of discussion.

This topic is closed to new replies.

Advertisement