private static StaticMesh LoadObj(string staticMeshId, string filePath) { // These are temporarily needed lists for storing the parsed data as you read it. // Its better to use "ListArrays" vs "Lists" because they will be accessed by indeces // by the faces of the obj file. List_Array <float> fileVerteces = new List_Array <float>(10000); List_Array <float> fileNormals = new List_Array <float>(10000); List_Array <float> fileTextureCoordinates = new List_Array <float>(10000); List_Array <int> fileIndeces = new List_Array <int>(10000); // Obj files are not required to include texture coordinates or normals bool hasTextureCoordinates = true; bool hasNormals = true; // Lets read the file and handle each line separately for ".obj" files using (StreamReader reader = new StreamReader(filePath)) { int lineNumber = 1; while (!reader.EndOfStream) { try { string[] parameters = reader.ReadLine().Trim().Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); switch (parameters[0]) { // Vertex case "v": fileVerteces.Add(float.Parse(parameters[1], CultureInfo.InvariantCulture)); fileVerteces.Add(float.Parse(parameters[2], CultureInfo.InvariantCulture)); fileVerteces.Add(float.Parse(parameters[3], CultureInfo.InvariantCulture)); break; // Texture Coordinate case "vt": fileTextureCoordinates.Add(float.Parse(parameters[1], CultureInfo.InvariantCulture)); fileTextureCoordinates.Add(float.Parse(parameters[2], CultureInfo.InvariantCulture)); break; // Normal case "vn": fileNormals.Add(float.Parse(parameters[1], CultureInfo.InvariantCulture)); fileNormals.Add(float.Parse(parameters[2], CultureInfo.InvariantCulture)); fileNormals.Add(float.Parse(parameters[3], CultureInfo.InvariantCulture)); break; // Face case "f": //if (parameters.Length < 4) // throw new StaticModelManagerException("obj file corrupt."); int first = fileIndeces.Count; for (int i = 1; i < parameters.Length; i++) { if (i > 3) { // Triangulate using the previous two verteces // NOTE: THIS MAY BE INCORRECT! I COULD NOT YET FIND DOCUMENTATION // ON THE TRIANGULATION DONE BY BLENDER (WORKS FOR QUADS AT LEAST) //// Last two (triangle strip) //fileIndeces.Add(fileIndeces[fileIndeces.Count - 6]); //fileIndeces.Add(fileIndeces[fileIndeces.Count - 6]); //fileIndeces.Add(fileIndeces[fileIndeces.Count - 6]); //fileIndeces.Add(fileIndeces[fileIndeces.Count - 6]); //fileIndeces.Add(fileIndeces[fileIndeces.Count - 6]); //fileIndeces.Add(fileIndeces[fileIndeces.Count - 6]); // First then previous (triangle fan) fileIndeces.Add(fileIndeces[first]); fileIndeces.Add(fileIndeces[first + 1]); fileIndeces.Add(fileIndeces[first + 2]); fileIndeces.Add(fileIndeces[fileIndeces.Count - 6]); fileIndeces.Add(fileIndeces[fileIndeces.Count - 6]); fileIndeces.Add(fileIndeces[fileIndeces.Count - 6]); } // Now include the new vertex string[] indexReferences = parameters[i].Split('/'); //if (indexReferences[0] == "") // throw new StaticModelManagerException("ERROR: obj file corrupted (missing vertex possition):" + filePath); fileIndeces.Add(int.Parse(indexReferences[0], CultureInfo.InvariantCulture)); if (hasNormals && indexReferences.Length < 3) { hasNormals = false; } if (hasTextureCoordinates && (indexReferences.Length < 2 || indexReferences[1] == "")) { hasTextureCoordinates = false; } if (hasTextureCoordinates && indexReferences[1] != "") { fileIndeces.Add(int.Parse(indexReferences[1], CultureInfo.InvariantCulture)); } else { fileIndeces.Add(0); } if (hasNormals && indexReferences[2] != "") { fileIndeces.Add(int.Parse(indexReferences[2], CultureInfo.InvariantCulture)); } else { fileIndeces.Add(0); } } break; } } catch { string[] pathSplit = filePath.Split('\\'); throw new StaticModelManagerException("Could not load model " + pathSplit[pathSplit.Length - 1] + ". There is a corruption on line " + lineNumber + "."); } lineNumber++; } } // Pull the final vertex order out of the indexed references // Note, arrays start at 0 but the index references start at 1 float[] verteces = new float[fileIndeces.Count]; for (int i = 0; i < fileIndeces.Count; i += 3) { int index = (fileIndeces[i] - 1) * 3; verteces[i] = fileVerteces[index]; verteces[i + 1] = fileVerteces[index + 1]; verteces[i + 2] = fileVerteces[index + 2]; } float[] textureCoordinates = null; if (hasTextureCoordinates) { // Pull the final texture coordinates order out of the indexed references // Note, arrays start at 0 but the index references start at 1 // Note, every other value needs to be inverse (not sure why but it works :P) textureCoordinates = new float[fileIndeces.Count / 3 * 2]; for (int i = 1; i < fileIndeces.Count; i += 3) { int index = (fileIndeces[i] - 1) * 2; int offset = (i - 1) / 3; textureCoordinates[i - 1 - offset] = fileTextureCoordinates[index]; textureCoordinates[i - offset] = 1 - fileTextureCoordinates[(index + 1)]; } } float[] normals = null; if (hasNormals) { // Pull the final normal order out of the indexed references // Note, arrays start at 0 but the index references start at 1 normals = new float[fileIndeces.Count]; for (int i = 2; i < fileIndeces.Count; i += 3) { int index = (fileIndeces[i] - 1) * 3; normals[i - 2] = fileNormals[index]; normals[i - 1] = fileNormals[(index + 1)]; normals[i] = fileNormals[(index + 2)]; } } int vertexBufferId; if (verteces != null) { // Make the vertex buffer on the GPU GL.GenBuffers(1, out vertexBufferId); GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBufferId); GL.BufferData <float>(BufferTarget.ArrayBuffer, (IntPtr)(verteces.Length * sizeof(float)), verteces, BufferUsageHint.StaticDraw); int bufferSize; GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out bufferSize); if (verteces.Length * sizeof(float) != bufferSize) { throw new StaticModelManagerException("Vertex array not uploaded correctly"); } // Deselect the new buffer GL.BindBuffer(BufferTarget.ArrayBuffer, 0); } else { vertexBufferId = 0; } int textureCoordinateBufferId; if (hasTextureCoordinates && textureCoordinates != null) { // Make the texture coordinate buffer on the GPU GL.GenBuffers(1, out textureCoordinateBufferId); GL.BindBuffer(BufferTarget.ArrayBuffer, textureCoordinateBufferId); GL.BufferData <float>(BufferTarget.ArrayBuffer, (IntPtr)(textureCoordinates.Length * sizeof(float)), textureCoordinates, BufferUsageHint.StaticDraw); int bufferSize; GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out bufferSize); if (textureCoordinates.Length * sizeof(float) != bufferSize) { throw new StaticModelManagerException("TexCoord array not uploaded correctly"); } // Deselect the new buffer GL.BindBuffer(BufferTarget.ArrayBuffer, 0); } else { textureCoordinateBufferId = 0; } int normalBufferId; if (hasNormals && normals != null) { // Make the normal buffer on the GPU GL.GenBuffers(1, out normalBufferId); GL.BindBuffer(BufferTarget.ArrayBuffer, normalBufferId); GL.BufferData <float>(BufferTarget.ArrayBuffer, (IntPtr)(normals.Length * sizeof(float)), normals, BufferUsageHint.StaticDraw); int bufferSize; GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out bufferSize); if (normals.Length * sizeof(float) != bufferSize) { throw new StaticModelManagerException("Normal array not uploaded correctly"); } // Deselect the new buffer GL.BindBuffer(BufferTarget.ArrayBuffer, 0); } else { normalBufferId = 0; } return(new StaticMesh( filePath, staticMeshId, vertexBufferId, 0, // Obj files don't support vertex colors textureCoordinateBufferId, normalBufferId, 0, // I don't support an index buffer at this time verteces.Length, null)); }
/// <summary>DONT USE THIS FUNCTION!!! This is an experimental file type I may use in the future.</summary> public static StaticModel LoadSevenModelFromDisk(string staticModelId, string filePath) { // These are temporarily needed lists for storing the parsed data as you read it. List_Array <float> fileVerteces = new List_Array <float>(1000); List_Array <float> fileNormals = new List_Array <float>(1000); List_Array <float> fileTextureCoordinates = new List_Array <float>(1000); List_Array <int> fileIndeces = new List_Array <int>(1000); Texture texture = null; string meshName = "defaultMeshName"; AvlTree <StaticMesh> meshes = new AvlTree_Linked <StaticMesh>(StaticMesh.CompareTo); // Lets read the file and handle each line separately for ".obj" files using (StreamReader reader = new StreamReader(filePath)) { while (!reader.EndOfStream) { string[] parameters = reader.ReadLine().Trim().Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); switch (parameters[0]) { // MeshName case "m": meshName = parameters[1]; break; // Texture case "t": if (!TextureManager.TextureExists(parameters[1])) { TextureManager.LoadTexture(parameters[1], parameters[2]); } texture = TextureManager.Get(parameters[1]); break; // Vertex case "v": fileVerteces.Add(float.Parse(parameters[1], CultureInfo.InvariantCulture)); fileVerteces.Add(float.Parse(parameters[2], CultureInfo.InvariantCulture)); fileVerteces.Add(float.Parse(parameters[3], CultureInfo.InvariantCulture)); break; // Texture Coordinate case "vt": fileTextureCoordinates.Add(float.Parse(parameters[1], CultureInfo.InvariantCulture)); fileTextureCoordinates.Add(float.Parse(parameters[2], CultureInfo.InvariantCulture)); break; // Normal case "vn": fileNormals.Add(float.Parse(parameters[1], CultureInfo.InvariantCulture)); fileNormals.Add(float.Parse(parameters[2], CultureInfo.InvariantCulture)); fileNormals.Add(float.Parse(parameters[3], CultureInfo.InvariantCulture)); break; // Face case "f": // DEVELOPMENT NOTE: The following triangulation algorithm works, but it // could be optimized beyond its current state. // The following variables are used for triangulation of a polygon // with greater than three verteces. int firstPosition, firstTextureCoordinates, firstNormal, secondPosition, secondTextureCoordinates, secondNormal; if (parameters.Length > 3) { // First Vertex (we have to store it this way for possible triangulation) string[] indexReferences = parameters[1].Split('/'); if (indexReferences[0] == "") { throw new StaticModelManagerException("ERROR: obj file corrupted (missing vertex possition): " + filePath); } firstPosition = int.Parse(indexReferences[0], CultureInfo.InvariantCulture); if (indexReferences[1] != "") { firstTextureCoordinates = int.Parse(indexReferences[1], CultureInfo.InvariantCulture); } else { firstTextureCoordinates = 0; } if (indexReferences[2] != "") { firstNormal = int.Parse(indexReferences[2], CultureInfo.InvariantCulture); } else { firstNormal = 0; } // Second Vertex (we have to store it this way for possible triangulation) indexReferences = parameters[2].Split('/'); if (indexReferences[0] == "") { throw new StaticModelManagerException("ERROR: obj file corrupted (missing vertex possition): " + filePath); } secondPosition = int.Parse(indexReferences[0], CultureInfo.InvariantCulture); if (indexReferences[1] != "") { secondTextureCoordinates = int.Parse(indexReferences[1], CultureInfo.InvariantCulture); } else { secondTextureCoordinates = 0; } if (indexReferences[2] != "") { secondNormal = int.Parse(indexReferences[2], CultureInfo.InvariantCulture); } else { secondNormal = 0; } } else { throw new StaticModelManagerException("ERROR: obj file corrupted:" + filePath); } // Verteces past the first two for (int i = 3; i < parameters.Length; i++) { // Triangulate using the first two verteces fileIndeces.Add(firstPosition); fileIndeces.Add(firstTextureCoordinates); fileIndeces.Add(firstNormal); fileIndeces.Add(secondPosition); fileIndeces.Add(secondTextureCoordinates); fileIndeces.Add(secondNormal); // Now include the new vertex string[] indexReferences = parameters[i].Split('/'); if (indexReferences[0] == "") { throw new StaticModelManagerException("ERROR: obj file corrupted (missing vertex possition): " + filePath); } fileIndeces.Add(int.Parse(indexReferences[0], CultureInfo.InvariantCulture)); if (indexReferences[1] != "") { fileIndeces.Add(int.Parse(indexReferences[1], CultureInfo.InvariantCulture)); } else { fileIndeces.Add(0); } if (indexReferences[2] != "") { fileIndeces.Add(int.Parse(indexReferences[2], CultureInfo.InvariantCulture)); } else { fileIndeces.Add(0); } } break; //// OLD VERSION OF THE FACE PARSING //// NOTE! This does not yet triangulate faces //// NOTE! This needs all possible values (position, texture mapping, and normal). //for (int i = 1; i < parameters.Length; i++) //{ // string[] indexReferences = parameters[i].Split('/'); // fileIndeces.Add(int.Parse(indexReferences[0], CultureInfo.InvariantCulture)); // if (indexReferences[1] != "") // fileIndeces.Add(int.Parse(indexReferences[1], CultureInfo.InvariantCulture)); // else // fileIndeces.Add(0); // if (indexReferences[2] != "") // fileIndeces.Add(int.Parse(indexReferences[2], CultureInfo.InvariantCulture)); // else // fileIndeces.Add(0); //} //break; // End Current Mesh case "7": // Pull the final vertex order out of the indexed references // Note, arrays start at 0 but the index references start at 1 float[] verteces = new float[fileIndeces.Count]; for (int i = 0; i < fileIndeces.Count; i += 3) { int index = (fileIndeces[i] - 1) * 3; verteces[i] = fileVerteces[index]; verteces[i + 1] = fileVerteces[index + 1]; verteces[i + 2] = fileVerteces[index + 2]; } // Pull the final texture coordinates order out of the indexed references // Note, arrays start at 0 but the index references start at 1 // Note, every other value needs to be inverse (not sure why but it works :P) float[] textureCoordinates = new float[fileIndeces.Count / 3 * 2]; for (int i = 1; i < fileIndeces.Count; i += 3) { int index = (fileIndeces[i] - 1) * 2; int offset = (i - 1) / 3; textureCoordinates[i - 1 - offset] = fileTextureCoordinates[index]; textureCoordinates[i - offset] = 1 - fileTextureCoordinates[(index + 1)]; } // Pull the final normal order out of the indexed references // Note, arrays start at 0 but the index references start at 1 float[] normals = new float[fileIndeces.Count]; for (int i = 2; i < fileIndeces.Count; i += 3) { int index = (fileIndeces[i] - 1) * 3; normals[i - 2] = fileNormals[index]; normals[i - 1] = fileNormals[(index + 1)]; normals[i] = fileNormals[(index + 2)]; } int vertexBufferId; if (verteces != null) { // Declare the buffer GL.GenBuffers(1, out vertexBufferId); // Select the new buffer GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBufferId); // Initialize the buffer values GL.BufferData <float>(BufferTarget.ArrayBuffer, (IntPtr)(verteces.Length * sizeof(float)), verteces, BufferUsageHint.StaticDraw); // Quick error checking int bufferSize; GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out bufferSize); if (verteces.Length * sizeof(float) != bufferSize) { throw new StaticModelManagerException("Vertex array not uploaded correctly"); } // Deselect the new buffer GL.BindBuffer(BufferTarget.ArrayBuffer, 0); } else { vertexBufferId = 0; } int textureCoordinateBufferId; if (textureCoordinates != null) { // Declare the buffer GL.GenBuffers(1, out textureCoordinateBufferId); // Select the new buffer GL.BindBuffer(BufferTarget.ArrayBuffer, textureCoordinateBufferId); // Initialize the buffer values GL.BufferData <float>(BufferTarget.ArrayBuffer, (IntPtr)(textureCoordinates.Length * sizeof(float)), textureCoordinates, BufferUsageHint.StaticDraw); // Quick error checking int bufferSize; GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out bufferSize); if (textureCoordinates.Length * sizeof(float) != bufferSize) { throw new StaticModelManagerException("TexCoord array not uploaded correctly"); } // Deselect the new buffer GL.BindBuffer(BufferTarget.ArrayBuffer, 0); } else { textureCoordinateBufferId = 0; } int normalBufferId; if (normals != null) { // Declare the buffer GL.GenBuffers(1, out normalBufferId); // Select the new buffer GL.BindBuffer(BufferTarget.ArrayBuffer, normalBufferId); // Initialize the buffer values GL.BufferData <float>(BufferTarget.ArrayBuffer, (IntPtr)(normals.Length * sizeof(float)), normals, BufferUsageHint.StaticDraw); // Quick error checking int bufferSize; GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out bufferSize); if (normals.Length * sizeof(float) != bufferSize) { throw new StaticModelManagerException("Normal array not uploaded correctly"); } // Deselect the new buffer GL.BindBuffer(BufferTarget.ArrayBuffer, 0); } else { normalBufferId = 0; } meshes.Add( new StaticMesh( meshName, staticModelId + "sub" + meshes.Count, vertexBufferId, 0, // Obj files don't support vertex colors textureCoordinateBufferId, normalBufferId, 0, // I don't support an index buffer at this time verteces.Length, texture)); fileVerteces.Clear(); fileNormals.Clear(); fileTextureCoordinates.Clear(); fileIndeces.Clear(); texture = null; break; } } } return(new StaticModel(staticModelId, meshes)); }
/// <summary>DONT USE THIS FUNCTION!!! This is an experimental file type I may use in the future.</summary> public static StaticModel LoadSevenModelFromDisk(string staticModelId, string filePath) { // These are temporarily needed lists for storing the parsed data as you read it. List_Array<float> fileVerteces = new List_Array<float>(1000); List_Array<float> fileNormals = new List_Array<float>(1000); List_Array<float> fileTextureCoordinates = new List_Array<float>(1000); List_Array<int> fileIndeces = new List_Array<int>(1000); Texture texture = null; string meshName = "defaultMeshName"; AvlTree<StaticMesh> meshes = new AvlTree_Linked<StaticMesh>(StaticMesh.CompareTo); // Lets read the file and handle each line separately for ".obj" files using (StreamReader reader = new StreamReader(filePath)) { while (!reader.EndOfStream) { string[] parameters = reader.ReadLine().Trim().Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); switch (parameters[0]) { // MeshName case "m": meshName = parameters[1]; break; // Texture case "t": if (!TextureManager.TextureExists(parameters[1])) TextureManager.LoadTexture(parameters[1], parameters[2]); texture = TextureManager.Get(parameters[1]); break; // Vertex case "v": fileVerteces.Add(float.Parse(parameters[1], CultureInfo.InvariantCulture)); fileVerteces.Add(float.Parse(parameters[2], CultureInfo.InvariantCulture)); fileVerteces.Add(float.Parse(parameters[3], CultureInfo.InvariantCulture)); break; // Texture Coordinate case "vt": fileTextureCoordinates.Add(float.Parse(parameters[1], CultureInfo.InvariantCulture)); fileTextureCoordinates.Add(float.Parse(parameters[2], CultureInfo.InvariantCulture)); break; // Normal case "vn": fileNormals.Add(float.Parse(parameters[1], CultureInfo.InvariantCulture)); fileNormals.Add(float.Parse(parameters[2], CultureInfo.InvariantCulture)); fileNormals.Add(float.Parse(parameters[3], CultureInfo.InvariantCulture)); break; // Face case "f": // DEVELOPMENT NOTE: The following triangulation algorithm works, but it // could be optimized beyond its current state. // The following variables are used for triangulation of a polygon // with greater than three verteces. int firstPosition, firstTextureCoordinates, firstNormal, secondPosition, secondTextureCoordinates, secondNormal; if (parameters.Length > 3) { // First Vertex (we have to store it this way for possible triangulation) string[] indexReferences = parameters[1].Split('/'); if (indexReferences[0] == "") throw new StaticModelManagerException("ERROR: obj file corrupted (missing vertex possition): " + filePath); firstPosition = int.Parse(indexReferences[0], CultureInfo.InvariantCulture); if (indexReferences[1] != "") firstTextureCoordinates = int.Parse(indexReferences[1], CultureInfo.InvariantCulture); else firstTextureCoordinates = 0; if (indexReferences[2] != "") firstNormal = int.Parse(indexReferences[2], CultureInfo.InvariantCulture); else firstNormal = 0; // Second Vertex (we have to store it this way for possible triangulation) indexReferences = parameters[2].Split('/'); if (indexReferences[0] == "") throw new StaticModelManagerException("ERROR: obj file corrupted (missing vertex possition): " + filePath); secondPosition = int.Parse(indexReferences[0], CultureInfo.InvariantCulture); if (indexReferences[1] != "") secondTextureCoordinates = int.Parse(indexReferences[1], CultureInfo.InvariantCulture); else secondTextureCoordinates = 0; if (indexReferences[2] != "") secondNormal = int.Parse(indexReferences[2], CultureInfo.InvariantCulture); else secondNormal = 0; } else throw new StaticModelManagerException("ERROR: obj file corrupted:" + filePath); // Verteces past the first two for (int i = 3; i < parameters.Length; i++) { // Triangulate using the first two verteces fileIndeces.Add(firstPosition); fileIndeces.Add(firstTextureCoordinates); fileIndeces.Add(firstNormal); fileIndeces.Add(secondPosition); fileIndeces.Add(secondTextureCoordinates); fileIndeces.Add(secondNormal); // Now include the new vertex string[] indexReferences = parameters[i].Split('/'); if (indexReferences[0] == "") throw new StaticModelManagerException("ERROR: obj file corrupted (missing vertex possition): " + filePath); fileIndeces.Add(int.Parse(indexReferences[0], CultureInfo.InvariantCulture)); if (indexReferences[1] != "") fileIndeces.Add(int.Parse(indexReferences[1], CultureInfo.InvariantCulture)); else fileIndeces.Add(0); if (indexReferences[2] != "") fileIndeces.Add(int.Parse(indexReferences[2], CultureInfo.InvariantCulture)); else fileIndeces.Add(0); } break; //// OLD VERSION OF THE FACE PARSING //// NOTE! This does not yet triangulate faces //// NOTE! This needs all possible values (position, texture mapping, and normal). //for (int i = 1; i < parameters.Length; i++) //{ // string[] indexReferences = parameters[i].Split('/'); // fileIndeces.Add(int.Parse(indexReferences[0], CultureInfo.InvariantCulture)); // if (indexReferences[1] != "") // fileIndeces.Add(int.Parse(indexReferences[1], CultureInfo.InvariantCulture)); // else // fileIndeces.Add(0); // if (indexReferences[2] != "") // fileIndeces.Add(int.Parse(indexReferences[2], CultureInfo.InvariantCulture)); // else // fileIndeces.Add(0); //} //break; // End Current Mesh case "7": // Pull the final vertex order out of the indexed references // Note, arrays start at 0 but the index references start at 1 float[] verteces = new float[fileIndeces.Count]; for (int i = 0; i < fileIndeces.Count; i += 3) { int index = (fileIndeces[i] - 1) * 3; verteces[i] = fileVerteces[index]; verteces[i + 1] = fileVerteces[index + 1]; verteces[i + 2] = fileVerteces[index + 2]; } // Pull the final texture coordinates order out of the indexed references // Note, arrays start at 0 but the index references start at 1 // Note, every other value needs to be inverse (not sure why but it works :P) float[] textureCoordinates = new float[fileIndeces.Count / 3 * 2]; for (int i = 1; i < fileIndeces.Count; i += 3) { int index = (fileIndeces[i] - 1) * 2; int offset = (i - 1) / 3; textureCoordinates[i - 1 - offset] = fileTextureCoordinates[index]; textureCoordinates[i - offset] = 1 - fileTextureCoordinates[(index + 1)]; } // Pull the final normal order out of the indexed references // Note, arrays start at 0 but the index references start at 1 float[] normals = new float[fileIndeces.Count]; for (int i = 2; i < fileIndeces.Count; i += 3) { int index = (fileIndeces[i] - 1) * 3; normals[i - 2] = fileNormals[index]; normals[i - 1] = fileNormals[(index + 1)]; normals[i] = fileNormals[(index + 2)]; } int vertexBufferId; if (verteces != null) { // Declare the buffer GL.GenBuffers(1, out vertexBufferId); // Select the new buffer GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBufferId); // Initialize the buffer values GL.BufferData<float>(BufferTarget.ArrayBuffer, (IntPtr)(verteces.Length * sizeof(float)), verteces, BufferUsageHint.StaticDraw); // Quick error checking int bufferSize; GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out bufferSize); if (verteces.Length * sizeof(float) != bufferSize) throw new StaticModelManagerException("Vertex array not uploaded correctly"); // Deselect the new buffer GL.BindBuffer(BufferTarget.ArrayBuffer, 0); } else { vertexBufferId = 0; } int textureCoordinateBufferId; if (textureCoordinates != null) { // Declare the buffer GL.GenBuffers(1, out textureCoordinateBufferId); // Select the new buffer GL.BindBuffer(BufferTarget.ArrayBuffer, textureCoordinateBufferId); // Initialize the buffer values GL.BufferData<float>(BufferTarget.ArrayBuffer, (IntPtr)(textureCoordinates.Length * sizeof(float)), textureCoordinates, BufferUsageHint.StaticDraw); // Quick error checking int bufferSize; GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out bufferSize); if (textureCoordinates.Length * sizeof(float) != bufferSize) throw new StaticModelManagerException("TexCoord array not uploaded correctly"); // Deselect the new buffer GL.BindBuffer(BufferTarget.ArrayBuffer, 0); } else { textureCoordinateBufferId = 0; } int normalBufferId; if (normals != null) { // Declare the buffer GL.GenBuffers(1, out normalBufferId); // Select the new buffer GL.BindBuffer(BufferTarget.ArrayBuffer, normalBufferId); // Initialize the buffer values GL.BufferData<float>(BufferTarget.ArrayBuffer, (IntPtr)(normals.Length * sizeof(float)), normals, BufferUsageHint.StaticDraw); // Quick error checking int bufferSize; GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out bufferSize); if (normals.Length * sizeof(float) != bufferSize) throw new StaticModelManagerException("Normal array not uploaded correctly"); // Deselect the new buffer GL.BindBuffer(BufferTarget.ArrayBuffer, 0); } else { normalBufferId = 0; } meshes.Add( new StaticMesh( meshName, staticModelId + "sub" + meshes.Count, vertexBufferId, 0, // Obj files don't support vertex colors textureCoordinateBufferId, normalBufferId, 0, // I don't support an index buffer at this time verteces.Length, texture)); fileVerteces.Clear(); fileNormals.Clear(); fileTextureCoordinates.Clear(); fileIndeces.Clear(); texture = null; break; } } } return new StaticModel(staticModelId, meshes); }
private static StaticMesh LoadObj(string staticMeshId, string filePath) { // These are temporarily needed lists for storing the parsed data as you read it. // Its better to use "ListArrays" vs "Lists" because they will be accessed by indeces // by the faces of the obj file. List_Array<float> fileVerteces = new List_Array<float>(10000); List_Array<float> fileNormals = new List_Array<float>(10000); List_Array<float> fileTextureCoordinates = new List_Array<float>(10000); List_Array<int> fileIndeces = new List_Array<int>(10000); // Obj files are not required to include texture coordinates or normals bool hasTextureCoordinates = true; bool hasNormals = true; // Lets read the file and handle each line separately for ".obj" files using (StreamReader reader = new StreamReader(filePath)) { int lineNumber = 1; while (!reader.EndOfStream) { try { string[] parameters = reader.ReadLine().Trim().Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); switch (parameters[0]) { // Vertex case "v": fileVerteces.Add(float.Parse(parameters[1], CultureInfo.InvariantCulture)); fileVerteces.Add(float.Parse(parameters[2], CultureInfo.InvariantCulture)); fileVerteces.Add(float.Parse(parameters[3], CultureInfo.InvariantCulture)); break; // Texture Coordinate case "vt": fileTextureCoordinates.Add(float.Parse(parameters[1], CultureInfo.InvariantCulture)); fileTextureCoordinates.Add(float.Parse(parameters[2], CultureInfo.InvariantCulture)); break; // Normal case "vn": fileNormals.Add(float.Parse(parameters[1], CultureInfo.InvariantCulture)); fileNormals.Add(float.Parse(parameters[2], CultureInfo.InvariantCulture)); fileNormals.Add(float.Parse(parameters[3], CultureInfo.InvariantCulture)); break; // Face case "f": //if (parameters.Length < 4) // throw new StaticModelManagerException("obj file corrupt."); int first = fileIndeces.Count; for (int i = 1; i < parameters.Length; i++) { if (i > 3) { // Triangulate using the previous two verteces // NOTE: THIS MAY BE INCORRECT! I COULD NOT YET FIND DOCUMENTATION // ON THE TRIANGULATION DONE BY BLENDER (WORKS FOR QUADS AT LEAST) //// Last two (triangle strip) //fileIndeces.Add(fileIndeces[fileIndeces.Count - 6]); //fileIndeces.Add(fileIndeces[fileIndeces.Count - 6]); //fileIndeces.Add(fileIndeces[fileIndeces.Count - 6]); //fileIndeces.Add(fileIndeces[fileIndeces.Count - 6]); //fileIndeces.Add(fileIndeces[fileIndeces.Count - 6]); //fileIndeces.Add(fileIndeces[fileIndeces.Count - 6]); // First then previous (triangle fan) fileIndeces.Add(fileIndeces[first]); fileIndeces.Add(fileIndeces[first + 1]); fileIndeces.Add(fileIndeces[first + 2]); fileIndeces.Add(fileIndeces[fileIndeces.Count - 6]); fileIndeces.Add(fileIndeces[fileIndeces.Count - 6]); fileIndeces.Add(fileIndeces[fileIndeces.Count - 6]); } // Now include the new vertex string[] indexReferences = parameters[i].Split('/'); //if (indexReferences[0] == "") // throw new StaticModelManagerException("ERROR: obj file corrupted (missing vertex possition):" + filePath); fileIndeces.Add(int.Parse(indexReferences[0], CultureInfo.InvariantCulture)); if (hasNormals && indexReferences.Length < 3) hasNormals = false; if (hasTextureCoordinates && (indexReferences.Length < 2 || indexReferences[1] == "")) hasTextureCoordinates = false; if (hasTextureCoordinates && indexReferences[1] != "") fileIndeces.Add(int.Parse(indexReferences[1], CultureInfo.InvariantCulture)); else fileIndeces.Add(0); if (hasNormals && indexReferences[2] != "") fileIndeces.Add(int.Parse(indexReferences[2], CultureInfo.InvariantCulture)); else fileIndeces.Add(0); } break; } } catch { string[] pathSplit = filePath.Split('\\'); throw new StaticModelManagerException("Could not load model " + pathSplit[pathSplit.Length - 1] + ". There is a corruption on line " + lineNumber +"."); } lineNumber++; } } // Pull the final vertex order out of the indexed references // Note, arrays start at 0 but the index references start at 1 float[] verteces = new float[fileIndeces.Count]; for (int i = 0; i < fileIndeces.Count; i += 3) { int index = (fileIndeces[i] - 1) * 3; verteces[i] = fileVerteces[index]; verteces[i + 1] = fileVerteces[index + 1]; verteces[i + 2] = fileVerteces[index + 2]; } float[] textureCoordinates = null; if (hasTextureCoordinates) { // Pull the final texture coordinates order out of the indexed references // Note, arrays start at 0 but the index references start at 1 // Note, every other value needs to be inverse (not sure why but it works :P) textureCoordinates = new float[fileIndeces.Count / 3 * 2]; for (int i = 1; i < fileIndeces.Count; i += 3) { int index = (fileIndeces[i] - 1) * 2; int offset = (i - 1) / 3; textureCoordinates[i - 1 - offset] = fileTextureCoordinates[index]; textureCoordinates[i - offset] = 1 - fileTextureCoordinates[(index + 1)]; } } float[] normals = null; if (hasNormals) { // Pull the final normal order out of the indexed references // Note, arrays start at 0 but the index references start at 1 normals = new float[fileIndeces.Count]; for (int i = 2; i < fileIndeces.Count; i += 3) { int index = (fileIndeces[i] - 1) * 3; normals[i - 2] = fileNormals[index]; normals[i - 1] = fileNormals[(index + 1)]; normals[i] = fileNormals[(index + 2)]; } } int vertexBufferId; if (verteces != null) { // Make the vertex buffer on the GPU GL.GenBuffers(1, out vertexBufferId); GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBufferId); GL.BufferData<float>(BufferTarget.ArrayBuffer, (IntPtr)(verteces.Length * sizeof(float)), verteces, BufferUsageHint.StaticDraw); int bufferSize; GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out bufferSize); if (verteces.Length * sizeof(float) != bufferSize) throw new StaticModelManagerException("Vertex array not uploaded correctly"); // Deselect the new buffer GL.BindBuffer(BufferTarget.ArrayBuffer, 0); } else { vertexBufferId = 0; } int textureCoordinateBufferId; if (hasTextureCoordinates && textureCoordinates != null) { // Make the texture coordinate buffer on the GPU GL.GenBuffers(1, out textureCoordinateBufferId); GL.BindBuffer(BufferTarget.ArrayBuffer, textureCoordinateBufferId); GL.BufferData<float>(BufferTarget.ArrayBuffer, (IntPtr)(textureCoordinates.Length * sizeof(float)), textureCoordinates, BufferUsageHint.StaticDraw); int bufferSize; GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out bufferSize); if (textureCoordinates.Length * sizeof(float) != bufferSize) throw new StaticModelManagerException("TexCoord array not uploaded correctly"); // Deselect the new buffer GL.BindBuffer(BufferTarget.ArrayBuffer, 0); } else { textureCoordinateBufferId = 0; } int normalBufferId; if (hasNormals && normals != null) { // Make the normal buffer on the GPU GL.GenBuffers(1, out normalBufferId); GL.BindBuffer(BufferTarget.ArrayBuffer, normalBufferId); GL.BufferData<float>(BufferTarget.ArrayBuffer, (IntPtr)(normals.Length * sizeof(float)), normals, BufferUsageHint.StaticDraw); int bufferSize; GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out bufferSize); if (normals.Length * sizeof(float) != bufferSize) throw new StaticModelManagerException("Normal array not uploaded correctly"); // Deselect the new buffer GL.BindBuffer(BufferTarget.ArrayBuffer, 0); } else { normalBufferId = 0; } return new StaticMesh( filePath, staticMeshId, vertexBufferId, 0, // Obj files don't support vertex colors textureCoordinateBufferId, normalBufferId, 0, // I don't support an index buffer at this time verteces.Length, null); }
internal void AddKearning(int followingCharacter, int ammount) { _kearnings.Add(new Link <int, int>(followingCharacter, ammount)); }
public static void LoadFontFile(string id, string filePath, string textureLocations) { List_Array<CharacterSprite> characters = new List_Array<CharacterSprite>(255); List_Array<string> textures = new List_Array<string>(1); int lineHeight = -1, fontBase = int.MinValue; using (StreamReader reader = new StreamReader(filePath)) { int lineNumber = 1; while (!reader.EndOfStream) { string line = reader.ReadLine(); string[] parameters = line.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); switch (parameters[0].ToLower()) { case "common": for (int i = 1; i < parameters.Length; i++) { string[] attributes = parameters[i].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); switch (attributes[0].ToLower()) { case "lineheight": if (!int.TryParse(attributes[1], out lineHeight)) throw new TextManagerException("The line height value of the font file is corrupt on line " + lineNumber + "."); break; case "base": if (!int.TryParse(attributes[1], out fontBase)) throw new TextManagerException("The base value of the font file is corrupt on line " + lineNumber + "."); break; } } break; case "page": string[] textureFile = parameters[2].Split("\"".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); try { TextureManager.LoadTexture(textureFile[1], textureLocations + textureFile[1]); } catch { throw new TextManagerException("The font file is using a non-supported image file on line " + lineNumber + "."); } textures.Add(textureFile[1]); break; case "char": int charId = -1, x = -1, y = -1, width = -1, height = -1, xOffset = int.MinValue, yOffset = int.MinValue, xAdvance = -1, page = -1; // channel=-1; // Lets get all the attributes of the character for (int i = 1; i < parameters.Length; i++) { string[] attribute = parameters[i].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); if (attribute.Length < 2) throw new TextManagerException("Font file has a corrupted character attribute on line " + lineNumber + "."); switch (attribute[0].ToLower()) { case "id": if (!int.TryParse(attribute[1], out charId)) throw new TextManagerException("An id value in font file is corrupted on line " + lineNumber + "."); break; case "x": if (!int.TryParse(attribute[1], out x)) throw new TextManagerException("A x value in font file is corrupted on line " + lineNumber + "."); break; case "y": if (!int.TryParse(attribute[1], out y)) throw new TextManagerException("A y value in font file is corrupted on line " + lineNumber + "."); break; case "width": if (!int.TryParse(attribute[1], out width)) throw new TextManagerException("A width value in font file is corrupted on line " + lineNumber + "."); break; case "height": if (!int.TryParse(attribute[1], out height)) throw new TextManagerException("A height value in font file is corrupted on line " + lineNumber + "."); break; case "xoffset": if (!int.TryParse(attribute[1], out xOffset)) throw new TextManagerException("A xoffset value in font file is corrupted on line " + lineNumber + "."); break; case "yoffset": if (!int.TryParse(attribute[1], out yOffset)) throw new TextManagerException("A yoffset value in font file is corrupted on line " + lineNumber + "."); break; case "xadvance": if (!int.TryParse(attribute[1], out xAdvance)) throw new TextManagerException("A xadvance value in font file is corrupted on line " + lineNumber + "."); break; case "page": if (!int.TryParse(attribute[1], out page)) throw new TextManagerException("A page value in font file is corrupted on line " + lineNumber + "."); break; //// This check is most likely unnecessary, an error will be thrown during image loading attempt. //case "chnl": // if (!int.TryParse(attribute[1], out channel)) // throw new TextManagerException("A chnl value in font file is corrupted on line " + lineNumber + "."); // if (channel != 15) // throw new TextManagerException("The font file is using a non-supported image file."); } } // Make sure all the necessary values were imported and are valid if (charId == -1) throw new TextManagerException("Font file is corrupt/missing on a char id on line " + lineNumber + "."); if (x < 0) throw new TextManagerException("Font file has corrupt/missing on x value on line " + lineNumber + "."); if (y < 0) throw new TextManagerException("Font file has a corrupt/missing y value on line " + lineNumber + "."); if (width < 0) throw new TextManagerException("Font file has a corrupt/missing width value on line " + lineNumber + "."); if (height == -1) throw new TextManagerException("Font file has a corrupt/missing height value on line " + lineNumber + "."); if (xOffset == int.MinValue) throw new TextManagerException("Font file is missing a xoffset value on line " + lineNumber + "."); if (yOffset == int.MinValue) throw new TextManagerException("Font file is missing a yoffset value on line " + lineNumber + "."); if (xAdvance < 0) throw new TextManagerException("Font file has a corrupt/missing xadvance value on line " + lineNumber + "."); if (page < 0 || page > textures.Count) throw new TextManagerException("Font file has a corrupt/missing page value on line " + lineNumber + "."); //// This check is most likely unnecessary, an error will be thrown during image loading attempt. //if (channel == -1) // throw new TextManagerException("Font file is missing a channel value on line " + lineNumber + "."); characters.Add( new CharacterSprite( TextureManager.Get(textures[page]), charId, xAdvance, x, y, width, height, xOffset, yOffset)); break; #region OLD CODE (I'll delete this when I'm done debugging the newer version) // THIS WAS MY INITIAL PARSER JUST TO GET THINGS WORKING // characters.Add(new CharacterSprite( // // Texture // TextureManager.Get(textures[int.Parse(parameters[9].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture)]), // // Id // int.Parse(parameters[1].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture), // // X Advance // int.Parse(parameters[8].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture), // // X // int.Parse(parameters[2].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture), // // Y // int.Parse(parameters[3].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture), // // Width // int.Parse(parameters[4].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture), // // Height // int.Parse(parameters[5].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture), // // X Offset // int.Parse(parameters[6].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture), // // Y Offset // int.Parse(parameters[7].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture))); // break; //case "kerning": // int first = int.Parse(parameters[1].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture); // for (int i = 0; i < characters.Count; i++) // if (characters[i].Id == first) // characters[i].AddKearning( // int.Parse(parameters[2].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture), // int.Parse(parameters[3].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture)); // break; #endregion } lineNumber++; } } if (lineHeight < 0) throw new TextManagerException("Font file has a corrupt/missing line height value."); _fontDatabase.Add(new Font(id, lineHeight, fontBase, characters)); string[] pathSplit = filePath.Split('\\'); Output.WriteLine("Font file loaded: \"" + pathSplit[pathSplit.Length - 1] + "\"."); }
public static void LoadFontFile(string id, string filePath, string textureLocations) { List_Array <CharacterSprite> characters = new List_Array <CharacterSprite>(255); List_Array <string> textures = new List_Array <string>(1); int lineHeight = -1, fontBase = int.MinValue; using (StreamReader reader = new StreamReader(filePath)) { int lineNumber = 1; while (!reader.EndOfStream) { string line = reader.ReadLine(); string[] parameters = line.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); switch (parameters[0].ToLower()) { case "common": for (int i = 1; i < parameters.Length; i++) { string[] attributes = parameters[i].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); switch (attributes[0].ToLower()) { case "lineheight": if (!int.TryParse(attributes[1], out lineHeight)) { throw new TextManagerException("The line height value of the font file is corrupt on line " + lineNumber + "."); } break; case "base": if (!int.TryParse(attributes[1], out fontBase)) { throw new TextManagerException("The base value of the font file is corrupt on line " + lineNumber + "."); } break; } } break; case "page": string[] textureFile = parameters[2].Split("\"".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); try { TextureManager.LoadTexture(textureFile[1], textureLocations + textureFile[1]); } catch { throw new TextManagerException("The font file is using a non-supported image file on line " + lineNumber + "."); } textures.Add(textureFile[1]); break; case "char": int charId = -1, x = -1, y = -1, width = -1, height = -1, xOffset = int.MinValue, yOffset = int.MinValue, xAdvance = -1, page = -1; // channel=-1; // Lets get all the attributes of the character for (int i = 1; i < parameters.Length; i++) { string[] attribute = parameters[i].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); if (attribute.Length < 2) { throw new TextManagerException("Font file has a corrupted character attribute on line " + lineNumber + "."); } switch (attribute[0].ToLower()) { case "id": if (!int.TryParse(attribute[1], out charId)) { throw new TextManagerException("An id value in font file is corrupted on line " + lineNumber + "."); } break; case "x": if (!int.TryParse(attribute[1], out x)) { throw new TextManagerException("A x value in font file is corrupted on line " + lineNumber + "."); } break; case "y": if (!int.TryParse(attribute[1], out y)) { throw new TextManagerException("A y value in font file is corrupted on line " + lineNumber + "."); } break; case "width": if (!int.TryParse(attribute[1], out width)) { throw new TextManagerException("A width value in font file is corrupted on line " + lineNumber + "."); } break; case "height": if (!int.TryParse(attribute[1], out height)) { throw new TextManagerException("A height value in font file is corrupted on line " + lineNumber + "."); } break; case "xoffset": if (!int.TryParse(attribute[1], out xOffset)) { throw new TextManagerException("A xoffset value in font file is corrupted on line " + lineNumber + "."); } break; case "yoffset": if (!int.TryParse(attribute[1], out yOffset)) { throw new TextManagerException("A yoffset value in font file is corrupted on line " + lineNumber + "."); } break; case "xadvance": if (!int.TryParse(attribute[1], out xAdvance)) { throw new TextManagerException("A xadvance value in font file is corrupted on line " + lineNumber + "."); } break; case "page": if (!int.TryParse(attribute[1], out page)) { throw new TextManagerException("A page value in font file is corrupted on line " + lineNumber + "."); } break; //// This check is most likely unnecessary, an error will be thrown during image loading attempt. //case "chnl": // if (!int.TryParse(attribute[1], out channel)) // throw new TextManagerException("A chnl value in font file is corrupted on line " + lineNumber + "."); // if (channel != 15) // throw new TextManagerException("The font file is using a non-supported image file."); } } // Make sure all the necessary values were imported and are valid if (charId == -1) { throw new TextManagerException("Font file is corrupt/missing on a char id on line " + lineNumber + "."); } if (x < 0) { throw new TextManagerException("Font file has corrupt/missing on x value on line " + lineNumber + "."); } if (y < 0) { throw new TextManagerException("Font file has a corrupt/missing y value on line " + lineNumber + "."); } if (width < 0) { throw new TextManagerException("Font file has a corrupt/missing width value on line " + lineNumber + "."); } if (height == -1) { throw new TextManagerException("Font file has a corrupt/missing height value on line " + lineNumber + "."); } if (xOffset == int.MinValue) { throw new TextManagerException("Font file is missing a xoffset value on line " + lineNumber + "."); } if (yOffset == int.MinValue) { throw new TextManagerException("Font file is missing a yoffset value on line " + lineNumber + "."); } if (xAdvance < 0) { throw new TextManagerException("Font file has a corrupt/missing xadvance value on line " + lineNumber + "."); } if (page < 0 || page > textures.Count) { throw new TextManagerException("Font file has a corrupt/missing page value on line " + lineNumber + "."); } //// This check is most likely unnecessary, an error will be thrown during image loading attempt. //if (channel == -1) // throw new TextManagerException("Font file is missing a channel value on line " + lineNumber + "."); characters.Add( new CharacterSprite( TextureManager.Get(textures[page]), charId, xAdvance, x, y, width, height, xOffset, yOffset)); break; #region OLD CODE (I'll delete this when I'm done debugging the newer version) // THIS WAS MY INITIAL PARSER JUST TO GET THINGS WORKING // characters.Add(new CharacterSprite( // // Texture // TextureManager.Get(textures[int.Parse(parameters[9].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture)]), // // Id // int.Parse(parameters[1].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture), // // X Advance // int.Parse(parameters[8].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture), // // X // int.Parse(parameters[2].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture), // // Y // int.Parse(parameters[3].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture), // // Width // int.Parse(parameters[4].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture), // // Height // int.Parse(parameters[5].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture), // // X Offset // int.Parse(parameters[6].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture), // // Y Offset // int.Parse(parameters[7].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture))); // break; //case "kerning": // int first = int.Parse(parameters[1].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture); // for (int i = 0; i < characters.Count; i++) // if (characters[i].Id == first) // characters[i].AddKearning( // int.Parse(parameters[2].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture), // int.Parse(parameters[3].Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1], CultureInfo.InvariantCulture)); // break; #endregion } lineNumber++; } } if (lineHeight < 0) { throw new TextManagerException("Font file has a corrupt/missing line height value."); } _fontDatabase.Add(new Font(id, lineHeight, fontBase, characters)); string[] pathSplit = filePath.Split('\\'); Output.WriteLine("Font file loaded: \"" + pathSplit[pathSplit.Length - 1] + "\"."); }