mirror of
https://github.com/UOH-CS-Level5/551455-graphics-programming-2526-the-repo-Zyb3rWolfi.git
synced 2025-11-29 00:43:08 +00:00
Added normal textures
This commit is contained in:
parent
d2b3027a11
commit
da9990908a
67
TheRepo/TheLabs/Helpers.cs
Normal file
67
TheRepo/TheLabs/Helpers.cs
Normal file
@ -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<Vertex> vertices, List<uint> 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -12,7 +12,7 @@ public class Mesh : IDisposable
|
|||||||
private readonly int _vertexCount;
|
private readonly int _vertexCount;
|
||||||
private readonly bool _useIndices;
|
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)
|
public Mesh(float[] vertices, uint[] indices, VertexLayout layout)
|
||||||
{
|
{
|
||||||
@ -65,7 +65,7 @@ public class Mesh : IDisposable
|
|||||||
if (layout == VertexLayout.PosColor)
|
if (layout == VertexLayout.PosColor)
|
||||||
{
|
{
|
||||||
// Stride = 7 floats (3 Pos + 4 Color)
|
// Stride = 7 floats (3 Pos + 4 Color)
|
||||||
var stride = 7 * sizeof(float);
|
var stride = 14 * sizeof(float);
|
||||||
|
|
||||||
// Location 0: Position
|
// Location 0: Position
|
||||||
GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, stride, 0);
|
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.VertexAttribPointer(2, 2, VertexAttribPointerType.Float, false, stride, 3 * sizeof(float));
|
||||||
GL.EnableVertexAttribArray(2);
|
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)
|
else if (layout == VertexLayout.PosTex)
|
||||||
{
|
{
|
||||||
@ -96,7 +103,7 @@ public class Mesh : IDisposable
|
|||||||
else if (layout == VertexLayout.PosTexNormal)
|
else if (layout == VertexLayout.PosTexNormal)
|
||||||
{
|
{
|
||||||
// Stride = 8 floats (3 Pos + 3 Normal + 2 Tex)
|
// Stride = 8 floats (3 Pos + 3 Normal + 2 Tex)
|
||||||
var stride = 8 * sizeof(float);
|
var stride = 14 * sizeof(float);
|
||||||
|
|
||||||
// Location 0: Position
|
// Location 0: Position
|
||||||
GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, stride, 0);
|
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)
|
// Location 2: TexCoord (Offset 6 floats: 3 pos + 3 normal)
|
||||||
GL.VertexAttribPointer(2, 2, VertexAttribPointerType.Float, false, stride, 6 * sizeof(float));
|
GL.VertexAttribPointer(2, 2, VertexAttribPointerType.Float, false, stride, 6 * sizeof(float));
|
||||||
GL.EnableVertexAttribArray(2);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -58,8 +58,9 @@ namespace TheLabs
|
|||||||
base.OnLoad();
|
base.OnLoad();
|
||||||
|
|
||||||
// --- Set up Lighting and Material ---
|
// --- Set up Lighting and Material ---
|
||||||
_mainLight = new Lighting(new Vector3(1.2f, 1.0f, 2.0f),
|
_mainLight = new Lighting(new Vector3(
|
||||||
new Vector3(0.3f),
|
1.2f, 1.0f, 2.0f),
|
||||||
|
new Vector3(0.5f),
|
||||||
new Vector3(1.5f),
|
new Vector3(1.5f),
|
||||||
new Vector3(1.0f));
|
new Vector3(1.0f));
|
||||||
|
|
||||||
@ -78,14 +79,17 @@ namespace TheLabs
|
|||||||
|
|
||||||
// -- Load Shaders, Textures, and Create Scene Objects ---
|
// -- Load Shaders, Textures, and Create Scene Objects ---
|
||||||
_shader = new Shader("Shaders/shader.vert", "Shaders/shader.frag");
|
_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 ---
|
// --- Create Scene Graph ---
|
||||||
_rootNode = new SceneNode();
|
_rootNode = new SceneNode();
|
||||||
|
|
||||||
// Create Example Object
|
// Create Example Object
|
||||||
_buildingObject = ShapeFactory.CreateTexturedSphere();
|
_buildingObject = ShapeFactory.CreateTexturedCube();
|
||||||
_buildingRender = new RenderObject(_buildingObject, _shader, _texture, _defaultMaterial, _mainLight);
|
_buildingRender = new RenderObject(_buildingObject, _shader, _texture, _defaultMaterial, _mainLight);
|
||||||
|
_buildingRender.NormalMap = _normalMap;
|
||||||
_buildingNode = new SceneNode(_buildingRender);
|
_buildingNode = new SceneNode(_buildingRender);
|
||||||
_buildingNode.Position = new Vector3(2.0f, -1.0f, 0.0f);
|
_buildingNode.Position = new Vector3(2.0f, -1.0f, 0.0f);
|
||||||
_buildingNode.Scale = new Vector3(0.1f, 0.1f, 0.1f);
|
_buildingNode.Scale = new Vector3(0.1f, 0.1f, 0.1f);
|
||||||
|
|||||||
@ -9,6 +9,7 @@ public class RenderObject
|
|||||||
public Mesh Mesh;
|
public Mesh Mesh;
|
||||||
public Shader Shader;
|
public Shader Shader;
|
||||||
public Texture Texture;
|
public Texture Texture;
|
||||||
|
public Texture NormalMap;
|
||||||
public Material Material;
|
public Material Material;
|
||||||
public Lighting Lighting;
|
public Lighting Lighting;
|
||||||
|
|
||||||
@ -41,7 +42,7 @@ public class RenderObject
|
|||||||
Shader.Use();
|
Shader.Use();
|
||||||
if (Texture != null && UseTexture)
|
if (Texture != null && UseTexture)
|
||||||
{
|
{
|
||||||
Texture.Use();
|
Texture.Use(TextureUnit.Texture0);
|
||||||
Shader.SetInt("uTexture", 0);
|
Shader.SetInt("uTexture", 0);
|
||||||
GL.Uniform1(GL.GetUniformLocation(Shader.Handle, "uUseTexture"), 1);
|
GL.Uniform1(GL.GetUniformLocation(Shader.Handle, "uUseTexture"), 1);
|
||||||
}
|
}
|
||||||
@ -49,6 +50,17 @@ public class RenderObject
|
|||||||
{
|
{
|
||||||
GL.Uniform1(GL.GetUniformLocation(Shader.Handle, "uUseTexture"), 0);
|
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);
|
Material.Apply(Shader);
|
||||||
light.Apply(Shader);
|
light.Apply(Shader);
|
||||||
|
|||||||
@ -9,6 +9,7 @@ out vec4 outputColor; // The final output color of the fragment
|
|||||||
in vec3 FragPos;
|
in vec3 FragPos;
|
||||||
in vec3 Normal;
|
in vec3 Normal;
|
||||||
in vec2 TexCoord;
|
in vec2 TexCoord;
|
||||||
|
in mat3 vTBN; // Tangent, Bitangent, Normal matrix
|
||||||
|
|
||||||
struct MaterialProperty {
|
struct MaterialProperty {
|
||||||
vec3 ambientColour;
|
vec3 ambientColour;
|
||||||
@ -30,10 +31,12 @@ struct LightProperty {
|
|||||||
|
|
||||||
// --- UNIFORMS ---
|
// --- UNIFORMS ---
|
||||||
uniform sampler2D uTexture; // Image Texture
|
uniform sampler2D uTexture; // Image Texture
|
||||||
|
uniform sampler2D uNormalMap; // Normal Map Texture
|
||||||
uniform vec3 uViewPos; // Camera Position
|
uniform vec3 uViewPos; // Camera Position
|
||||||
uniform MaterialProperty uMaterial; // Material Properties
|
uniform MaterialProperty uMaterial; // Material Properties
|
||||||
uniform LightProperty uPointLight; // Light Properties
|
uniform LightProperty uPointLight; // Light Properties
|
||||||
uniform int uUseTexture; // Flag to indicate if texture should be used
|
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) {
|
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()
|
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);
|
vec3 viewDir = normalize(uViewPos - FragPos);
|
||||||
|
|
||||||
// 2. Calculate Lighting using the Function
|
// 2. Calculate Lighting using the Function
|
||||||
@ -76,9 +88,10 @@ void main()
|
|||||||
|
|
||||||
// 3. Apply Texture Switch
|
// 3. Apply Texture Switch
|
||||||
if (uUseTexture == 1) {
|
if (uUseTexture == 1) {
|
||||||
|
|
||||||
outputColor = vec4(result, 1.0) * texture(uTexture, TexCoord);
|
outputColor = vec4(result, 1.0) * texture(uTexture, TexCoord);
|
||||||
} else {
|
} else {
|
||||||
outputColor = vec4(result, 1.0);
|
outputColor = vec4(result, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -7,12 +7,15 @@
|
|||||||
layout(location = 0) in vec3 aPosition; // Raw 3D position
|
layout(location = 0) in vec3 aPosition; // Raw 3D position
|
||||||
layout(location = 1) in vec3 aNormal; // The direction perpendicular to the surface
|
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 = 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 ---
|
// --- OUTPUTS ---
|
||||||
// We can pass data to the fragment shader through these
|
// We can pass data to the fragment shader through these
|
||||||
out vec3 FragPos;
|
out vec3 FragPos;
|
||||||
out vec3 Normal;
|
out vec3 Normal;
|
||||||
out vec2 TexCoord;
|
out vec2 TexCoord;
|
||||||
|
out mat3 vTBN;
|
||||||
|
|
||||||
// --- UNIFORMS ---
|
// --- UNIFORMS ---
|
||||||
// These are matrices that help transform our vertices
|
// These are matrices that help transform our vertices
|
||||||
@ -22,6 +25,12 @@ uniform mat4 projection;
|
|||||||
|
|
||||||
void main(void)
|
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
|
// 1. Calculate World Position
|
||||||
FragPos = vec3(model * vec4(aPosition, 1.0));
|
FragPos = vec3(model * vec4(aPosition, 1.0));
|
||||||
|
|
||||||
|
|||||||
@ -1,72 +1,83 @@
|
|||||||
namespace TheLabs;
|
using OpenTK.Mathematics;
|
||||||
|
|
||||||
|
namespace TheLabs;
|
||||||
|
|
||||||
public static class ShapeFactory
|
public static class ShapeFactory
|
||||||
{
|
{
|
||||||
public static Mesh CreateTexturedCube()
|
public static Mesh CreateTexturedCube()
|
||||||
{
|
{
|
||||||
float[] vertices = {
|
List<Vertex> vertices = new List<Vertex>();
|
||||||
// Format: X, Y, Z, NX, NY, NZ, U, V
|
List<uint> indices = new List<uint>();
|
||||||
|
|
||||||
// --- Front Face (Normal points +Z: 0, 0, 1) ---
|
// --- FRONT FACE (Normal 0, 0, 1) ---
|
||||||
-0.5f, -0.5f, 0.5f, 0f, 0f, 1f, 0f, 0f, // Bottom-left
|
// Sequence: Bottom-Left -> Bottom-Right -> Top-Right -> Top-Left
|
||||||
0.5f, -0.5f, 0.5f, 0f, 0f, 1f, 1f, 0f, // Bottom-right
|
Helpers.AddFace(vertices, indices,
|
||||||
0.5f, 0.5f, 0.5f, 0f, 0f, 1f, 1f, 1f, // Top-right
|
new Vertex(new Vector3(-0.5f, -0.5f, 0.5f), new Vector3(0, 0, 1), new Vector2(0, 0), Vector3.Zero, Vector3.Zero), // BL
|
||||||
-0.5f, 0.5f, 0.5f, 0f, 0f, 1f, 0f, 1f, // Top-left
|
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) ---
|
// --- BACK FACE (Normal 0, 0, -1) ---
|
||||||
-0.5f, -0.5f, -0.5f, 0f, 0f, -1f, 1f, 0f,
|
// Sequence: Bottom-Right -> Bottom-Left -> Top-Left -> Top-Right (Relative to Front view)
|
||||||
0.5f, -0.5f, -0.5f, 0f, 0f, -1f, 0f, 0f,
|
Helpers.AddFace(vertices, indices,
|
||||||
0.5f, 0.5f, -0.5f, 0f, 0f, -1f, 0f, 1f,
|
new Vertex(new Vector3( 0.5f, -0.5f, -0.5f), new Vector3(0, 0, -1), new Vector2(0, 0), Vector3.Zero, Vector3.Zero), // BR
|
||||||
-0.5f, 0.5f, -0.5f, 0f, 0f, -1f, 1f, 1f,
|
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) ---
|
// --- LEFT FACE (Normal -1, 0, 0) ---
|
||||||
-0.5f, -0.5f, -0.5f, -1f, 0f, 0f, 0f, 0f,
|
// Sequence: Back-Left -> Front-Left -> Front-Top -> Back-Top
|
||||||
-0.5f, -0.5f, 0.5f, -1f, 0f, 0f, 1f, 0f,
|
Helpers.AddFace(vertices, indices,
|
||||||
-0.5f, 0.5f, 0.5f, -1f, 0f, 0f, 1f, 1f,
|
new Vertex(new Vector3(-0.5f, -0.5f, -0.5f), new Vector3(-1, 0, 0), new Vector2(0, 0), Vector3.Zero, Vector3.Zero), // BL
|
||||||
-0.5f, 0.5f, -0.5f, -1f, 0f, 0f, 0f, 1f,
|
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) ---
|
// --- RIGHT FACE (Normal 1, 0, 0) ---
|
||||||
0.5f, -0.5f, -0.5f, 1f, 0f, 0f, 1f, 0f,
|
// Sequence: Front-Right -> Back-Right -> Back-Top -> Front-Top
|
||||||
0.5f, -0.5f, 0.5f, 1f, 0f, 0f, 0f, 0f,
|
Helpers.AddFace(vertices, indices,
|
||||||
0.5f, 0.5f, 0.5f, 1f, 0f, 0f, 0f, 1f,
|
new Vertex(new Vector3( 0.5f, -0.5f, 0.5f), new Vector3(1, 0, 0), new Vector2(0, 0), Vector3.Zero, Vector3.Zero), // FR
|
||||||
0.5f, 0.5f, -0.5f, 1f, 0f, 0f, 1f, 1f,
|
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) ---
|
// --- TOP FACE (Normal 0, 1, 0) ---
|
||||||
-0.5f, 0.5f, -0.5f, 0f, 1f, 0f, 0f, 1f,
|
// Sequence: Front-Left -> Front-Right -> Back-Right -> Back-Left
|
||||||
0.5f, 0.5f, -0.5f, 0f, 1f, 0f, 1f, 1f,
|
Helpers.AddFace(vertices, indices,
|
||||||
0.5f, 0.5f, 0.5f, 0f, 1f, 0f, 1f, 0f,
|
new Vertex(new Vector3(-0.5f, 0.5f, 0.5f), new Vector3(0, 1, 0), new Vector2(0, 0), Vector3.Zero, Vector3.Zero), // FL
|
||||||
-0.5f, 0.5f, 0.5f, 0f, 1f, 0f, 0f, 0f,
|
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) ---
|
// --- BOTTOM FACE (Normal 0, -1, 0) ---
|
||||||
-0.5f, -0.5f, -0.5f, 0f, -1f, 0f, 1f, 1f,
|
// Sequence: Front-Left -> Back-Left -> Back-Right -> Front-Right
|
||||||
0.5f, -0.5f, -0.5f, 0f, -1f, 0f, 0f, 1f,
|
Helpers.AddFace(vertices, indices,
|
||||||
0.5f, -0.5f, 0.5f, 0f, -1f, 0f, 0f, 0f,
|
new Vertex(new Vector3(-0.5f, -0.5f, 0.5f), new Vector3(0, -1, 0), new Vector2(0, 1), Vector3.Zero, Vector3.Zero), // FL
|
||||||
-0.5f, -0.5f, 0.5f, 0f, -1f, 0f, 1f, 0f
|
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
|
List<float> finalFloats = new List<float>();
|
||||||
0, 2, 1,
|
|
||||||
0, 2, 3,
|
foreach (var v in vertices)
|
||||||
// Back face
|
{
|
||||||
4, 5, 6,
|
finalFloats.Add(v.Position.X); finalFloats.Add(v.Position.Y); finalFloats.Add(v.Position.Z);
|
||||||
4, 6, 7,
|
finalFloats.Add(v.Normal.X); finalFloats.Add(v.Normal.Y); finalFloats.Add(v.Normal.Z);
|
||||||
// Left face
|
finalFloats.Add(v.TexCoords.X); finalFloats.Add(v.TexCoords.Y);
|
||||||
8, 9, 10,
|
|
||||||
8, 10, 11,
|
// --- NEW: Add Tangent and Bitangent ---
|
||||||
// Right face
|
finalFloats.Add(v.Tangent.X); finalFloats.Add(v.Tangent.Y); finalFloats.Add(v.Tangent.Z);
|
||||||
12, 14, 13,
|
finalFloats.Add(v.Bitangent.X); finalFloats.Add(v.Bitangent.Y); finalFloats.Add(v.Bitangent.Z);
|
||||||
12, 14, 15,
|
}
|
||||||
// Top face
|
|
||||||
16, 17, 18,
|
|
||||||
16, 18, 19,
|
|
||||||
// Bottom face
|
|
||||||
20, 22, 21,
|
|
||||||
20, 22, 23
|
|
||||||
};
|
|
||||||
|
|
||||||
return new Mesh(vertices, indices, Mesh.VertexLayout.PosTexNormal);
|
return new Mesh(finalFloats.ToArray(), indices.ToArray(), Mesh.VertexLayout.PosTexNormalTangent);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Mesh CreateColouredCircle()
|
public static Mesh CreateColouredCircle()
|
||||||
@ -321,6 +332,26 @@ public static class ShapeFactory
|
|||||||
|
|
||||||
return new Mesh(vertices.ToArray(), indices.ToArray(), Mesh.VertexLayout.PosTexNormal);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
22
TheRepo/TheLabs/Vertex.cs
Normal file
22
TheRepo/TheLabs/Vertex.cs
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user