RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Direct3D, Part 3: Using Meshes to Save and Load Complex Scenes : Page 4

Direct3D's Mesh class lets you manage, save, and load complex scenes quickly and easily.

Saving .x Files
Many game developers build complex scenes in advanced 3-D modelers such as Studio Max, Blender 3D, and Lightwave 3D. They can then export the results into .x files and load them into Visual Studio applications.

If you're a do-it-yourselfer, however, it's not too hard to write Visual Basic or C# code to save a Mesh into a .x file. There are really only a couple of steps after you build the Mesh. The sample program d3dSaveXFile, which you can find in the downloadable code in both VB.NET and C# versions, uses the following code to save a .x file:

   ' Save the mesh into a .x file.
   ' Make the extended materials.
   Dim exmaterials(m_Materials.Length - 1) _
      As ExtendedMaterial
   Dim files() As String = _
      {"brick.jpg", "water.jpg", _
      "wood.jpg", "woodend.jpg"}
   For i As Integer = 0 To m_Materials.Length - 1
      exmaterials(i).Material3D = m_Materials(i)
      exmaterials(i).TextureFilename = files(i)
   Next i
   ' Prepare the mesh and save it.
   m_Mesh.GenerateAdjacency(CSng(0.1), adjacency)
   m_Mesh.Save("test.x", adjacency, exmaterials, XFileFormat.Text)
First, the code makes an array of ExtendedMaterial structures to store information about the Mesh's materials and textures. Each ExtendedMaterial holds material information plus the name of the file that contains its texture. Later, you must assume that the material files are located in the some directory where the program loading the .x file can find them (usually in the same directory as the .x file).

Next, the program creates a new adjacency array. Like the program d3dMakeMesh, this example uses an adjacency array when it optimizes the Mesh data. Optimizing the data may rearrange the scene's faces and vertices, however, so the original adjacency array may now be incorrect. The code shown here calls the Mesh's GenerateAdjacency method to recreate that data.

Finally, the program calls the Mesh object's Save method, passing it the name of the file where it should save the data, the adjacency array, the extended materials array, and the format it wants the file to use (Binary, Text, or Compressed).

That's all there is to it.

Loading .x Files
Loading a .x file is a little more involved than saving one, because you have to read the individual texture files. The following code shows how the sample program d3dLoadXFile loads .x files:

   ' Load a mesh from a .x file.
   Public Sub LoadMesh(ByVal file_path As String, _
   ByVal file_name As String)
      ' Load the mesh.
      If Not file_path.EndsWith("\") Then file_path &= "\"
      Dim exmaterials() As ExtendedMaterial = Nothing
      m_Mesh = Mesh.FromFile(file_name, MeshFlags.Managed, _
         m_Device, exmaterials)
      ' Load the textures and materials.
      ReDim m_Textures(exmaterials.Length - 1)
      ReDim m_Materials(exmaterials.Length - 1)
      For i As Integer = 0 To exmaterials.Length - 1
         Dim texture_file As String = _
         If texture_file IsNot Nothing Then
            Debug.WriteLine("Texture " & i & ": " & texture_file)
            If texture_file.Length > 0 Then
                  m_Textures(i) = TextureLoader.FromFile( _
                     m_Device, file_path & texture_file)
               Catch ex As Exception
                  Debug.WriteLine("Error loading texture " & _
               End Try
            End If
            Debug.WriteLine("Texture " & i & ": " & "<nothing>")
         End If
         m_Materials(i) = exmaterials(i).Material3D
         m_Materials(i).Ambient = m_Materials(i).Diffuse
      Next i
      ' Save the number of subsets.
      m_NumSubSets = m_Materials.Length
   End Sub
The preceding code makes sure the path where it should look for texture files ends with a backslash. It defines an ExtendedMaterial array and calls the Mesh class's FromFile method to load the file. The code then allocates arrays to hold one material and one texture for each of the entries in the loaded ExtendedMaterial array. It loops through the array, saving the materials and trying to open the texture files. Finally, the code saves the number of subsets so the drawing code can loop through the subsets calling DrawSubset for each.

When it starts, example program d3dLoadXFile looks through a Meshes directory (included in the download) and lists any .x files it finds in its combo box. When you select one of the files, the program loads and displays it.

Figure 2 shows program d3dLoadXFile displaying a .x file built by Microsoft and included in the SDK samples. This scene uses a single texture file (tiger.bmp) to draw each of the tiger's sides.

Figure 2. Terrific Tiger: The program d3dLoadXFile loaded this Mesh from a .x file.
Figure 3. Pretty Plane: This scene uses two texture files.

Figure 3 shows another .x file included in the SDK samples that uses two texture files to draw the plane's body and wings.

Because different .x files may place their data in different places at different scales, the d3dLoadXFile program provides Zoom In (+) and Zoom Out () buttons that you can use to zoom in or out on the data.

With a little experimentation, you'll become comfortable with the power of the Mesh class. A Mesh can represent multiple subsets of faces, each of which uses its own materials and textures. By using a Mesh, you can draw relatively complex scenes with remarkably little code, as well as save scenes and reload them by reading Mesh data from .x files without too much trouble.

But that's not all! Meshes can do still more, such as providing a basis for three-dimensional animation. A Mesh can contain a hierarchy of separate objects that are spatially related to each other. For example, if you wanted to model a humanoid robot, the robot's head, arms, and legs are all attached to the body. As the body moves, so do these appendages. Similarly, if you bend an elbow joint, the attached forearm and hand move as well. Connecting meshes in this manner is called mesh animation, which I hope to cover in a future article. Until then, send any .x file Mesh masterpieces you create to RodStephens@vb-helper.com. I'll be happy to post the best of your creations so you can share them with others.

Rod Stephens is a consultant and author who has written more than a dozen books and two hundred magazine articles, mostly about Visual Basic. During his career he has worked on an eclectic assortment of applications for repair dispatch, fuel tax tracking, professional football training, wastewater treatment, geographic mapping, and ticket sales. His VB Helper web site receives more than 7 million hits per month and provides three newsletters and thousands of tips, tricks, and examples for Visual Basic programmers.
Email AuthorEmail Author
Close Icon
Thanks for your registration, follow us on our social networks to keep up-to-date