imageI have been playing with Silverlight the last few evenings, trying to port Roger Alsings "EvoLisa" application to Silverlight. This application is very cool, it uses a genetic algorithm to create an image composed of polygons that resembles a target image (that you can choose). I have been thinking of doing something like that for some time. I am very interested in artificial life and evolution simulations, especially after reading so many books on evolution by Richard Dawkins and others.

The EvoLisa application is written in WebForms and uses the GDI Graphics object to draw polygons to a bitmap surface, it then does pixel level comparisons to check how close this generated image is to the target image. This proved to be very difficult to port to Silverlight as it was not possible access the pixel buffer of Silverlight WPF controls and surfaces. After hours of googling for 2D or 3D graphícs libraries for Silverlight I gave up and implemented a standard scan line polygon fill algorithm. It is not the simplest of algorithms, especially if you want to support complex polygons.

Another issue was to to display the generated pixel buffer, this is also not possible. The only way to currently do it is through the Image control and encode you pixel buffer as a binary PNG stream which the Image control can then display.  Luckily Joe Stegman had already figured this out, so I did not need to write my own png encoder.

The last issue was also surprising, there is currently no way to read an image (client side) and access the pixels of that image. This is very easy to do server side with the Bitmap class, so instead of writing my own jpg/png decoder I send the target image to the server do the decoding there using the Bitmap class and  then return the pixels as an array of bytes. This is only required once so there is no significant performance penalty for doing this. Hopefully Silverlight 3 will add more low level graphics APIs.

You can see a screenshot to the right, this is just after two evenings of hacking, so the GUI is still very ruff. The performance is not completely on par with the WinForms version, probably because of the scan line polygon renderer is not as optimised as the GDI version (I think GDI is not hardware accelerated, right?).

Last night I took a break from the Silverlight version because I just had to try to do the same but using WPF and Direct3D to render the polygons, I got something working but I don't know the performance benefit yet as it is currently only rendering at the monitor refresh rate. You clearly notice how the Silverlight version slows down as more polygons are added, this is something that I hope the Direct3D version will eliminate.

3 comments:

Justin Chase said...

"After hours of googling for 2D or 3D graphícs libraries for Silverlight I gave up and implemented a standard scan line polygon fill algorithm."

It's all vector graphics based, can't you just use the standard Shapes or a Path to draw whatever you want? That should be pretty straight forward too. In fact this should be a million times easier than doing it with GDI+.

Torkel Ödegaard said...

Yes, I know WPF is all vector based.

Maybe I was not clear enough, the problem is that if you use the primitives available in Silverlight you have no way to access (read) the pixels of the generated image.

Since I need to do pixel level comparisons I am unable to use any of the Silverlight WPF primitive graphics controls.

John said...

Im looking at some personal venture at the moment. I have developed a simple 3D mathmatical class library for Silverlight and was looking to do some interaction. I have yet to find an overview of the code-behind structures for silverlight. Alot of detail oriented but very little "Big Picture" structures out there. As well, you got any suggestions as to some good XAML object literature (preferably web-based)