Sign in to follow this  
Sol Blue

Alpha test is entirely ignored...!

Recommended Posts

Hi all, I'm writing a 2D, top-down game, using ID3DXSprite in object space for drawing. The rendering is going fine, except I can't get an alpha test working. The sprite appears where it's supposed to, but without the surrounding pixels trimmed. Here's some code from my render() function:
// The following code specifies an alpha test and reference value.
gDevice->SetRenderState(D3DRS_ALPHAREF, 10));
gDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER));

...

gDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(255, 0, 255), 1.0f, 0));

gDevice->BeginScene());
mSprite->Begin(D3DXSPRITE_OBJECTSPACE|D3DXSPRITE_DONOTMODIFY_RENDERSTATE));
gDevice->SetRenderState(D3DRS_ALPHATESTENABLE, true));

mSprite->Draw(mTex, 0, 0, 0, D3DCOLOR_XRGB(255, 255, 255)));

gDevice->SetRenderState(D3DRS_ALPHATESTENABLE, false));
mSprite->End());
gDevice->EndScene());

gDevice->Present(0, 0, 0, 0));

Here's the thing: no matter what function I use for the alpha test, nothing changes. For example, the alpha test doesn't seem to kick in with either of these two:
gDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_ALWAYS));
gDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_NEVER));

...even though with D3DCMP_NEVER, the alpha test should prevent everything from being drawn. Anyone see what I'm doing wrong?

Share this post


Link to post
Share on other sites
Not sure if NEVER and such ever worked, but for common alpha testing you'll also have to make sure that the texture you are using has an alpha channel. Apart from that your setup looks fine... it should work. You might also want to use such great tools as PIX or NVidia PerfHUD to verify that the alpha testing states are still in place when the actual draw call is executed. Maybe some other piece of your code resets these renderstates before you actually draw the sprite.

Share this post


Link to post
Share on other sites
Thanks for the reply, Schrompf. I do know the texture has an alpha channel.

I've got it to work with one change: never turning the alpha test off.

gDevice->SetRenderState(D3DRS_ALPHATESTENABLE, true));

mSprite->Draw(mTex, 0, 0, 0, D3DCOLOR_XRGB(255, 255, 255)));

gDevice->SetRenderState(D3DRS_ALPHATESTENABLE, false));



Somehow, if I comment out that last line, it works, and the alpha test is correctly applied. Bizarrely, that must mean that the alpha test was somehow disabled even at the Draw() line.

Edit: This also works:
gDevice->SetRenderState(D3DRS_ALPHATESTENABLE, true);
mSprite->Draw(mTex, 0, 0, 0, D3DCOLOR_XRGB(255, 255, 255));
mSprite->Flush();
gDevice->SetRenderState(D3DRS_ALPHATESTENABLE, false);


I guess this means that the alpha test is applied when sprites are flushed to the back buffer, not when they're queued by the Draw() calls. Can anyone confirm that's the way it works?

Share this post


Link to post
Share on other sites
I wouldn't assume anything about how ID3DXSprite works internally. But, try maybe turning the alpha test back off after the call to End() on the sprite object.

You could also try turning alpha test on, drawing, turning it off, drawing another sprite, turning it back on, and drawing yet another sprite, and see if you get sensible behavior without having to Flush the sprite.

Share this post


Link to post
Share on other sites
ID3DXSprite just queues up the sprites internally to render them all at once, possibly even sorting them by texture if you ask it nicely (via a flag). When you call end it does the actual draw. Just moving the alphatest disable down below the sprite end call should fix things up.

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