**PETZOLD BOOK BLOG**

Recent Entries | ||

< Previous | Browse the Archives | Next > |

Subscribe to the RSS Feed |

December 15, 2006

Roscoe, NY

Yesterday I discussed how the *TextureCoordinates* collection of the *MeshGeometry3D* class can actually have coordinates outside the range of 0 and 1, contrary to the documentation. I said coordinates outside this range were "internally normalized." Of course, that was a supposition because I am not privy to WPF source code, and today I think that supposition was not quite conceptually correct.

I think it's probably more accurate to say that the complete range of *TextureCoordinates* values defines a 2D coordinate system for the brush. In many cases, the actual extents of this coordinate system are irrelevant because by default brushes stretch to fill their content, which in this case is the coordinate system implied by the *TextureCoordinates* collection.

But sometimes brushes can be affected by the coordinate system. In 2D graphics programming, that coordinate system is 96 DPI. In 3D programming, that coordinate system is defined by *TextureCoordinates* collection.

Consider this XAML file:

The program defines a 10 x 10 unit *GeometryDrawing* as a resource and then uses that in two *DrawingBrush* objects with *TileMode* set to *Tile*. These two *DrawingBrush* objects cover two *GeometryModel3D* objects. In both, the mesh geometries define rectangular surfaces 2 units wide and 4 units deep.

In the first object, the *TextureCoordinates* collection is defined as the documentation suggests with coordinates between 0 and 1. The *Viewport* of the *DrawingBrush* is defined as "0 0 0.1 0.05", which means that each tile occupies 1/10th of the width and 1/20 of the depth of the surface. Consequently, the surface is covered with 10 tiles across the width, and 20 tiles down the depth, which results in the tiles appearing square.

In the second object, the *TextureCoordinates* are defined with X values ranging from 0 to 100, and Y values from 0 to 50. The *ViewportUnits* property of the *DrawingBrush* is set to "Absolute" and the *Viewport* property is "0 0 10 2.5", which means that each tile is 10 units wide and 2.5 units deep. These units are relative to the coordinate system defined by the *TextureCoordinates* collection (which is 100 wide and 50 deep), so again there are 10 tiles across the width and 20 tiles down the depth. The result is the same as the first object.

In the second object, you can set *ViewportUnits* to the default "RelativeToBoundingBox" (or leave it out) and *Viewport* to "0 0 0.1 0.05" and you'll get the same result. In the first object, it doesn't matter what you set *ViewportUnits* to because the coordinate system defined by the *TextureCoordinates* collection has rendered the two options the same.

I haven't seen any advantage to defining *TextureCoordinates* values outside the range of 0 and 1, and I don't think there is one. But I think this example provides a little bit of insight into how 2D brushes are used by WPF 3D.

(c) Copyright Charles Petzold

www.charlespetzold.com