Advertisement
purplejragon

mesh.cs

Feb 4th, 2021
353
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 6.19 KB | None | 0 0
  1. using OpenTK.Graphics.OpenGL4;
  2. using OpenTK.Mathematics;
  3. using System.Collections.Generic;
  4. using System.IO;
  5.  
  6. namespace Okapi.Rendering
  7. {
  8.  
  9.     // The way an OBJ file works is that there are multiple lines with different
  10.     // letters at the front. "v" means position, "vt" means texture coordinates/UVs,
  11.     // "vn" means normals, "s" means smooth shading (true or false), and "f" means faces.
  12.     // The faces are split up into 4 vertices, and each vertex has 3 numbers.
  13.     // The first number indicates the index of the position. So if the first position
  14.     // line's (remember its a position line if the line starts with "v") coordinates
  15.     // are (1.0, -1.0, 1.0), the putting an index of 1 for the first number would mean
  16.     // that vertex has a position of (1.0, -1.0, 1.0). The same thing applies to the
  17.     // UVs and normals. This means that positions, normals, and UVs can be reused by
  18.     // multiple vertices.
  19.     struct Vertex
  20.     {
  21.         public Vector3 pos;
  22.         public Vector2 uv;
  23.         public Vector3 norm;
  24.     }
  25.     class Mesh
  26.     {
  27.         private float[] loadedVertices;
  28.         private readonly List<Vector3> positions = new List<Vector3>();
  29.         private readonly List<Vector2> uvs = new List<Vector2>();
  30.         private readonly List<Vector3> norms = new List<Vector3>();
  31.         private readonly List<Vertex> verts = new List<Vertex>();
  32.         private readonly List<float> vertexData = new List<float>();
  33.         public Mesh(string path)
  34.         {
  35.  
  36.             string[] text = File.ReadAllLines(path);
  37.  
  38.             for (int i = 0; i < text.Length; i++)
  39.             {
  40.                 string line = text[i];
  41.  
  42.                 if (string.IsNullOrEmpty(line) | line.StartsWith('m') | line.StartsWith('o') | line.StartsWith('#')) continue;
  43.  
  44.                 if (line.StartsWith("v "))
  45.                 {
  46.                     char[] charsToTrim = { ',', 'v'};
  47.                     line = line.Trim(charsToTrim);
  48.                     line = line.Trim();
  49.                     string[] coords = line.Split(' ');
  50.  
  51.                     positions.Add(new Vector3(float.Parse(coords[0]), float.Parse(coords[1]), float.Parse(coords[2])));
  52.                 }
  53.                 else if (line.StartsWith("vt "))
  54.                 {
  55.                     char[] charsToTrim = { ',', 'v', 't'};
  56.                     line = line.Trim(charsToTrim);
  57.                     line = line.Trim();
  58.                     string[] coords = line.Split(' ');
  59.                    
  60.                     uvs.Add(new Vector2(float.Parse(coords[0]), float.Parse(coords[1])));
  61.                 }
  62.                 else if (line.StartsWith("vn "))
  63.                 {
  64.                     char[] charsToTrim = { ',', 'v', 'n' };
  65.                     line = line.Trim(charsToTrim);
  66.                     line = line.Trim();
  67.                     string[] coords = line.Split(' ');
  68.  
  69.                     norms.Add(new Vector3(float.Parse(coords[0]), float.Parse(coords[1]), float.Parse(coords[2])));
  70.                 }
  71.                 else if (line.StartsWith("f "))
  72.                 {
  73.                     line = line.Trim('f');
  74.                     line = line.Trim();
  75.                     //char[] charsToSplit = { ' ' };
  76.                     string[] groupedIndices = line.Split(' ');
  77.                     for (int a = 0; a < groupedIndices.Length; a++)
  78.                     {
  79.                         Vertex vertex = new Vertex
  80.                         {
  81.                             pos = positions[int.Parse(groupedIndices[a].Split('/')[0]) - 1],
  82.                             uv = uvs[int.Parse(groupedIndices[a].Split('/')[1]) - 1],
  83.                             norm = norms[int.Parse(groupedIndices[a].Split('/')[2]) - 1]
  84.                         };
  85.                         verts.Add(vertex);
  86.                     }
  87.                    
  88.                 }
  89.                 foreach (Vertex vert in verts)
  90.                 {
  91.                     vertexData.Add(vert.pos.X);
  92.                     vertexData.Add(vert.pos.Y);
  93.                     vertexData.Add(vert.pos.Z);
  94.                     vertexData.Add(vert.norm.X);
  95.                     vertexData.Add(vert.norm.Y);
  96.                     vertexData.Add(vert.norm.Z);
  97.                     vertexData.Add(vert.uv.X);
  98.                     vertexData.Add(vert.uv.Y);
  99.                 }
  100.  
  101.             }
  102.         }
  103.  
  104.  
  105.  
  106.         private int vbo;
  107.         private int vao;
  108.         private Shader shader;
  109.         public void Load(Shader shader)
  110.         {
  111.             loadedVertices = vertexData.ToArray();
  112.             this.shader = shader;
  113.             // Creating our VBOs.
  114.             vbo = GL.GenBuffer();
  115.             GL.BindBuffer(BufferTarget.ArrayBuffer, vbo);
  116.             // Then, upload the vertices to the buffer.
  117.             GL.BufferData(BufferTarget.ArrayBuffer, loadedVertices.Length * sizeof(float), loadedVertices, BufferUsageHint.StaticDraw);
  118.             // Use the shader.
  119.             this.shader.Use();
  120.             // Generates the VAOs.
  121.             vao = GL.GenVertexArray();
  122.             GL.BindVertexArray(vao);
  123.             // Finds the aPos, aNormal, and aTexCoords vec4 in the vertex shader, tells
  124.             // the program how to interpret the vertex data.
  125.             int positionLocation = this.shader.GetAttribLocation("aPos");
  126.             GL.EnableVertexAttribArray(positionLocation);
  127.             GL.VertexAttribPointer(positionLocation, 3, VertexAttribPointerType.Float, false, 8 * sizeof(float), 0);
  128.            
  129.             int normalLocation = this.shader.GetAttribLocation("aNormal");
  130.             GL.EnableVertexAttribArray(normalLocation);
  131.             GL.VertexAttribPointer(normalLocation, 3, VertexAttribPointerType.Float, false, 8 * sizeof(float), 3 * sizeof(float));
  132.  
  133.             int uvLocation = this.shader.GetAttribLocation("aTexCoord");
  134.             GL.EnableVertexAttribArray(uvLocation);
  135.             GL.VertexAttribPointer(uvLocation, 2, VertexAttribPointerType.Float, false, 8 * sizeof(float), 6 * sizeof(float));
  136.         }
  137.  
  138.         public void Draw()
  139.         {
  140.             shader.Use();
  141.             GL.BindVertexArray(vao);
  142.             GL.DrawArrays(PrimitiveType.Triangles, 0, loadedVertices.Length / 8);
  143.             GL.BindVertexArray(0);
  144.         }
  145.  
  146.     }
  147. }
  148.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement