he previous article on WPF 3D development showed examples that all use relatively simple single-color materials. The material’s brush determines its color. But WPF also allows you to make materials using brushes that are not simple colors. The following list summarizes the kinds of brushes you can use to make a material.
- Drawing: Paints an area with a drawing that can include shapes, images, text, and even media.
- Gradient: Paints an area with a linear or radial color gradient.
- Image: Paints an area with an image.
- Visual: Paints an area with an image of a visual such as a Button, Label, or Grid.
Here’s how to create a simple material that uses a blue brush.
To make a more complicated material, simply replace the Brush attribute with a more sophisticated brush. The following code makes a brush that displays the image in the file brick.jpg.
Here’s another example that creates a visual brush containing a Label with a gradient background. (This kind of brush can get quite complex if it contains a complicated visual.)
When you use these kinds of brushes, you need to make one more change to the MeshGeometry3D object: you need to tell Direct3D which part of the 3D object corresponds to which part of the brush.
You specify the mapping from brush to object by adding a new TextureCoordinates attribute to the MeshGeometry3D object. This attribute gives the coordinates of the 3D points in the 2D texture space. In that texture space, the upper left corner is at (0, 0), with X increasing to the right and Y increasing downward.
For example, the following code defines a square in the Z = 1 plane.
Table 1 shows how the rectangle’s points correspond to the brush’s coordinates.
|(-1, 1, 1)
|(-1, -1, 1)
|(1, -1, 1)
|(1, 1, 1)
The sample program TexturedCube shown in Figure 1 uses materials filled with image and visual brushes.
|Figure 1. Terrific Textures: This cube is covered with images and visuals.
If you recall how the XAML code builds three-dimensional objects, you’ll remember that a GeometryModel3D object contains both the geometric data that defines the object and the material that covers it. That means one material must apply to all the objects defined by the GeometryModel3D object. Therefore, you need more than one GeometryModel3D object to draw objects that have different materials.
The sample program TexturedCube uses six different GeometryModel3D objects with their own materials to draw a cube where every face has a different material.
The final WPF 3D topic?for now?is transformation. A transformation modifies something by scaling, rotating, or moving it. You can apply transformations to all sorts of things, including lights, brushes, objects, Model3DGroups, ModelVisual3Ds, and cameras.
|Figure 2. Perfect Projections: Perspective projections look more natural so most applications use them.
The Projections program example shown in Figure 2 uses transforms to make building cubes easier. Building a cube in XAML code isn’t too hard, but it is tedious, so it’s a convenient candidate for automation. Rather than building three cubes from scratch, the Projections program uses a Model3DGroup to build a cube centered at the origin. It then uses copies of the same Model3DGroup, but with transformations, to create two other cubes that have been translated to new positions.
The following XAML code shows how the program builds one of its cubes. All the program’s cubes use the exact same GeometryModel3D objects. Each cube uses a TranslateTransform to translate itself into the proper position. In this example, the cube is translated by four units in the Z direction.
|Figure 3. Cube Conversion: This program displays three cubes that have been stretched.
By using TranslateTransform, RotateTransform, and ScaleTransform elements, you can move a 3D object just about anywhere you like. That lets you use simple objects such as cubes centered at the origin to build more complex objects.
For example, the Interlocked program shown in Figure 3 displays three cubes that have been scaled by a factor of 0.4 in one direction and 1.25 in another. You could calculate the location of each shape’s corners manually, but it’s a lot easier to simply transform the cube appropriately.
Most of the programs described in this article use one more transformation: they transform the camera’s position when you use the programs’ sliders.
The following code shows how the programs define their cameras.
The code begins with a Transform3DGroup that includes two rotations, first around the X axis and then around the Y axis. The rotations’ angles are bound to the values of two Sliders named sliX and sliY.
The camera’s definition uses the transformation to change the camera’s position at run time.
The following code shows how the programs define their Sliders. The only real trick here is that sliX uses a ScaleTransform to flip itself upside down. That makes its values increase downward instead of upward and just seems more intuitive to use.
|Figure 4. Amazing Maze: This scene uses multiple lights, materials, and an animated transformation.
Into the Third Dimension
Even split across two parts, this article covers only a small part of WPF’s 3D capabilities. There’s still plenty to learn about brushes, transformations, building shapes, and animating 3D models. However, the techniques described here can get you pretty far.
The Maze program example (see Figure 4) demonstrates many of the techniques described here?plus a few others, including lights, materials that display images, and a camera transformation that you can control with the program’s sliders. (See the downloadable code to find out how it uses an animated transformation to make the globe spin, and to see subroutines that build rectangles, boxes, spheres, and cones.)
The results may not fool anyone into thinking they’re looking at a photograph but they are fairly realistic, and the performance is outstanding. They’re certainly good enough to build some interesting visualization or game programs.
Now it’s your turn. You can start from scratch or use the downloadable sample programs as starting points to build some scenes of your own. If you send me images of the result (you can contact me via my bio at the end of this article), I can post them online.