The OBJ file format is a simple-to-understand ASCII text-based
format that we will parse and extract information from using our new TokenStream
class.Many 3D modeling
applications support this file format, so if you have such a tool,
you’ll be able to create your own geometry and load it in Direct3D.
1. Understanding the OBJ Model Format
The
Wavefront OBJ file format is fairly straightforward. The file has
support for comments, which work like C comments, where an entire line
can be commented out. In the OBJ file commented lines start with a #
symbol and are used for adding remarks to the file that are not supposed
to be interpreted by the tool importing the geometry.
In an OBJ file, information is separated line by
line. This means each vertex position has its own line, each texture
coordinate has its own line, each vertex normal has its own line, and so
forth. Each line in the model’s file starts with a keyword that tells
the tool loading the file what information is present on that line.
mtllib: This keyword is used to
define a material. When you see this keyword, you’ll know that what
follows is the file name for the material properties, which we’ll cover
later in this section.
v: This keyword is used to define a vertex position. Every v keyword is followed by three numbers that represent the X, Y, and Z position of the vertex point.
vt: This keyword is used to define a vertex’s texture coordinate. Each vt keyword is followed by the U and V texture coordinate.
vn: This keyword is used to define a vertex’s normal direction. Each vn keyword is followed by three floating-point values that represent a unit-length normal.
g: This keyword is used to define the name of a mesh in the file. The OBJ file can have more than one mesh defined inside of it.
usemtl:
This keyword is used to define what material the mesh is using.
Different meshes can use different materials, and the materials
themselves are defined in the material file that follows the mtllib keyword.
f: This keyword is used to define a face. Following the f
keyword are three sets of indices for triangles or four sets of indices
if the information is represented by quads.
For each face there are three sets of indices.
Each of these specifies three values separated by a slash (/). These
values are array indexes into the vertex, texture coordinate, and normal
list. For example, if you see the following
it would be interpreted as having three vertices
that make up the face (a triangle), where the first vertex uses the
first position in the positions list (i.e., all the v
keywords), the second value is an index for the texture coordinate list,
and the third is an index for the normal list. The second vertex uses
the fourth position in the positions list, the fifth texture coordinate
from the texture coordinate list, and the sixth normal from the normal
list to define the vertex. This continues for all vertices specified for
the face.
This means that each token that follows f
defines a vertex of the surface. Each of these tokens can be further
broken down to define which position, texture coordinate, and normal
from their respective lists are attributes of that vertex. The sample OBJ model is a 3D cube made up of 12 triangles, two for each
side of the cube. This OBJ file was exported by MilkShape 3D.
Listing 1. A Sample OBJ File
# Wavefront OBJ exported by MilkShape 3D
mtllib box.mtl
v -2.000000 -2.000000 -2.000000
v 2.000000 -2.000000 -2.000000
v -2.000000 2.000000 -2.000000
v 2.000000 2.000000 -2.000000
v -2.000000 -2.000000 2.000000
v 2.000000 -2.000000 2.000000
v -2.000000 2.000000 2.000000
v 2.000000 2.000000 2.000000
# 8 vertices
vt 1.000000 0.000000
vt 1.000000 1.000000
vt 0.000000 1.000000
vt 0.000000 0.000000
# 4 texture coordinates
vn 0.000000 -0.000000 -1.000000
vn -0.000000 -1.000000 0.000000
vn -1.000000 0.000000 -0.000000
vn 1.000000 0.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 0.000000 1.000000
# 6 normals
g cube
usemtl material
s 1
f 1/1/1 3/2/1 4/3/1
f 1/1/1 4/3/1 2/4/1
f 1/4/2 2/1/2 6/2/2
f 1/4/2 6/2/2 5/3/2
f 1/4/3 5/1/3 7/2/3
f 1/4/3 7/2/3 3/3/3
f 2/1/4 4/2/4 8/3/4
f 2/1/4 8/3/4 6/4/4
f 3/3/5 7/4/5 8/1/5
f 3/3/5 8/1/5 4/2/5
f 5/4/6 6/1/6 8/2/6
f 5/4/6 8/2/6 7/3/6
# 12 triangles in group
# 12 triangles total
|
The material file is similar to the model file. In the material file the name of the material is specified by the newmtl keyword. The diffuse color for the material is specified by the Kd keyword, the ambient term by the Ka keyword, and the specular term by the Ks keyword. The Ns keyword specifies the shininess of the specular term, or in other words the specular power, and the illum keyword specifies the illumination, where 1 means the specular term is not used and 2 means it is used. The map_Kd keyword is used to specify a color texture image’s file name. The last keyword that can appear in an OBJ material file is the d keyword, which specifies the material’s transparency (alpha) value. Some tools use Tr instead of d, which is the same thing.
A sample material file that was created when the cube model was created is shown in Listing 2.
Listing 2. A Sample OBJ Material File
newmtl material
Ka 0.300000 0.3000000 0.300000
Kd 0.700000 0.7000000 0.700000
Ks 1.000000 1.0000001 1.000000
Ns 50.000000
Tr 0.000000
illum 2
map_Kd decal.dds