Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using OpenTK.Graphics.OpenGL4;
- using OpenTK.Mathematics;
- using System.Collections.Generic;
- using System.IO;
- namespace Okapi.Rendering
- {
- // The way an OBJ file works is that there are multiple lines with different
- // letters at the front. "v" means position, "vt" means texture coordinates/UVs,
- // "vn" means normals, "s" means smooth shading (true or false), and "f" means faces.
- // The faces are split up into 4 vertices, and each vertex has 3 numbers.
- // The first number indicates the index of the position. So if the first position
- // line's (remember its a position line if the line starts with "v") coordinates
- // are (1.0, -1.0, 1.0), the putting an index of 1 for the first number would mean
- // that vertex has a position of (1.0, -1.0, 1.0). The same thing applies to the
- // UVs and normals. This means that positions, normals, and UVs can be reused by
- // multiple vertices.
- struct Vertex
- {
- public Vector3 pos;
- public Vector2 uv;
- public Vector3 norm;
- }
- class Mesh
- {
- private float[] loadedVertices;
- private readonly List<Vector3> positions = new List<Vector3>();
- private readonly List<Vector2> uvs = new List<Vector2>();
- private readonly List<Vector3> norms = new List<Vector3>();
- private readonly List<Vertex> verts = new List<Vertex>();
- private readonly List<float> vertexData = new List<float>();
- public Mesh(string path)
- {
- string[] text = File.ReadAllLines(path);
- for (int i = 0; i < text.Length; i++)
- {
- string line = text[i];
- if (string.IsNullOrEmpty(line) | line.StartsWith('m') | line.StartsWith('o') | line.StartsWith('#')) continue;
- if (line.StartsWith("v "))
- {
- char[] charsToTrim = { ',', 'v'};
- line = line.Trim(charsToTrim);
- line = line.Trim();
- string[] coords = line.Split(' ');
- positions.Add(new Vector3(float.Parse(coords[0]), float.Parse(coords[1]), float.Parse(coords[2])));
- }
- else if (line.StartsWith("vt "))
- {
- char[] charsToTrim = { ',', 'v', 't'};
- line = line.Trim(charsToTrim);
- line = line.Trim();
- string[] coords = line.Split(' ');
- uvs.Add(new Vector2(float.Parse(coords[0]), float.Parse(coords[1])));
- }
- else if (line.StartsWith("vn "))
- {
- char[] charsToTrim = { ',', 'v', 'n' };
- line = line.Trim(charsToTrim);
- line = line.Trim();
- string[] coords = line.Split(' ');
- norms.Add(new Vector3(float.Parse(coords[0]), float.Parse(coords[1]), float.Parse(coords[2])));
- }
- else if (line.StartsWith("f "))
- {
- line = line.Trim('f');
- line = line.Trim();
- //char[] charsToSplit = { ' ' };
- string[] groupedIndices = line.Split(' ');
- for (int a = 0; a < groupedIndices.Length; a++)
- {
- Vertex vertex = new Vertex
- {
- pos = positions[int.Parse(groupedIndices[a].Split('/')[0]) - 1],
- uv = uvs[int.Parse(groupedIndices[a].Split('/')[1]) - 1],
- norm = norms[int.Parse(groupedIndices[a].Split('/')[2]) - 1]
- };
- verts.Add(vertex);
- }
- }
- foreach (Vertex vert in verts)
- {
- vertexData.Add(vert.pos.X);
- vertexData.Add(vert.pos.Y);
- vertexData.Add(vert.pos.Z);
- vertexData.Add(vert.norm.X);
- vertexData.Add(vert.norm.Y);
- vertexData.Add(vert.norm.Z);
- vertexData.Add(vert.uv.X);
- vertexData.Add(vert.uv.Y);
- }
- }
- }
- private int vbo;
- private int vao;
- private Shader shader;
- public void Load(Shader shader)
- {
- loadedVertices = vertexData.ToArray();
- this.shader = shader;
- // Creating our VBOs.
- vbo = GL.GenBuffer();
- GL.BindBuffer(BufferTarget.ArrayBuffer, vbo);
- // Then, upload the vertices to the buffer.
- GL.BufferData(BufferTarget.ArrayBuffer, loadedVertices.Length * sizeof(float), loadedVertices, BufferUsageHint.StaticDraw);
- // Use the shader.
- this.shader.Use();
- // Generates the VAOs.
- vao = GL.GenVertexArray();
- GL.BindVertexArray(vao);
- // Finds the aPos, aNormal, and aTexCoords vec4 in the vertex shader, tells
- // the program how to interpret the vertex data.
- int positionLocation = this.shader.GetAttribLocation("aPos");
- GL.EnableVertexAttribArray(positionLocation);
- GL.VertexAttribPointer(positionLocation, 3, VertexAttribPointerType.Float, false, 8 * sizeof(float), 0);
- int normalLocation = this.shader.GetAttribLocation("aNormal");
- GL.EnableVertexAttribArray(normalLocation);
- GL.VertexAttribPointer(normalLocation, 3, VertexAttribPointerType.Float, false, 8 * sizeof(float), 3 * sizeof(float));
- int uvLocation = this.shader.GetAttribLocation("aTexCoord");
- GL.EnableVertexAttribArray(uvLocation);
- GL.VertexAttribPointer(uvLocation, 2, VertexAttribPointerType.Float, false, 8 * sizeof(float), 6 * sizeof(float));
- }
- public void Draw()
- {
- shader.Use();
- GL.BindVertexArray(vao);
- GL.DrawArrays(PrimitiveType.Triangles, 0, loadedVertices.Length / 8);
- GL.BindVertexArray(0);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement