Home » Community » Forums » For Beginners » GDI AlphaBlend - Transparent Color appearing Opaque
  Intel sponsors gamedev.net search:   
[Control Panel] [Register] [Bookmarks] [Who's Online] [Active Topics] [Stats] [FAQ] [Search]

Add Forum to Favorites |  Send Topic To a Friend | View Forum FAQ | Track this topic


 Last Thread Next Thread 
 GDI AlphaBlend - Transparent Color appearing Opaque
Post New Topic  Post Reply 
Hi,

I seem to be having some difficulty getting the GDI AlphaBlend function working correctly. I'm using a 32-bit image with alpha to get a partial transparency, but the portions of the image set for 0 alpha always appear as solid white.

I'm trying to create shadows of aircraft flying over my terrain, so the big white box around the plane shadows is ... undesirable. I'm using the following for blitting:
BLENDFUNCTION bf;
   bf.BlendFlags = 0;
   bf.AlphaFormat = AC_SRC_ALPHA;
   bf.BlendOp = AC_SRC_OVER;
   bf.SourceConstantAlpha= 255;

				
   AlphaBlend(myDestination->getBackBufferDC(), static_cast<int>(X + myShadowOffsetX), static_cast<int>(Y + myShadowOffsetY), myShadow->width, myShadow->height, myShadow->ImageDC, 0, 0, myShadow->width, myShadow->height, bf);


The image I'm using for the shadow itself is this: [IMG]http://img481.imageshack.us/img481/3677/enemy1shadow32li9.png[/IMG]
(ImageShack seems to have converted it to a PNG file, but the white portions are alpha value = 0, and the black are approximately 50% (value of 130).

The result of the AlphaBlend looks like this: [img]http://img130.imageshack.us/img130/3550/ss01alphablendnotworkindg9.jpg[/img]

Any ideas? Thanks for any help.
-Amrazek

 User Rating: 1031   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

AlphaBlend() does not work in the way you are trying to use it. It applies an alpha value over the entire image. Bitmaps do not contain per-pixel alpha values and so you cannot define a set of pixels to be transparent.

This method is the standard way to achieve transparent images.



 User Rating: 1676   |  Rate This User  Send Private MessageView ProfileView JournalView GD Showcase Entries Report this Post to a Moderator | Link

Quote:
Original post by Colin Jeanne
AlphaBlend() does not work in the way you are trying to use it. It applies an alpha value over the entire image. Bitmaps do not contain per-pixel alpha values and so you cannot define a set of pixels to be transparent.


You're wrong, they do. Windows (kind of) supports 32-bit bitmaps, but there's a catch if you use the AlphaBlend function. You have to premultiply each pixel of the source bitmap with its alpha value. The reason you're seeing a white background is because those pixels should be black: 255 times 0 yields 0 for each channel red, green and blue. Note that although AlphaBlend requires you to premultiply, it does need the alpha channel, so keep your bitmaps intact.

Also, take notice that AlphaBlend is slooow. I'm pretty sure there are better alternatives to the native GDI, even if they are implemented entirely in software.

 User Rating: 1227   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

Quote:
You have to premultiply each pixel of the source bitmap with its alpha value. The reason you're seeing a white background is because those pixels should be black: 255 times 0 yields 0 for each channel red, green and blue. Note that although AlphaBlend requires you to premultiply, it does need the alpha channel, so keep your bitmaps intact.

I remember reading somewhere in the documentation that it required the premultiplied value, but the examples I found through google didn't premultiply. In hindsight, they probably were only making use of the constant alpha and not the alpha value for every pixel. I added the following:
	  int bufferSize = target->widthBytes * target->height;
	  BYTE* buffer = (BYTE*)malloc(bufferSize);

	  // retrieve the pixel values
	  GetBitmapBits(target->NewBitmap, bufferSize, buffer);

	      // calculate the new alpha values
		  int i = 0;

		  while (i < bufferSize) {
		  	  buffer[i + 0] = buffer[i + 0] * buffer[i + 3];
			  buffer[i + 1] = buffer[i + 1] * buffer[i + 3];
			  buffer[i + 2] = buffer[i + 2] * buffer[i + 3];
			  
			  i = i + 4;
		  }

	  // set the pixel values
	  SetBitmapBits(target->NewBitmap, bufferSize, buffer);
	  delete buffer;


And the image worked perfectly!

Quote:
Also, take notice that AlphaBlend is slooow. I'm pretty sure there are better alternatives to the native GDI, even if they are implemented entirely in software.

I know, that's why I'm making sparing use of it. I tried just blitting the shadows with a mask, but their solid color didn't look right and was actually distracting.

Thanks for your help! Problem solved :)

 User Rating: 1031   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

All times are ET (US)

Post Reply
 Last Thread Next Thread 
Forum Rules:
You may not post new threads
You may not post replies
You may not edit your posts
You may not use HTML in your posts
Jump To:
Administrative Options: