Full source code: http://www.bluerosegames.com/BlitWriteableBitmapSample.zip
This post is partially inspired by René Schulte’s series on extending WriteableBitmap. You can see his fantastic posts here:
http://kodierer.blogspot.com/2009/11/drawing-shapes-silverlight.html
The other inspiration for this comes from efforts that I have been making with SilverSprite, an open source library to compile and run 2D XNA games in Silverlight. When rendering a lot of bitmap sprites to the screen using traditional Silverlight techniques of adding Images to the visual tree works fine for tens or even a couple of hundred of sprites, but add more than this and have them all moving around and this technique starts falling short.
There are some other issues as well, such as drawing with a tint or drawing with anything other than alpha blending. For cases such as these, I wanted to be able to offer an alternative and settled upon rendering (“blitting”) images myself to a WriteableBitmap. This functionality will make it into SilverSprite soon, but in the meantime you can take advantage of it now.
Following in René’s footsteps, I have implemented these methods as extension methods on WriteableBitmap. There are some overloads to simplify the call a bit, but they all end up calling this method:
public static void Blit(this WriteableBitmap bmp, Rect destRect, WriteableBitmap source, Rect sourceRect, Color color, BlendMode blendMode)
Most of these parameters should be clear as to what they do. The part of the source bitmap that is specified is copied to the destination rectangle of the target bitmap. The image is scaled to fill the destination rectangle if the source and destination rectangle differ in size. The two parameters that need a bit more explanation are the color and blend mode.
The color, if not Colors.White, will tint the source image. You can specify a partially transparent color to draw with and the image will be drawn partially transparent.
The blend mode can be AlphaBlend, Additive, Subtractive, or None. AlphaBlend is what you’re used to with Silverlight, but it can be too limiting in some cases. Additive blending can be very useful. Instead of alpha blending the colors, the source and destination red, green, and blue colors are added together to get the resulting color. Let’s consider 3 fully opaque circles, one each of red, green, and blue. With alpha blending, we get something like this:
Whichever one is drawn last ends up on top. If the circles were partially transparent, the values would be alpha blended. For additive, we get something like this:
The center is white because the red, green, and blue components are added together to make white. for subtractive we can start with a white background and draw:
This is exactly what you would get if you inverted the colors in the additive example. This makes sense because we’re subtracting color values instead of adding them, so we’re doing an inverse operation.
Finally, with blend mode None, The source pixels are copied as is to the target, and so the transparent areas of the source image are drawn overwriting the values that were there:
One place where additive blending is useful is with particles effects. Particle effects look more natural and impressive when using additive blending. Here is an example of using additive blending with particles. The particle emitter follows the mouse. The source code for this sample is included at the top of this post.
November 16th, 2009 at 2:49 AM
Great post Bill!
I am going to put up a Codeplex project for my WriteableBitmap extensions. You may want to contribute your Blit extension.
I also wanted to implement a Blit method to my extensions, good that you’ve made it.
December 4th, 2009 at 11:20 AM
I agree with you on mixing standard SL blitting options and direct access to the pixel table WriteableBitmap gives to you. I published short example with an benchmark on my own blog: http://www.dbiesiada.com/blog/2009/12/blitter-and...
Good thing is that I perceive that SL team might have optimized WriteableBitmap.Render() method in SL4. Works faster on SL4 runtime than the one I made for SL3.
December 7th, 2009 at 2:07 PM
I have finally put my WriteableBitmap extensions up on Codeplex and included Bill Reiss' blitting methods:
http://writeablebitmapex.codeplex.com
See the credits.
December 7th, 2009 at 9:14 AM
[...] http://blogs.silverarcade.com/silverlight-games-101/15/silverlight-blitting-and-blending-with-silver... [...]
December 7th, 2009 at 2:26 PM
Thanks Rene I've also posted about it here: http://blogs.silverarcade.com/silverlight-games-1...