Wednesday, 14 October 2009

WPF 3D, The Beauty of Mistakes

When I first coded graphical applications for Windows using GDI many years ago, one thing I discovered was that coding mistakes could often produce very attractive results, particularly when using things like bitmaps and ROP modes. Not as exciting as some of my first work controlling industrial machines, when a mistake could cause 3 tonnes of metal cutting equipment to crash into its end-stops at high speed, but pretty nonetheless.

With WPF 3D coding it's even better. When writing code I like to test things out as often as possible, and this is particularly beneficial with 3D work as often when trying to visualize things in 3D space it's just easier to build things up gradually. The sad thing is that the intermediate results often look better than the finished article, even if they are not correct. For example, this is a chart before the size of the radial elements was calculated.

This is an incomplete spherical element.
And this is the same item with a little more coding.

Another example of this is the use of normals to influence lighting and shading. I most often build up the mesh by creating the points and triangle indices first, viewing the results for correct positioning etc. While it's undoubtedly better to think about and hopefully calculate the normals at this time, I tend to do it afterwards. I'm then disappointed because although the appearance is definitely more correct, it's often not as attractive. The simple bar chart example below shows this.

The finished article had much better defined edges and smooth colours, but it definitely didn't look as nice!

Thursday, 8 October 2009

Silverlight and WPF

This week I have been doing some work producing charts. Many years ago I sold a product called 'Business Graphics Library' and since then many of my projects have involved special charts written on request for customers. As an experiment I wanted to try porting a chart I called a 'starburst', which had originally been written in Excel VBA, to Silverlight.

The chart had a dynamic layout, so I wrote the new one entirely in C# rather than XAML. As you can imagine it was much more straightforward than the Excel VBA original given the rich graphics supported by SL.

Simple starburst

The next step was to use the same code for a WPF desktop application. The Silverlight control included some data structures for passing the information to be plotted, including colours, and my first attempt was to use these, as well as the chart code itself, directly from the library by simply adding a reference to the Silverlight control DLL into the WPF project. This almost worked, but ultimately failed because the Silverlight classes I used were in different .Net assemblies to their WPF equivalents. Even basic types like Color had this problem.

To solve this I added the classes as existing items to the new project, but used the 'Add As Link' option in the dialog (by clicking the arrow on the Add button). I now had common source between the 2 projects, and I could display my chart on a web page using Silverlight or a desktop app using WPF. So far so good.

At this point it was all driven from C#/VB code. The next stage was to be able to use my control entirely from XAML, so some dependency properties were required. Registering these using DependencyProperty.Register worked fine for WPF, which I did first, but I could not get the same code to compile for Silverlight. It turns out that there are different Register methods, and the arguments I had used for WPF (which has 3 overloads) were not compatible with Silverlight (which has only one). Luckily there is a WPF overload which is compatible with the Silverlight implementation so by passing a null for the 4th argument I had compatible code again.

Slightly disappointing to be entering the area of coding around differences. Having a common API between desktop and web applications is a really good idea, and little differences like this seem to be pointless distractions. Of course there are big differences as well. Having used an image projection in SL I was disappointed not to find it in WPF. But my real goal for the Starburst chart is a true 3D version (the subject of another post shortly), but this can only work for WPF as Silverlight does not support true 3D. Given that Silverlight's one major advantage over Flash is the .Net Framework (IMHO) I would hate to seem them diverge.