Defining the Mesh

While there are many times when you may want to manually create vertex and index data, it's also common to want to load existing vertex data from an external source, such as a file. A common file format holding this data is an .X file. In the previous chapters, large portions of the code were there just to create simple objects that were to be rendered. While for the simple cubes and triangles, it wasn't all that bad, imagine trying to write similar code that was creating an object that had tens of thousands of vertices instead of the 36 that were used for the cube. The amount of time and effort to write this code would be substantial.

Luckily there is an object in Managed DirectX that can encapsulate storing and loading vertex and index data, namely the Mesh. Meshes can be used to store any type of graphical data, but are mainly used to encapsulate complex models. Meshes also contain several methods used to enhance performance of rendering these objects. All mesh objects will contain a vertex buffer and an index buffer like we've already used, plus will also contain an attribute buffer that we'll discuss later in this chapter.

The actual mesh object resides in the Direct3D Extensions library (D3DX). Currently, we've only had references to the main Direct3D assembly, so before we can use this mesh object, we'll first need to add a reference to the Microsoft.DirectX.Direct3DX.dll assembly to our project. Now, let's try to create our rotating box application using the mesh object.

After you make sure you have the correct references loaded in your solution, you should add a member variable for your mesh. You would place this in the same spot you put your vertex buffer and index buffer member variables before:

 private Mesh mesh = null; 

There are three constructors for creating a mesh; however, currently none of these will be needed. There are several static methods on the Mesh class that we can use to create or load various models. One of the first you'll notice is the "Box" method, which, as its name implies, creates a mesh that contains a box. Considering that's what we want to render right now, that looks perfect. Place the following code after your device creation method:

 mesh = Mesh.Box(device, 2.0f, 2.0f, 2.0f); 

This method will create a new mesh that contains the vertices and indices to render a cube with a height, width, and depth of 2.0f. This is the same size cube we created manually with our vertex buffer before. We've reduced all of that creation code we had down to one line; it doesn't get much easier than that.

Now that we've got our mesh created, though, do we render it the same way, or do we need to do something different? When rendering our cube before, we needed to call SetStreamSource to let Direct3D know which vertex buffer to read data from, as well as setting the indices and vertex format property. None of this is required when rendering a mesh.

DRAWING WITH A MESH

Saying the methods you used when drawing the cube before aren't necessary isn't entirely accurate. The mesh stores the vertex buffer, index buffer, and vertex format being used internally. When the mesh is rendered, it will automatically set the stream source, as well as the indices and vertex format properties for you.

Now that our mesh has been created, what do we need to do in order to render it onscreen? Meshes are broken up into a group of subsets (based on the attribute buffer, which we'll discuss shortly) and there is a method "DrawSubset" we can use for rendering. Let's modify our DrawBox function as follows:

 private void DrawBox(float yaw, float pitch, float roll, float x, float y, float z) {     angle += 0.01f;     device.Transform.World = Matrix.RotationYawPitchRoll(yaw, pitch, roll) *          Matrix.Translation(x, y, z);     mesh.DrawSubset(0); } 

As you can see, we've replaced our call to DrawIndexedPrimitives with a single call to DrawSubset. The generic primitives created by the Mesh class (such as Mesh.Box) will always have a single subset that is zero based. This is all we need to do in order for our application to run; amazingly simple. Go ahead and check it out now.

Well, we've got our nine spinning cubes again, but, boy, are they all pure white. If you looked at the vertex format of the vertices created in the mesh (you can do something as simple as looking at the VertexFormat property on the mesh), you'll see that the only data stored in this mesh is position and normal data. There is no color stored in the mesh, and since we've turned lighting off, it renders everything in white.

If you remember from Chapter 1, "Introducing Direct3D," lighting only works when there is normal data stored for our vertices, and since there is some normal data for our cube, maybe we should just turn lighting back on. The default lighting value for a device is enabled, so you can either remove the line setting it to false, or set it to true.

Well, we've successfully turned our white cubes into black cubes now. Hopefully you guessed this is because we have no lights in our scene, so everything is "dark," thus rendered black. Now rather than specifying specific lights, wouldn't it be great if we could just have a constant light around our entire scene? Welcome to ambient lighting.

Ambient lights provide a constant source of light for a scene. All objects in the scene will be lit exactly the same way since ambient light isn't dependent on any factors that the other lighting methods are (such as position, direction, or attenuation). You don't even really need normal data in order to use an ambient light. Ambient light is highly efficient, but doesn't produce "realistic" results. For now, though, it will produce sufficient results. Add the following line where your lighting render state was:

 device.RenderState.Ambient = Color.Red; 

The ambient light in a scene is globally defined by the ambient render state, which takes in a color. In this case, we want our "global" light to take on a red color so that we can see the effects easily. Running the application now, you might expect to see nine spinning red cubes, but no, they are still black. What else could be missing?



Managed DirectX 9 Graphics and Game Programming, Kick Start
Managed DirectX 9 Kick Start: Graphics and Game Programming
ISBN: B003D7JUW6
EAN: N/A
Year: 2002
Pages: 180
Authors: Tom Miller

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net