440 likes | 702 Views
X file & Mesh. Chapter 8. What is X file?. X file is a file that is used to store D3D program's data. Any X file has extension *.x. X file could be text file or binary file. They are exactly same except one is in binary format for the purpose to keep their data in secrete.
E N D
X file & Mesh Chapter 8
What is X file? • X file is a file that is used to store D3D program's data. • Any X file has extension *.x. • X file could be text file or binary file. They are exactly same except one is in binary format for the purpose to keep their data in secrete. • The first line of X file (text version) must be xof 0302txt 0032 It is called X declaration. • X file consists of two parts. All template definitions are in Part I; all data bodies are in Part II. • Any kind of data can be stored in a X file. Such as vertex arrays. One template could have more than one data body. • All data stored in X file are in a tree hierarchy structure.
Templates After X declaration, there are list of Templates, which are like template Game_Infor{ <C042EEE0-7983-4a41-BD17-A1FBB75F7754> // GUID STRING Game_name; STRING COMPANY; DWORD nVertices; array Vector vertices[nVertices]; […] //place holder for child template } Note: Not every template has child template place holder […]
Generate GUID GUID is a128 bits number for registering the template class, which can be generated by GUIDGEN.exe C:\Program Files\Microsoft Visual Studio\Common\Tools\GUIDGEN.exe
What is Mesh? In DirectX3D, mesh is a special format to record the 3D model information data. Generally, a mesh data could have some of the following information. (1 & 2 are the must) 1. Vertices. 2. Faces, which are determined by 3 or 4 vertices index. 3. Material list. (important if Mesh has multiple materials) 4. Normal of each vertices and normal of each face. 5. Texture coordinates of each vertex in all surfaces. 6. Texture image file name. 7. Effectively Animations. We can record mesh data in a X file
Template of Mesh template Mesh { <3D82AB44-62DA-11cf-AB39-0020AF71E433> DWORD nVertices; // number of vertices array Vector vertices[nVertices]; DWORD nFaces; // number of facesarray MeshFace faces[nFaces]; [...] } Note 1: The minimum of a Mesh is of vertices & faces.Note 2: Vector is a set of 3 float numbers.Note 3: MeshFace is a set 3 or 4 indices of the vertices.
Possible Templates in Mesh 1 template MeshMaterialList { <F6F23F42-7686-11cf-8F52-0040333594A3> WORD nMaterials; // number of material colors DWORD nFaceIndexes; // number of color faces array DWORD faceIndexes[nFaceIndexes]; // The indexes values of the following materials [Material] // list of Materials} Note 1: This is used to specify the color of each MeshFace. Note 2: In array of faceIndexes, the nth integer value is the material index of the nthMeshface.Note 3: If there is only one Material, we set 1, 1, 0 means all MeshFaces use the same color Material.
Possible Templates in Mesh 2 template MeshNormals { <F6F23F43-7686-11cf-8F52-0040333594A3> DWORD nNormals; // number of vertices normal array Vector normals[nNormals]; DWORD nFaceNormals; // number of face normal array MeshFace faceNormals[nFaceNormals]; } Note 1: In array of vectors normals, the nth normal vector will belong to the nth vertex.Note 2: faceNormals is just the set of vertex indices. The program can automatically calculate the normal of Meshface.
Possible Templates in Mesh 3 template MeshTextureCoords { <F6F23F40-7686-11cf-8F52-0040333594A3> DWORD nTextureCoords; // number of coordinates array Coords2d textureCoords[nTextureCoords]; // list of floating number pairs } Note: In array of vectors textureCoords , the nth 2 floating numbers is the Texture Coordinates of the nth vertex.
Hierarchy in tiger.x Mesh MeshMaterialList Material MeshTextureCoords TextureFilename
Mesh Data in cube.x // 24 vertices
// 6 faces // 6 vertex normal // 6 mesh faces
Hierarchy in cube.x Mesh child MeshMaterialList child Material child MeshNormals TextureFilename child MeshTextureCoords
Hierarchy in ColorCube.x Mesh MeshVertexColors
Multiple Meshes Cube3.x
Hierarchy in taurus.x Mesh MeshMaterialList Material MeshNormals
Use DirectX Mesh Viewer The mesh model in a X file can be viewed by Mesh viewer Note: The texture image file must be in the same folder, otherwise the texture won’t be loaded.
Use Mesh to Draw 3D Model Use Mesh to draw 3D Model is very simple, which only needs two lines of code, if without materials and textures. Mesh mesh = Mesh.FromFile(NameOfXFile, MeshFlags.SystemMemory, device); mesh.DrawSubset(0); However, Mesh has materials and textures data, we need to use object ExtendedMaterialto collect materials and textures information. • ExtendedMaterial[] materials = null; • mesh = Mesh.FromFile("tiger.x", MeshFlags.SystemMemory, • device, out materials);
Load Mesh to 3D program • Mesh mesh; // Main Mesh objectMaterial meshMaterial; // Mesh material Texture meshTexture; // Mesh Texture • void InitMesh() • { • ExtendedMaterial[] materials = null; • mesh = Mesh.FromFile("tiger.x", MeshFlags.SystemMemory, m_device, out materials); • meshMaterial = materials[0].Material3D; • meshMaterial.Ambient =meshMaterial.Diffuse; // if lighting on • meshTexture = TextureLoader.FromFile(device, materials[0].TextureFilename) ; • } Note: This is only for one material
Draw Mesh • void Render() • { . . . . . . . .. • device.BeginScene();SetRotation();device.Material = meshMaterial;device.SetTexture(0, meshTexture); mesh.DrawSubset(0); // must use index 0 device.EndScene();device.Present(); • . . . . . . • } Note: tiger.x and tiger.bmp must in the same directory
Multiple Materials • Mesh mesh; // Main Mesh objectMaterial [] meshMaterials; // Mesh material array Texture [] meshTextures; // Mesh Texture array int total; • void InitMesh() • { • ExtendedMaterial[] materials = null; • mesh = Mesh.FromFile("tiger.x", MeshFlags.SystemMemory, device, out materials); • total = materials.Length; • meshTextures = newTexture[total]; • meshMaterials = new Material[total];
for( int i=0; i<total; i++ ) • { • meshMaterials[i] = materials[i].Material3D; • meshMaterials[i].Ambient = meshMaterials[i].Diffuse; • // if lighting on • meshTextures[i] = TextureLoader.FromFile(device, • materials[i].TextureFilename); • } • } Note: If there is no Texture in the Mesh, delete code related to the textures.
Draw Mesh • void Render(){ . . . . . . . .. • device.BeginScene();SetRotation();for( int i=0; i<total; i++ ){ • device.Material = meshMaterials[i]; device.SetTexture(0, meshTextures[i]); mesh.DrawSubset(i) • } • device.EndScene();device.Present(); . . . . . . • }
Write mesh to X file Step1: Use the following Constructor to create a Mesh object public Mesh( int numFaces, int numVertices, MeshFlags options, VertexFormats vertexFormat, Device device ); Example: cube_mesh = new Mesh(12, 8, MeshFlags.Managed,CustomVertex.PositionColored.Format, device);
Step2: Set VertexBuffer and IndexBuffer values of the Mesh.Define vertex array Verts and index array Indices. CustomVertex.PositionColored [] Verts;short []Indices; After set their data, write them into vertexBuffer and indexBuffer of mesh object using(VertexBuffer VB = mesh.VertexBuffer){ GraphicsStream data = VB.Lock(0, 0, LockFlags.None); data.Write(Verts); VB.Unlock();} using(IndexBuffer IB = mesh.IndexBuffer){ IB.SetData(Indices, 0, LockFlags.None); } Note: Index array must be of type short. One int will be split into 2 short index numbers
Step3: Save to an X file by the following function of Mesh public void Mesh::Save(string filename, int[] adjacency, ExtendedMaterial[] materials, EffectInstance[] effects, XFileFormat format ); Note:1) It will save to the same directory of the excitable application2) adjacency is array of three Int32 values per face that specify the three neighbors for each face in the mesh. Set to null if no.3) materials cannot set to null, the array size is at least 1.4) effects can set to null if no.5) formatset to FileFormat.TEXT.
Example1: Coding ColorCube.x • private void MakeCubeMesh(){int numVerts = 8; // 8 pointsint numFaces = 12; // 12 triangles • Mesh=new Mesh(numFaces, numVerts, MeshFlags.Managed, CustomVertex.PositionColored.Format, device); • CustomVertex.PositionColored [] Verts = new CustomVertex.PositionColored[8];Verts[0].Position = new Vector3(-1.0f, 1.0f, 1.0f);Verts[1].Position = new Vector3(-1.0f, -1.0f, 1.0f);Verts[2].Position = new Vector3( 1.0f, 1.0f, 1.0f);Verts[3].Position = new Vector3( 1.0f, -1.0f, 1.0f);Verts[4].Position = new Vector3(-1.0f, 1.0f, -1.0f);Verts[5].Position = new Vector3(1.0f, 1.0f, -1.0f);Verts[6].Position = new Vector3(-1.0f, -1.0f, -1.0f);Verts[7].Position = new Vector3(1.0f, -1.0f, -1.0f);
Verts[0].Color = Color.Red.ToArgb() ; Verts[1].Color = Color.Blue.ToArgb() ;Verts[2].Color = Color.Green.ToArgb() ; Verts[3].Color = Color.Yellow.ToArgb(); • Verts[4].Color = Color.Yellow.ToArgb() ; Verts[5].Color = Color.Blue.ToArgb() ;Verts[6].Color = Color.Green.ToArgb() ; Verts[7].Color = Color.Red.ToArgb() ; • using(VertexBuffer VB = mesh.VertexBuffer) { GraphicsStream data = VB.Lock(0, 0, LockFlags.None); data.Write(Verts); vb.Unlock();} Or use mesh.SetVertexBufferData(Verts, LockFlags.None);
short[] indices = { // must use type short not type int 0,1,2, 1,3,2, // Front Face 4,5,6, 6,5,7, // Back Face 0,5,4, 0,2,5, // Top Face 1,6,7, 1,7,3, // Bottom Face 0,6,1, 4,6,0, // Left Face 2,3,7, 5,2,7 // Right Face }; using(IndexBuffer IB = mesh.IndexBuffer) { IB.SetData(indices, 0, LockFlags.None); }int [] adj= null; ExtendedMaterial[] mtrl = new ExtendedMaterial[1]; mesh.Save("cube.x", adj, mtrl, null, XFileFormat.Text); } Or use mesh.SetIndexBufferData(indices, LockFlags.None);
Example2: Coding TexturedSphere.x private void MakeTexturedSphereMesh(int m, int n, float r){int numVerts = (m+1)*(n+1); int numFaces = 2*m*n; mesh=new Mesh(numFaces, numVerts, MeshFlags.Managed, CustomVertex.PositionColored.Format, device); CustomVertex.PositionNormalTextured[] Verts = newCustomVertex.PositionNormalTextured[(m+1)*(n+1)]; float a =2*(float)Math.PI/m; float t = (float)Math.PI/n for(int j=0; j<(m+1)*(n+1); j++) {int k=j/(m+1); int i=j%(m+1);float x = r*(float)Math.Sin(k*a)*(float)Math.Cos(i*t);float y = r*(float)Math.Sin(k*a)*(float)Math.Sin(i*t);float z = r*(float)Math.Cos(k*a); Verts[j].Position = new Vector3(x, y, z); Verts[j].Normal = Verts[j].Position ; Verts[j].Tu =(float)i/(float)m; Verts[j].Tv =(float)k/(float)n; }
mesh.SetVertexBufferData(Verts, LockFlags.None); int[] indices = new int[6*m*n];for(int j=0;j<m*n;j++){int k = j/m;int i = j%m; indices[j*6] = j+k; indices[1+j*6] = j+k+(m+2); indices[2+j*6] = j+k+(m+1); indices[3+j*6] = j+k; indices[4+j*6] = j+k+1; indices[5+j*6] = j+k+(m+2);} short [] index = new short [6*m*n]; for(int i=0; i<6*m*n ; i++) index[i] = (short)indices[i];mesh.SetIndexBufferData(index, LockFlags.None ); int []adj= null; ExtendedMaterial[] mtrl = new ExtendedMaterial[1]; mtrl[0].TextureFilename = "earth.jpg"; mesh.Save("sphere.x", adj, mtrl,null, XFileFormat.Text); • }
DirectX3D Built-in Mesh DirectX3D has built-in the following several meshes: • Mesh.Teapot(device); • Mesh.Box(device, float, float, float); • Mesh.Taurus(device, float, float, int, int ); • Mesh.Cylinder(device, float, float,float, int, int); • Mesh.Sphere(device, float, int, int ); • Mesh.Polygon(device, float, int ); They can be directly used in 3D programs.