/// <summary> /// http://en.wikipedia.org/wiki/Wavefront_.obj_file /// </summary> /// <param name="filename"></param> /// <returns></returns> public static Mesh LoadObjFile(string filename) { var file = Filepaths.GetModelFileInfo(filename); if (!file.Exists) throw new ModelException(StandardExceptions.NewFileNotFound(file)); string src; using (var s = new StreamReader(file.FullName)) { src = s.ReadToEnd(); } var lines = src.Split('\n').Where(s => !s.StartsWith("#")).ToList(); var vertexs = new List<Vector3>(); var vertexTextures = new List<Vector2>(); var vertexNormals = new List<Vector3>(); foreach ( var xyzw in lines.Where(s => s.StartsWith("v ")) .Select(s => s.Substring(s.IndexOf(' ') + 1).Split(' ')) .ToList()) { string x = "", y = "", z = "", w = ""; if (xyzw.Length >= 1) x = xyzw[0]; if (xyzw.Length >= 2) y = xyzw[1]; if (xyzw.Length >= 3) z = xyzw[2]; if (xyzw.Length == 4) w = xyzw[3]; // TODO: Vertex4 for position in the Vertex class vertexs.Add(new Vector3(float.Parse(x), float.Parse(y), float.Parse(z))); } // TODO: .mtl and that stuff foreach ( var uvw in lines.Where(s => s.StartsWith("vt ")) .Select(s => s.Substring(s.IndexOf(' ') + 1).Split(' ')) .ToList()) { string u = "", v = "", w = ""; if (uvw.Length >= 1) u = uvw[0]; if (uvw.Length >= 2) v = uvw[1]; if (uvw.Length == 3) w = uvw[3]; // TODO: Vertex3 for texture in the Vertex class vertexTextures.Add(new Vector2(float.Parse(u), float.Parse(v))); } foreach ( var xyz in lines.Where(s => s.StartsWith("vn ")) .Select(s => s.Substring(s.IndexOf(' ') + 1).Split(' ')) .ToList()) { string x = "", y = "", z = ""; if (xyz.Length >= 1) x = xyz[0]; if (xyz.Length >= 2) y = xyz[1]; if (xyz.Length >= 3) z = xyz[2]; vertexNormals.Add(new Vector3(float.Parse(x), float.Parse(y), float.Parse(z)).Normalized()); } // TODO: lines starting with vp var vertices = new List<Vertex>(); var indices = new List<int>(); foreach ( var face in lines.Where(s => s.StartsWith("f ")) .Select(s => s.Substring(s.IndexOf(' ') + 1).Split(' ')) .ToList()) { for (int i = 0; i < face.Length - 2; i++) { for (int j = 0; j < 3; j++) { string[] vert = face[i + j].Split('/'); int v = 0, t = 0, n = 0; v = int.Parse(vert[0]); if (vert.Length >= 2 && vert[1] != string.Empty) t = int.Parse(vert[1]); if (vert.Length == 3) n = int.Parse(vert[2]); Vector3 position = vertexs[v - 1]; Vector2 texture = Vector2.Zero; if (t != 0) texture = vertexTextures[t - 1]; Vector3 normal = Vector3.Zero; if (n != 0) normal = vertexNormals[n - 1]; vertices.Add(new Vertex(position, normal, texture)); indices.Add(indices.Count); } } } var mesh = new Mesh( BufferLibrary.CreateVertexBuffer(filename, vertices.ToArray()), BufferLibrary.CreateIndexBuffer( filename, indices.Select(i => (uint) i).ToArray(), PrimitiveType.Triangles), indices.Count, PrimitiveType.Triangles); AddMesh(mesh, filename); return mesh; }
private void RenderMesh(Mesh mesh) { GL.BindBuffer(BufferTarget.ArrayBuffer, mesh.VboId); GL.BindBuffer(BufferTarget.ElementArrayBuffer, mesh.IboId); GL.EnableVertexAttribArray(0); GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, Vertex.SizeInBytes, (IntPtr)0); GL.EnableVertexAttribArray(1); GL.VertexAttribPointer(1, 3, VertexAttribPointerType.Float, false, Vertex.SizeInBytes, (IntPtr)(sizeof(float) * 3)); GL.EnableVertexAttribArray(2); GL.VertexAttribPointer(2, 2, VertexAttribPointerType.Float, false, Vertex.SizeInBytes, (IntPtr)(sizeof(float) * 6)); GL.DrawRangeElements(mesh.Mode, 0, mesh.Count, mesh.Count, DrawElementsType.UnsignedInt, IntPtr.Zero); GL.BindBuffer(BufferTarget.ArrayBuffer, 0); GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0); }
public static void AddMesh(Mesh mesh, string name) { Meshes[name] = mesh; }