dotNoted

Icon

Observations of .Net development in the wild

VS 2005 debugger watch gets a bit lost in the stack when chaining IEnumerable instances

In the spirit of deferring execution to the last possible minute, which on .Net means using IEnumerable and in C# 2.0 the yield keyword, I’ve built a graphics rendering engine which returns rendered objects as an IEnumerable stream. The interface to this engine allows access to an IEnumerable of the rendered objects, which in turn delegates to an object-specific renderer, which in turn delegates to a graphics-system specific renderer. All each one does is to return an IEnumerable to the client object, and defers rendering or otherwise doing computation until the enumeration is iterated. Then it processes each object in turn. This is a nice way to stream computation, since the cost of computation is amortized over each object from the beginning, and each additional one is a marginal, predictable cost, rather than having a huge cost for the first object and then a diminishing cost for subsequent ones. Ad-hoc decision making during the streaming, such as a decision to cancel, is therefore cheaper, since you didn’t have to pay for almost all of the result up front. If you’ve done functional programming, you already know this. We programmers who have done imperative programming most of our lives are just now catching on…

It seems that there are some technical challenges to stacking your IEnumerables high, however. VS apparently does a stack trace to figure out which debug watch language to use, and gets it wrong when it has too many to go through and you get some BCL code iterating your enumeration. Here’s what I get when I call List.AddRange on the graphic engine’s Render operation for some unit test:

VS debugger watch is a bit confused

Note that the code is C#, but the watch popup thinks it’s dealing with C++/CLI.

Filed under: .Net Graphics

Anisotropic filtering != anisotrophic filtering

It’s "anisotropic filtering", not "anisotrophic filtering".

Anisotropic = not isotropic = not (an) the same (iso) direction or alignment (tropic).

Anisotrophic = not isotrophic = not (an) having the same (iso) nutritional requirements or processes (trophic).

When we’re talking about filtering a texture image so that it has less pixels on one side vs. another, that is non-isotropic, meaning that the filtering isn’t the same throughout the image. This is useful when the square texture is projected and has more of a trapezoidal shape due to perspective.

Although care and feeding of your textures could be shown to improve quality, as well…

Filed under: .Net Graphics

SharpMap

I’ve been contributing to the SharpMap project lately (as codekaizen). This contribution unites my interest in .Net and DirectX graphics, GIS, Linear Algebra and Software Engineering.
 
It’s also important for a project at my day job. We’ll have the best mapping component money doesn’t have to buy. Way better than some other libraries, which don’t even offer updatability to their native format. How lame is that? That has always bothered me, especially given the price tag on those components.
 
Check it out, it is a great library, and many people are using it.

Filed under: .Net Graphics

Xaml Namespace Hell

Good tool to get the confounded namespaced right.
 
 
 

Filed under: .Net Graphics

Giving credit

I ran into someone who obviously had a handle on the PathGradientBrush before I did, so I’d thought it respectable to call out to his site where he details the PathGradientBrush use. Yep, it’ Bob Powell, and if you do graphics work you probably know of him, since he hangs out on the newgroups regularly. I don’t quite see my application of using it for shadows, but it isn’t much of a stretch from his billiard ball example. Thanks for all your excellent help, Bob.

Filed under: .Net Graphics

A use for the PathGradientBrush!

I’ve found it!

Ok, I was hasty and somewhat petulant about the PathGradiantBrush. I admit I was not restrained in my hour of roiling frustration with the confounded thing when skewering both it and it’s author for a lack of appreciation of the finer points of connecting same. But let’s be frank: apparently nobody uses it because it is a rough beast which is not only too difficult to use for what limited benefit obtained, but also horrendously underdocumented.

Nevertheless, there is something it is good at: radial blends. The reason for this is that it has a CenterColor property. This fact struck me in answer to a mental question (scream for effect) "How do I get the center of this shape shaded?" The CenterColor property allows a two-tone blend in a circle shape, thus simluating a shadow when a shade of gray is used at the middle and transparent everywhere else. Translate and elongate this shape a little, and you get a good dropshadow when you are drawing your own objects. See pic for effect. The following code should get you close:

GraphicsPath path = new GraphicsPath();

path.AddEllipse(aRectangle);

shadowBrush = new PathGradientBrush(path);

shadowBrush.CenterColor = SystemColors.ControlDarkDark;

shadowBrush.SurroundColors = new Color[] { Color.Transparent };

shadowBrush.CenterPoint = new PointF(aRectangle.Width/2, aRectangle.Height/2);

Filed under: .Net Graphics

PathGradientBrush

Man, what a whack piece of work this is. What was MS thinking?

I work with curved graphics a lot lately, cause basically the look better (use Windows 95 and then XP with the Luna skins… also see the Mac’s progression… less squares, more curves). Every try to color a curve with a PathGradientBrush? Basically, you can’t. That’s because it appears that the PGB does linear interpolation in coloring the area defined by the closed path. This gives the color gradients sharp edges and strange overlaps. The AddCurve method of the GraphicsPath object uses some kind of spline interpolation (I think it is cubic spline interpolation, but I’m not a mathmatician, so I don’t really know, but I get the concept. The link has some pictures of what the difference is between spline and linear interpolation.)

Anyway, I opt for alpha-blended, repositioned (both done with the Blend property of the LinearGradientBrush) fills on my curves. They look better, are easier to deal with, and, I think, more computationally inexpensive. It’s what the XP Luna interface uses to do the skinning of windows and widgets. Check out the pics… the gradients can be turned by a RotationTransform matrix. The InterpolationColors property allows more than a two color gradient. Layering linear gradients allows some sophisticated yet simple to achieve shading.

So, ditch the PGB and all it’s hassles and master the LGB. Unless, that is, if the PGB analog in v2.0 does spline interpolation of colors.

Thanks to Professor Adel Faridani, whose understanding and commitment to justice helped me understand the math.

-r

Filed under: .Net Graphics