In my last blog entry I talked about how the new Bitmap API in Silverlight 3 gives you the ability to render controls to a WriteableBitmap, I also mentioned how it gives you direct access to editing pixels in a bitmap. I wanted to put together an example of what this ability can provide, and I wanted to show off how performant the get/put pixel abilities in Silverlight 3 actually are.
In the demo above you can see a fire algorithm (previously done in WPF and hacked up in Silverlight 2) as well as a text scroller - both of these are being rendered pixel by pixel. The bitmap the text scroller is manipulating was created by rendering a TextBlock with a drop shadow effect to a bitmap (read more on how to render text to an image here). By clicking on the demo you can see some simple elastic transitions being done on the rendered WriteableBitmaps - I was pretty impressed to see that even though tens of thousands of pixels are being manually rendered, the transitions performed very well (at least on my machine).
The ability to get/put pixels is exactly the sort of thing that will allow things like doom/quake/etc. to be ported to Silverlight - because you can bypass all XAML and just use a WriteableBitmap to manually render all of your UI at the pixel level.
One of the issues with getting and putting pixels with the Bitmap API in Silverlight 3 is that the direct pixel access is done by setting a pixel's color - which is an integer. Converting a Color to an Int when putting, or an Int to a Color when getting isn't exactly intuitive, so I wanted to post examples of both for others who might be giving this great new ability a whirl.
(more after the break..)
Converting from a Color into an integer is done by bit-shifting the bytes from each channel (alpha, red, green, blue) into an integer, and converting an integer to a Color is done by bit-shifting the integer back to the original color channels - below are examples of both:
Creating a WriteableBitmap and setting the color of the first Pixel:
(thanks to Andrea Boschin for his sample code showing how this was done)
1: // setting a pixel example
2: WriteableBitmap bitmap = new WriteableBitmap(400, 200);
3: Color c = Colors.Purple;
4: bitmap.Pixels = c.A << 24 | c.R << 16 | c.G << 8 | c.B;
Getting the color of the first Pixel from an existing WriteableBitmap:
1: // getting a pixel example
2: int colorAsInt = bitmap.Pixels;
3: Color c = Color.FromArgb((byte)((colorAsInt >> 0x18) & 0xff),
4: (byte)((colorAsInt >> 0x10) & 0xff),
5: (byte)((colorAsInt >> 8) & 0xff),
6: (byte)(colorAsInt & 0xff));
I'm very curious to see what doors the Silverlight 3 Bitmap API will open up for developers. I am hopeful to see some ports of older games, or 2D based demos, etc. - if you come across anything cool be sure to post it in the comments! Also, you can find the source code for the demo above attached - but wade at your own risk ;)