From da9990908ac7e33bffdd836379b289b5e06419cb Mon Sep 17 00:00:00 2001 From: zyb3rwolfi Date: Thu, 27 Nov 2025 17:58:57 +0000 Subject: [PATCH] Added normal textures --- TheRepo/TheLabs/Helpers.cs | 67 +++++++++++++ TheRepo/TheLabs/Mesh.cs | 39 +++++++- TheRepo/TheLabs/MyExampleWindow.cs | 12 ++- TheRepo/TheLabs/RenderObject.cs | 14 ++- TheRepo/TheLabs/Shaders/shader.frag | 19 +++- TheRepo/TheLabs/Shaders/shader.vert | 9 ++ TheRepo/TheLabs/ShapeFactory.cs | 143 +++++++++++++++++----------- TheRepo/TheLabs/Vertex.cs | 22 +++++ 8 files changed, 258 insertions(+), 67 deletions(-) create mode 100644 TheRepo/TheLabs/Helpers.cs create mode 100644 TheRepo/TheLabs/Vertex.cs diff --git a/TheRepo/TheLabs/Helpers.cs b/TheRepo/TheLabs/Helpers.cs new file mode 100644 index 0000000..e3f379a --- /dev/null +++ b/TheRepo/TheLabs/Helpers.cs @@ -0,0 +1,67 @@ +using OpenTK.Mathematics; + +namespace TheLabs; + +public static class Helpers +{ + public static void CalculateTangent(ref Vertex v1, ref Vertex v2, ref Vertex v3) + { + // 1. Calculate Edge Vectors (Geometry) + Vector3 edge1 = v2.Position - v1.Position; + Vector3 edge2 = v3.Position - v1.Position; + + // 2. Calculate Edge Vectors (Texture Space) + Vector2 deltaUV1 = v2.TexCoords - v1.TexCoords; + Vector2 deltaUV2 = v3.TexCoords - v1.TexCoords; + + // 3. The Math (Solving linear equations) + float f = 1.0f / (deltaUV1.X * deltaUV2.Y - deltaUV2.X * deltaUV1.Y); + + Vector3 tangent; + tangent.X = f * (deltaUV2.Y * edge1.X - deltaUV1.Y * edge2.X); + tangent.Y = f * (deltaUV2.Y * edge1.Y - deltaUV1.Y * edge2.Y); + tangent.Z = f * (deltaUV2.Y * edge1.Z - deltaUV1.Y * edge2.Z); + + // Normalize it + tangent = Vector3.Normalize(tangent); + Vector3 bitangent = Vector3.Normalize(Vector3.Cross(edge1, edge2)); + + // 4. Assign the same tangent to all 3 vertices of the triangle + // (For smooth objects, you would average them, but for a cube, this is fine) + v1.Tangent = tangent; v1.Bitangent = bitangent; + v2.Tangent = tangent; v2.Bitangent = bitangent; + v3.Tangent = tangent; v3.Bitangent = bitangent; + } + + public static void AddFace(List vertices, List indices, + Vertex v0, Vertex v1, Vertex v2, Vertex v3) + { + // 1. Calculate Tangents + // We calculate it twice to ensure the tangent is consistent across the whole face + // Triangle 1 (Bottom-Left, Bottom-Right, Top-Right) + CalculateTangent(ref v0, ref v1, ref v2); + // Triangle 2 (Bottom-Left, Top-Right, Top-Left) + CalculateTangent(ref v0, ref v2, ref v3); + + // 2. Track where these new vertices start in the main list + // (If the list has 4 items, the new ones start at index 4) + uint offset = (uint)vertices.Count; + + // 3. Add Vertices to the list + vertices.Add(v0); // Index: offset + 0 + vertices.Add(v1); // Index: offset + 1 + vertices.Add(v2); // Index: offset + 2 + vertices.Add(v3); // Index: offset + 3 + + // 4. Add Indices for the two triangles (Standard Quad) + // Triangle 1 + indices.Add(offset + 0); + indices.Add(offset + 1); + indices.Add(offset + 2); + + // Triangle 2 + indices.Add(offset + 0); + indices.Add(offset + 2); + indices.Add(offset + 3); + } +} \ No newline at end of file diff --git a/TheRepo/TheLabs/Mesh.cs b/TheRepo/TheLabs/Mesh.cs index c6f8ece..3683f77 100644 --- a/TheRepo/TheLabs/Mesh.cs +++ b/TheRepo/TheLabs/Mesh.cs @@ -12,7 +12,7 @@ public class Mesh : IDisposable private readonly int _vertexCount; private readonly bool _useIndices; - public enum VertexLayout { PosColor, PosTex, PosTexNormal } + public enum VertexLayout { PosColor, PosTex, PosTexNormal, PosTexNormalTangent } public Mesh(float[] vertices, uint[] indices, VertexLayout layout) { @@ -65,7 +65,7 @@ public class Mesh : IDisposable if (layout == VertexLayout.PosColor) { // Stride = 7 floats (3 Pos + 4 Color) - var stride = 7 * sizeof(float); + var stride = 14 * sizeof(float); // Location 0: Position GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, stride, 0); @@ -77,6 +77,13 @@ public class Mesh : IDisposable GL.VertexAttribPointer(2, 2, VertexAttribPointerType.Float, false, stride, 3 * sizeof(float)); GL.EnableVertexAttribArray(2); + + GL.VertexAttribPointer(3, 3, VertexAttribPointerType.Float, false, stride, 8 * sizeof(float)); + GL.EnableVertexAttribArray(3); + + // Loc 4: Bitangent (Offset 11) <-- NEW + GL.VertexAttribPointer(4, 3, VertexAttribPointerType.Float, false, stride, 11 * sizeof(float)); + GL.EnableVertexAttribArray(4); } else if (layout == VertexLayout.PosTex) { @@ -96,7 +103,7 @@ public class Mesh : IDisposable else if (layout == VertexLayout.PosTexNormal) { // Stride = 8 floats (3 Pos + 3 Normal + 2 Tex) - var stride = 8 * sizeof(float); + var stride = 14 * sizeof(float); // Location 0: Position GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, stride, 0); @@ -109,6 +116,32 @@ public class Mesh : IDisposable // Location 2: TexCoord (Offset 6 floats: 3 pos + 3 normal) GL.VertexAttribPointer(2, 2, VertexAttribPointerType.Float, false, stride, 6 * sizeof(float)); GL.EnableVertexAttribArray(2); + + } + else if (layout == VertexLayout.PosTexNormalTangent) + { + // --- NEW LOGIC FOR CUBES (Stride 14) --- + var stride = 14 * sizeof(float); + + // Loc 0: Position + GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, stride, 0); + GL.EnableVertexAttribArray(0); + + // Loc 1: Normal + GL.VertexAttribPointer(1, 3, VertexAttribPointerType.Float, false, stride, 3 * sizeof(float)); + GL.EnableVertexAttribArray(1); + + // Loc 2: TexCoord + GL.VertexAttribPointer(2, 2, VertexAttribPointerType.Float, false, stride, 6 * sizeof(float)); + GL.EnableVertexAttribArray(2); + + // Loc 3: Tangent + GL.VertexAttribPointer(3, 3, VertexAttribPointerType.Float, false, stride, 8 * sizeof(float)); + GL.EnableVertexAttribArray(3); + + // Loc 4: Bitangent + GL.VertexAttribPointer(4, 3, VertexAttribPointerType.Float, false, stride, 11 * sizeof(float)); + GL.EnableVertexAttribArray(4); } } diff --git a/TheRepo/TheLabs/MyExampleWindow.cs b/TheRepo/TheLabs/MyExampleWindow.cs index b246d8e..e14dc23 100644 --- a/TheRepo/TheLabs/MyExampleWindow.cs +++ b/TheRepo/TheLabs/MyExampleWindow.cs @@ -58,8 +58,9 @@ namespace TheLabs base.OnLoad(); // --- Set up Lighting and Material --- - _mainLight = new Lighting(new Vector3(1.2f, 1.0f, 2.0f), - new Vector3(0.3f), + _mainLight = new Lighting(new Vector3( + 1.2f, 1.0f, 2.0f), + new Vector3(0.5f), new Vector3(1.5f), new Vector3(1.0f)); @@ -78,14 +79,17 @@ namespace TheLabs // -- Load Shaders, Textures, and Create Scene Objects --- _shader = new Shader("Shaders/shader.vert", "Shaders/shader.frag"); - _texture = new Texture("Textures/placeholder.png"); + _texture = new Texture("Textures/cobble.jpg"); + Texture _normalMap = new Texture("Textures/cobbleNormal.jpg"); + // --- Create Scene Graph --- _rootNode = new SceneNode(); // Create Example Object - _buildingObject = ShapeFactory.CreateTexturedSphere(); + _buildingObject = ShapeFactory.CreateTexturedCube(); _buildingRender = new RenderObject(_buildingObject, _shader, _texture, _defaultMaterial, _mainLight); + _buildingRender.NormalMap = _normalMap; _buildingNode = new SceneNode(_buildingRender); _buildingNode.Position = new Vector3(2.0f, -1.0f, 0.0f); _buildingNode.Scale = new Vector3(0.1f, 0.1f, 0.1f); diff --git a/TheRepo/TheLabs/RenderObject.cs b/TheRepo/TheLabs/RenderObject.cs index 2b542ed..5be1092 100644 --- a/TheRepo/TheLabs/RenderObject.cs +++ b/TheRepo/TheLabs/RenderObject.cs @@ -9,6 +9,7 @@ public class RenderObject public Mesh Mesh; public Shader Shader; public Texture Texture; + public Texture NormalMap; public Material Material; public Lighting Lighting; @@ -41,7 +42,7 @@ public class RenderObject Shader.Use(); if (Texture != null && UseTexture) { - Texture.Use(); + Texture.Use(TextureUnit.Texture0); Shader.SetInt("uTexture", 0); GL.Uniform1(GL.GetUniformLocation(Shader.Handle, "uUseTexture"), 1); } @@ -49,6 +50,17 @@ public class RenderObject { GL.Uniform1(GL.GetUniformLocation(Shader.Handle, "uUseTexture"), 0); } + + if (NormalMap != null) + { + NormalMap.Use(TextureUnit.Texture1); + Shader.SetInt("uNormalMap", 1); + GL.Uniform1(GL.GetUniformLocation(Shader.Handle, "uUseNormalMap"), 1); + } + else + { + GL.Uniform1(GL.GetUniformLocation(Shader.Handle, "uUseNormalMap"), 0); + } Material.Apply(Shader); light.Apply(Shader); diff --git a/TheRepo/TheLabs/Shaders/shader.frag b/TheRepo/TheLabs/Shaders/shader.frag index 4f37796..2b5d98b 100644 --- a/TheRepo/TheLabs/Shaders/shader.frag +++ b/TheRepo/TheLabs/Shaders/shader.frag @@ -9,6 +9,7 @@ out vec4 outputColor; // The final output color of the fragment in vec3 FragPos; in vec3 Normal; in vec2 TexCoord; +in mat3 vTBN; // Tangent, Bitangent, Normal matrix struct MaterialProperty { vec3 ambientColour; @@ -30,10 +31,12 @@ struct LightProperty { // --- UNIFORMS --- uniform sampler2D uTexture; // Image Texture +uniform sampler2D uNormalMap; // Normal Map Texture uniform vec3 uViewPos; // Camera Position uniform MaterialProperty uMaterial; // Material Properties uniform LightProperty uPointLight; // Light Properties uniform int uUseTexture; // Flag to indicate if texture should be used +uniform int uUseNormalMap; // Flag to indicate if normal map should be used vec3 CalcPointLight(LightProperty light, vec3 normal, vec3 fragPos, vec3 viewDir) { @@ -66,9 +69,18 @@ vec3 CalcPointLight(LightProperty light, vec3 normal, vec3 fragPos, vec3 viewDir void main() { + vec3 norm; + + if (uUseNormalMap == 1) { + vec3 normalFromTexture = texture(uNormalMap, TexCoord).rgb; + vec3 colourShift = normalFromTexture * 2.0 - 1.0; // Transform from [0,1] to [-1,1] + // 1. Setup Vectors + norm = normalize(vTBN * colourShift); + + } else { + norm = normalize(Normal); + } - // 1. Setup Vectors - vec3 norm = normalize(Normal); vec3 viewDir = normalize(uViewPos - FragPos); // 2. Calculate Lighting using the Function @@ -76,9 +88,10 @@ void main() // 3. Apply Texture Switch if (uUseTexture == 1) { + outputColor = vec4(result, 1.0) * texture(uTexture, TexCoord); } else { outputColor = vec4(result, 1.0); } - + } \ No newline at end of file diff --git a/TheRepo/TheLabs/Shaders/shader.vert b/TheRepo/TheLabs/Shaders/shader.vert index 08ea0c7..ad50d6c 100644 --- a/TheRepo/TheLabs/Shaders/shader.vert +++ b/TheRepo/TheLabs/Shaders/shader.vert @@ -7,12 +7,15 @@ layout(location = 0) in vec3 aPosition; // Raw 3D position layout(location = 1) in vec3 aNormal; // The direction perpendicular to the surface layout(location = 2) in vec2 aTexCoord; // The U,V texture coordinates +layout(location = 3) in vec3 aTangent; // Tangent vector for normal mapping +layout(location = 4) in vec3 aBitangent; // Bitangent vector for normal mapping // --- OUTPUTS --- // We can pass data to the fragment shader through these out vec3 FragPos; out vec3 Normal; out vec2 TexCoord; +out mat3 vTBN; // --- UNIFORMS --- // These are matrices that help transform our vertices @@ -22,6 +25,12 @@ uniform mat4 projection; void main(void) { + vec3 T = normalize(vec3(model * vec4(aTangent, 0.0))); + vec3 B = normalize(vec3(model * vec4(aBitangent, 0.0))); + vec3 N = normalize(vec3(model * vec4(aNormal, 0.0))); + + vTBN = mat3(T, B, N); + // 1. Calculate World Position FragPos = vec3(model * vec4(aPosition, 1.0)); diff --git a/TheRepo/TheLabs/ShapeFactory.cs b/TheRepo/TheLabs/ShapeFactory.cs index b5b0de6..f633adf 100644 --- a/TheRepo/TheLabs/ShapeFactory.cs +++ b/TheRepo/TheLabs/ShapeFactory.cs @@ -1,72 +1,83 @@ -namespace TheLabs; +using OpenTK.Mathematics; + +namespace TheLabs; public static class ShapeFactory { public static Mesh CreateTexturedCube() { - float[] vertices = { - // Format: X, Y, Z, NX, NY, NZ, U, V + List vertices = new List(); + List indices = new List(); - // --- Front Face (Normal points +Z: 0, 0, 1) --- - -0.5f, -0.5f, 0.5f, 0f, 0f, 1f, 0f, 0f, // Bottom-left - 0.5f, -0.5f, 0.5f, 0f, 0f, 1f, 1f, 0f, // Bottom-right - 0.5f, 0.5f, 0.5f, 0f, 0f, 1f, 1f, 1f, // Top-right - -0.5f, 0.5f, 0.5f, 0f, 0f, 1f, 0f, 1f, // Top-left + // --- FRONT FACE (Normal 0, 0, 1) --- + // Sequence: Bottom-Left -> Bottom-Right -> Top-Right -> Top-Left + Helpers.AddFace(vertices, indices, + new Vertex(new Vector3(-0.5f, -0.5f, 0.5f), new Vector3(0, 0, 1), new Vector2(0, 0), Vector3.Zero, Vector3.Zero), // BL + new Vertex(new Vector3( 0.5f, -0.5f, 0.5f), new Vector3(0, 0, 1), new Vector2(1, 0), Vector3.Zero, Vector3.Zero), // BR + new Vertex(new Vector3( 0.5f, 0.5f, 0.5f), new Vector3(0, 0, 1), new Vector2(1, 1), Vector3.Zero, Vector3.Zero), // TR + new Vertex(new Vector3(-0.5f, 0.5f, 0.5f), new Vector3(0, 0, 1), new Vector2(0, 1), Vector3.Zero, Vector3.Zero) // TL + ); - // --- Back Face (Normal points -Z: 0, 0, -1) --- - -0.5f, -0.5f, -0.5f, 0f, 0f, -1f, 1f, 0f, - 0.5f, -0.5f, -0.5f, 0f, 0f, -1f, 0f, 0f, - 0.5f, 0.5f, -0.5f, 0f, 0f, -1f, 0f, 1f, - -0.5f, 0.5f, -0.5f, 0f, 0f, -1f, 1f, 1f, + // --- BACK FACE (Normal 0, 0, -1) --- + // Sequence: Bottom-Right -> Bottom-Left -> Top-Left -> Top-Right (Relative to Front view) + Helpers.AddFace(vertices, indices, + new Vertex(new Vector3( 0.5f, -0.5f, -0.5f), new Vector3(0, 0, -1), new Vector2(0, 0), Vector3.Zero, Vector3.Zero), // BR + new Vertex(new Vector3(-0.5f, -0.5f, -0.5f), new Vector3(0, 0, -1), new Vector2(1, 0), Vector3.Zero, Vector3.Zero), // BL + new Vertex(new Vector3(-0.5f, 0.5f, -0.5f), new Vector3(0, 0, -1), new Vector2(1, 1), Vector3.Zero, Vector3.Zero), // TL + new Vertex(new Vector3( 0.5f, 0.5f, -0.5f), new Vector3(0, 0, -1), new Vector2(0, 1), Vector3.Zero, Vector3.Zero) // TR + ); - // --- Left Face (Normal points -X: -1, 0, 0) --- - -0.5f, -0.5f, -0.5f, -1f, 0f, 0f, 0f, 0f, - -0.5f, -0.5f, 0.5f, -1f, 0f, 0f, 1f, 0f, - -0.5f, 0.5f, 0.5f, -1f, 0f, 0f, 1f, 1f, - -0.5f, 0.5f, -0.5f, -1f, 0f, 0f, 0f, 1f, + // --- LEFT FACE (Normal -1, 0, 0) --- + // Sequence: Back-Left -> Front-Left -> Front-Top -> Back-Top + Helpers.AddFace(vertices, indices, + new Vertex(new Vector3(-0.5f, -0.5f, -0.5f), new Vector3(-1, 0, 0), new Vector2(0, 0), Vector3.Zero, Vector3.Zero), // BL + new Vertex(new Vector3(-0.5f, -0.5f, 0.5f), new Vector3(-1, 0, 0), new Vector2(1, 0), Vector3.Zero, Vector3.Zero), // FL + new Vertex(new Vector3(-0.5f, 0.5f, 0.5f), new Vector3(-1, 0, 0), new Vector2(1, 1), Vector3.Zero, Vector3.Zero), // FT + new Vertex(new Vector3(-0.5f, 0.5f, -0.5f), new Vector3(-1, 0, 0), new Vector2(0, 1), Vector3.Zero, Vector3.Zero) // BT + ); - // --- Right Face (Normal points +X: 1, 0, 0) --- - 0.5f, -0.5f, -0.5f, 1f, 0f, 0f, 1f, 0f, - 0.5f, -0.5f, 0.5f, 1f, 0f, 0f, 0f, 0f, - 0.5f, 0.5f, 0.5f, 1f, 0f, 0f, 0f, 1f, - 0.5f, 0.5f, -0.5f, 1f, 0f, 0f, 1f, 1f, + // --- RIGHT FACE (Normal 1, 0, 0) --- + // Sequence: Front-Right -> Back-Right -> Back-Top -> Front-Top + Helpers.AddFace(vertices, indices, + new Vertex(new Vector3( 0.5f, -0.5f, 0.5f), new Vector3(1, 0, 0), new Vector2(0, 0), Vector3.Zero, Vector3.Zero), // FR + new Vertex(new Vector3( 0.5f, -0.5f, -0.5f), new Vector3(1, 0, 0), new Vector2(1, 0), Vector3.Zero, Vector3.Zero), // BR + new Vertex(new Vector3( 0.5f, 0.5f, -0.5f), new Vector3(1, 0, 0), new Vector2(1, 1), Vector3.Zero, Vector3.Zero), // BT + new Vertex(new Vector3( 0.5f, 0.5f, 0.5f), new Vector3(1, 0, 0), new Vector2(0, 1), Vector3.Zero, Vector3.Zero) // FT + ); - // --- Top Face (Normal points +Y: 0, 1, 0) --- - -0.5f, 0.5f, -0.5f, 0f, 1f, 0f, 0f, 1f, - 0.5f, 0.5f, -0.5f, 0f, 1f, 0f, 1f, 1f, - 0.5f, 0.5f, 0.5f, 0f, 1f, 0f, 1f, 0f, - -0.5f, 0.5f, 0.5f, 0f, 1f, 0f, 0f, 0f, + // --- TOP FACE (Normal 0, 1, 0) --- + // Sequence: Front-Left -> Front-Right -> Back-Right -> Back-Left + Helpers.AddFace(vertices, indices, + new Vertex(new Vector3(-0.5f, 0.5f, 0.5f), new Vector3(0, 1, 0), new Vector2(0, 0), Vector3.Zero, Vector3.Zero), // FL + new Vertex(new Vector3( 0.5f, 0.5f, 0.5f), new Vector3(0, 1, 0), new Vector2(1, 0), Vector3.Zero, Vector3.Zero), // FR + new Vertex(new Vector3( 0.5f, 0.5f, -0.5f), new Vector3(0, 1, 0), new Vector2(1, 1), Vector3.Zero, Vector3.Zero), // BR + new Vertex(new Vector3(-0.5f, 0.5f, -0.5f), new Vector3(0, 1, 0), new Vector2(0, 1), Vector3.Zero, Vector3.Zero) // BL + ); - // --- Bottom Face (Normal points -Y: 0, -1, 0) --- - -0.5f, -0.5f, -0.5f, 0f, -1f, 0f, 1f, 1f, - 0.5f, -0.5f, -0.5f, 0f, -1f, 0f, 0f, 1f, - 0.5f, -0.5f, 0.5f, 0f, -1f, 0f, 0f, 0f, - -0.5f, -0.5f, 0.5f, 0f, -1f, 0f, 1f, 0f - - }; + // --- BOTTOM FACE (Normal 0, -1, 0) --- + // Sequence: Front-Left -> Back-Left -> Back-Right -> Front-Right + Helpers.AddFace(vertices, indices, + new Vertex(new Vector3(-0.5f, -0.5f, 0.5f), new Vector3(0, -1, 0), new Vector2(0, 1), Vector3.Zero, Vector3.Zero), // FL + new Vertex(new Vector3(-0.5f, -0.5f, -0.5f), new Vector3(0, -1, 0), new Vector2(0, 0), Vector3.Zero, Vector3.Zero), // BL + new Vertex(new Vector3( 0.5f, -0.5f, -0.5f), new Vector3(0, -1, 0), new Vector2(1, 0), Vector3.Zero, Vector3.Zero), // BR + new Vertex(new Vector3( 0.5f, -0.5f, 0.5f), new Vector3(0, -1, 0), new Vector2(1, 1), Vector3.Zero, Vector3.Zero) // FR + ); - uint[] indices = { - // Front face - 0, 2, 1, - 0, 2, 3, - // Back face - 4, 5, 6, - 4, 6, 7, - // Left face - 8, 9, 10, - 8, 10, 11, - // Right face - 12, 14, 13, - 12, 14, 15, - // Top face - 16, 17, 18, - 16, 18, 19, - // Bottom face - 20, 22, 21, - 20, 22, 23 - }; + + List finalFloats = new List(); + + foreach (var v in vertices) + { + finalFloats.Add(v.Position.X); finalFloats.Add(v.Position.Y); finalFloats.Add(v.Position.Z); + finalFloats.Add(v.Normal.X); finalFloats.Add(v.Normal.Y); finalFloats.Add(v.Normal.Z); + finalFloats.Add(v.TexCoords.X); finalFloats.Add(v.TexCoords.Y); + + // --- NEW: Add Tangent and Bitangent --- + finalFloats.Add(v.Tangent.X); finalFloats.Add(v.Tangent.Y); finalFloats.Add(v.Tangent.Z); + finalFloats.Add(v.Bitangent.X); finalFloats.Add(v.Bitangent.Y); finalFloats.Add(v.Bitangent.Z); + } - return new Mesh(vertices, indices, Mesh.VertexLayout.PosTexNormal); + return new Mesh(finalFloats.ToArray(), indices.ToArray(), Mesh.VertexLayout.PosTexNormalTangent); } public static Mesh CreateColouredCircle() @@ -321,6 +332,26 @@ public static class ShapeFactory return new Mesh(vertices.ToArray(), indices.ToArray(), Mesh.VertexLayout.PosTexNormal); } + public static Mesh createTexturedSquare() + { + float[] vertices = { + // Format: X, Y, Z, U, V + + // --- Front Face --- + -0.5f, -0.5f, 0.0f, 0f, 0f, // Bottom-left + 0.5f, -0.5f, 0.0f, 1f, 0f, // Bottom-right + 0.5f, 0.5f, 0.0f, 1f, 1f, // Top-right + -0.5f, 0.5f, 0.0f, 0f, 1f, // Top-left + }; + + uint[] indices = { + // Front face + 0, 2, 1, + 0, 2, 3, + }; + + return new Mesh(vertices, indices, Mesh.VertexLayout.PosTex); + } } \ No newline at end of file diff --git a/TheRepo/TheLabs/Vertex.cs b/TheRepo/TheLabs/Vertex.cs new file mode 100644 index 0000000..58cb680 --- /dev/null +++ b/TheRepo/TheLabs/Vertex.cs @@ -0,0 +1,22 @@ +using OpenTK.Mathematics; + +namespace TheLabs; + +public struct Vertex +{ + public Vector3 Position; + public Vector3 Normal; + public Vector2 TexCoords; + public Vector3 Tangent; + public Vector3 Bitangent; + + // A constructor to make creating them easy + public Vertex(Vector3 position, Vector3 normal, Vector2 texCoords, Vector3 tangent, Vector3 bitangent) + { + Position = position; + Normal = normal; + TexCoords = texCoords; + Tangent = tangent; + Bitangent = bitangent; + } +} \ No newline at end of file