So in my app, I really really wanted to be able to use alpha blending, specifically to darken the entire game screen w/ 50% transparency black, whenever I put a pop-up on top of it.
However, as I soon found out, Alpha Blending just isnt possible with DirectDraw. Even if you use, say, Color.FromArgb(AlphaChannel, RedChannel, GreenChannel, BlueChannel), a DirectDraw app will flat-out override any AlphaChannel value with 255.
After researching, I saw where someone on this forum said it should be possible to get a device handle, and then use GDI+ to write to that device handle.
Well, it worked! Unfortunately, my app went from about ~140 FPS to about 10 FPS when I applied that alpha blending to every frame, so were looking at about a 92% performance degridation, but it did work!
if I werent so intent on continuing to show the normal game animations under the pop-up, I could simply take a snapshot of the current game surface, darken that, cache that, and then just keep copying that pre-darkened image, which would keep my framerate up. But that doesnt work for me.
Anyway, heres the code I used to alpha blend in DirectDraw (this covers an 800x600 surface with a 50% transparent black overlay):
---------------------------------------------------
//Here are some local variables youll need.
Byte[,] __tempByte;
IntPtr __tempIntPtr;
Graphics __newGraphics;
//Creates a brush thats 50% transparent black
SolidBrush __myBrush = new SolidBrush(Color.FromArgb(127, 0, 0, 0));
//Lock the surface
__tempByte=_surfaceToDarken.Lock(LockFlags.DoNotWait);
//Get a pointer to the surfaces device context
__tempIntPtr=_surfaceToDarken.GetDc();
//Instantiate a GDI+ Graphics object pointing to the DirectDraw surface
__newGraphics = Graphics.FromHdc(__tempIntPtr);
//Apply the alpha-blending to the surface
__newGraphics.FillRectangle(__myBrush, new Rectangle(0, 0, 800, 600));
//Now that were done, release and unlock the surface (and its device context)
_surfaceToDarken.ReleaseDc(__tempIntPtr);
_surfaceToDarken.Unlock(__tempByte);
---------------------------------------------------
In the end, I chose *not* to go with this approach because I either needed to take a huge performance hit or lock down my surface while Im showing it darkened. Instead, I just created an 800x600 .bmp that alternated between black and purple(transparent) for every other pixel, and then applied that to the background. Its not as pretty, but at least it can handle on-going animation underneith it without the huge performance hit.
(screenshot of this effect available at http://www.spitshine.com/downloads/ss6_2.gif)
I hope that helps. Id searched for hours and not found any code that could actually do this...
-Hiro_Antagonist
However, as I soon found out, Alpha Blending just isnt possible with DirectDraw. Even if you use, say, Color.FromArgb(AlphaChannel, RedChannel, GreenChannel, BlueChannel), a DirectDraw app will flat-out override any AlphaChannel value with 255.
After researching, I saw where someone on this forum said it should be possible to get a device handle, and then use GDI+ to write to that device handle.
Well, it worked! Unfortunately, my app went from about ~140 FPS to about 10 FPS when I applied that alpha blending to every frame, so were looking at about a 92% performance degridation, but it did work!
if I werent so intent on continuing to show the normal game animations under the pop-up, I could simply take a snapshot of the current game surface, darken that, cache that, and then just keep copying that pre-darkened image, which would keep my framerate up. But that doesnt work for me.
Anyway, heres the code I used to alpha blend in DirectDraw (this covers an 800x600 surface with a 50% transparent black overlay):
---------------------------------------------------
//Here are some local variables youll need.
Byte[,] __tempByte;
IntPtr __tempIntPtr;
Graphics __newGraphics;
//Creates a brush thats 50% transparent black
SolidBrush __myBrush = new SolidBrush(Color.FromArgb(127, 0, 0, 0));
//Lock the surface
__tempByte=_surfaceToDarken.Lock(LockFlags.DoNotWait);
//Get a pointer to the surfaces device context
__tempIntPtr=_surfaceToDarken.GetDc();
//Instantiate a GDI+ Graphics object pointing to the DirectDraw surface
__newGraphics = Graphics.FromHdc(__tempIntPtr);
//Apply the alpha-blending to the surface
__newGraphics.FillRectangle(__myBrush, new Rectangle(0, 0, 800, 600));
//Now that were done, release and unlock the surface (and its device context)
_surfaceToDarken.ReleaseDc(__tempIntPtr);
_surfaceToDarken.Unlock(__tempByte);
---------------------------------------------------
In the end, I chose *not* to go with this approach because I either needed to take a huge performance hit or lock down my surface while Im showing it darkened. Instead, I just created an 800x600 .bmp that alternated between black and purple(transparent) for every other pixel, and then applied that to the background. Its not as pretty, but at least it can handle on-going animation underneith it without the huge performance hit.
(screenshot of this effect available at http://www.spitshine.com/downloads/ss6_2.gif)
I hope that helps. Id searched for hours and not found any code that could actually do this...
-Hiro_Antagonist