Пример #1
0
        /// <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;
        }
Пример #2
0
        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);
        }
Пример #3
0
 public static void AddMesh(Mesh mesh, string name)
 {
     Meshes[name] = mesh;
 }