Alpha test is entirely ignored...!

Started by
3 comments, last by Namethatnobodyelsetook 15 years, 11 months ago
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?
Advertisement
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.
----------
Gonna try that "Indie" stuff I keep hearing about. Let's start with Splatter.
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?
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.

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.

This topic is closed to new replies.

Advertisement