Nov 15

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:

 

alphaBlend

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:

additive

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:

subtractive

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:

none

 

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.

This website uses IntenseDebate comments, but they are not currently loaded because either your browser doesn't support JavaScript, or they didn't load fast enough.

5 Responses to “Blitting and Blending with Silverlight’s WriteableBitmap”

  1. Rene Schulte Says:

    Great post Bill!
    I also wanted to implement a Blit method to my extensions, good that you’ve made it. :) I am going to put up a Codeplex project for my WriteableBitmap extensions. You may want to contribute your Blit extension.

  2. Daniel Biesiada Says:

    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.

  3. Rene Schulte Says:

    I have finally put my WriteableBitmap extensions up on Codeplex and included Bill Reiss' blitting methods:

    http://writeablebitmapex.codeplex.com

    See the credits.

  4. WriteableBitmap extensions now on CodePlex | Silverlight Games 101 Says:

    [...] http://blogs.silverarcade.com/silverlight-games-101/15/silverlight-blitting-and-blending-with-silver... [...]

  5. billreiss Says:

    Thanks Rene I've also posted about it here: http://blogs.silverarcade.com/silverlight-games-1...

Leave a Reply

preload preload preload