Sign in to follow this  
Spinewire

Problem with Alpha/Transparency and Surfaces **SOLVED**

Recommended Posts

Hi everyone, I'm making an entirely 2D game in DirectX, and I'm having some trouble with transparency in surfaces. What I'm trying to do is create a surface, fill it with 0% alpha ( D3DCOLOR_ARGB( 0, 0, 0, 0 ) ), and then blit some other surfaces onto that surface. The ultimate goal is that every place where I had blitted these 'child' surfaces would be opaque, and everywhere I hadn't would be entirely transparent on the 'master' surface. Unfortunately, this surface's background is not invisible as I would like, but is still opaque black. However, I checked on this surface in PIX, and I know that the surface itself meets the criteria. All of the 'unused' space has 0% alpha, and all of the 'used' space on it is opaque. Somehow, though, after it's blitted to my backbuffer, it becomes fully opaque again, and I don't know what's wrong with that step. Here's the code:
void render( void )
{
	HRESULT result;

	// Erase the backbuffer
	gbl_pD3dDevice->ColorFill( gbl_pBackBuffer, NULL, D3DCOLOR_XRGB( 0, 0, 0 ) );

	// Begin the scene
	result = gbl_pD3dDevice->BeginScene();

	if ( SUCCEEDED( result ) )
	{
		// Draw sprite(s), this code works fine
		gbl_pSprite->Begin( D3DXSPRITE_ALPHABLEND );
		gbl_pSprite->Draw( /* IRRELEVANT, THIS ALL WORKS FINE! */ );
		gbl_pSprite->End();


		gbl_pD3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); 
		gbl_pD3dDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL); 
		gbl_pD3dDevice->SetRenderState(D3DRS_ALPHAREF, (DWORD)8); 
		gbl_pD3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE); 


		// gbl_semitransp is a LPDIRECT3DSURFACE9, explained in the post
		gbl_pD3dDevice->StretchRect( gbl_semitransp, NULL, gbl_pBackBuffer, NULL, D3DTEXF_NONE );

		// Finished rendering
		gbl_pD3dDevice->EndScene();
		gbl_pD3dDevice->Present( NULL, NULL, NULL, NULL );
	}
} // render()


In this code, take for granted that gbl_semitransp is a LPDIRECT3DSURFACE9 composed of a fully alpha background, and several opaque areas where other surfaces have been blitted onto it. I've tried all sorts of SetRenderStates, and none of them seem to work. I don't know what other relevant code I should post, since there's a lot to sift through. The code above is summarized. Thanks for any help! [Edited by - Spinewire on July 5, 2008 1:03:27 AM]

Share this post


Link to post
Share on other sites
Dave: Yes, I have, but thank you for the idea.

Also note that if I colorfill the backbuffer with something other than black and comment out the line where it blits this strange semitransparent surface I'm trying to achieve to the backbuffer, that color will be clearly visible underneath my sprite. However, if I then uncomment the line where it draws this special surface, that surface (which is the same size as my viewport) will obscure both my sprite and that fill color with opaque black, which isn't what I want it to do.

One other thing, too. The sprite itself, which is a texture, uses a color key for transparency, and that works fine. Since this semitransparent surface is generated, and not loaded from a file, it doesn't have a colorkey, it's first filled with 0% alpha, and then the child surfaces are blitted onto it.

EDIT: Could you then please suggest a workable alternative, Evil Steve? Should I use a texture? (Keeping in mind that these surfaces are the size of the viewport, and I will probably have around 12-16 of them.) I'm still somewhat new to DirectX. Thanks.

Share this post


Link to post
Share on other sites
Quote:
Original post by Spinewire
Dave: Yes, I have, but thank you for the idea.

Also note that if I colorfill the backbuffer with something other than black and comment out the line where it blits this strange semitransparent surface I'm trying to achieve to the backbuffer, that color will be clearly visible underneath my sprite. However, if I then uncomment the line where it draws this special surface, that surface (which is the same size as my viewport) will obscure both my sprite and that fill color with opaque black, which isn't what I want it to do.

One other thing, too. The sprite itself, which is a texture, uses a color key for transparency, and that works fine. Since this semitransparent surface is generated, and not loaded from a file, it doesn't have a colorkey, it's first filled with 0% alpha, and then the child surfaces are blitted onto it.

EDIT: Could you then please suggest a workable alternative, Evil Steve? Should I use a texture? (Keeping in mind that these surfaces are the size of the viewport.) I'm still somewhat new to DirectX. Thanks.
If you need to use alpha, then the best way to do this sort of thing is to have your semi-transparent surface as a texture instead, and then render a quad with that texture applied to it.

I'm having a little difficulty understanding what you're trying to do though - why do you need to do this with surfaces rather than textured quads?

Share this post


Link to post
Share on other sites
I was under the impression that this would be faster with a surface, since having 12-16 screen-sized semitransparent textures might be difficult. I'll try switching to textured quads though. Thanks!

EDIT: I ended up actually using Sprite, but the effect is the same. Thanks for the advice. (**SOLVED**)

[Edited by - Spinewire on July 5, 2008 1:37:08 AM]

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