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
Compare commits
2 Commits
fe63a6d938
...
da9990908a
| Author | SHA1 | Date | |
|---|---|---|---|
| da9990908a | |||
| d2b3027a11 |
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);
|
||||
}
|
||||
}
|
||||
@ -11,12 +11,21 @@ public struct Lighting
|
||||
public Vector3 diffuseColour;
|
||||
public Vector3 specularColour;
|
||||
|
||||
public float constant;
|
||||
public float linear;
|
||||
public float quadratic;
|
||||
|
||||
public Lighting(Vector3 pos, Vector3 ambient, Vector3 diffuse, Vector3 specular)
|
||||
{
|
||||
position = pos;
|
||||
ambientColour = ambient;
|
||||
diffuseColour = diffuse;
|
||||
specularColour = specular;
|
||||
|
||||
constant = 1.0f;
|
||||
linear = 0.09f;
|
||||
quadratic = 0.032f;
|
||||
|
||||
}
|
||||
|
||||
public void Apply(Shader shader)
|
||||
@ -25,5 +34,10 @@ public struct Lighting
|
||||
GL.Uniform3(GL.GetUniformLocation(shader.Handle, "uPointLight.ambientColour"), ref ambientColour);
|
||||
GL.Uniform3(GL.GetUniformLocation(shader.Handle, "uPointLight.diffuseColour"), ref diffuseColour);
|
||||
GL.Uniform3(GL.GetUniformLocation(shader.Handle, "uPointLight.specularColour"), ref specularColour);
|
||||
|
||||
GL.Uniform1(GL.GetUniformLocation(shader.Handle, "uPointLight.constant"), constant);
|
||||
GL.Uniform1(GL.GetUniformLocation(shader.Handle, "uPointLight.linear"), linear);
|
||||
GL.Uniform1(GL.GetUniformLocation(shader.Handle, "uPointLight.quadratic"), quadratic);
|
||||
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -16,6 +17,7 @@ public class RenderObject
|
||||
public Matrix4 Transform = Matrix4.Identity;
|
||||
public Quaternion Rotation = Quaternion.Identity;
|
||||
public Vector3 Scale = Vector3.One;
|
||||
public bool UseTexture = true;
|
||||
|
||||
public RenderObject(Mesh mesh, Shader shader, Texture texture, Material material, Lighting lighting)
|
||||
{
|
||||
@ -38,8 +40,27 @@ public class RenderObject
|
||||
Material mat = new Material(pink * 0.1f, pink * 0.6f, Vector3.One, 32.0f);
|
||||
|
||||
Shader.Use();
|
||||
Texture.Use();
|
||||
if (Texture != null && UseTexture)
|
||||
{
|
||||
Texture.Use(TextureUnit.Texture0);
|
||||
Shader.SetInt("uTexture", 0);
|
||||
GL.Uniform1(GL.GetUniformLocation(Shader.Handle, "uUseTexture"), 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
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);
|
||||
|
||||
@ -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;
|
||||
@ -22,60 +23,75 @@ struct LightProperty {
|
||||
vec3 ambientColour;
|
||||
vec3 diffuseColour;
|
||||
vec3 specularColour;
|
||||
|
||||
float constant;
|
||||
float linear;
|
||||
float quadratic;
|
||||
};
|
||||
|
||||
// --- 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) {
|
||||
vec3 lightDir = normalize(light.position - fragPos);
|
||||
|
||||
// 1. Diffuse shading
|
||||
float diff = max(dot(normal, lightDir), 0.0);
|
||||
|
||||
// 2. Specular shading
|
||||
vec3 reflectDir = reflect(-lightDir, normal);
|
||||
float spec = pow(max(dot(viewDir, reflectDir), 0.0), uMaterial.shininess);
|
||||
|
||||
// 3. Attenuation
|
||||
float distance = length(light.position - fragPos);
|
||||
float attenuation = 1.0 / (light.constant + light.linear * distance +
|
||||
light.quadratic * (distance * distance));
|
||||
|
||||
// 4. Combine results
|
||||
vec3 ambient = light.ambientColour * uMaterial.ambientColour;
|
||||
vec3 diffuse = light.diffuseColour * diff * uMaterial.diffuseColour;
|
||||
vec3 specular = light.specularColour * spec * uMaterial.specularColour;
|
||||
|
||||
ambient *= attenuation;
|
||||
diffuse *= attenuation;
|
||||
specular *= attenuation;
|
||||
|
||||
return (ambient + diffuse + specular);
|
||||
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
// --- LIGHTING CALCULATIONS ---
|
||||
// Lighting Setup (hardcoded for simplicity)
|
||||
vec3 lightPos = vec3(1.2f, 1.0f, 2.0f);
|
||||
vec3 lightColor = vec3(1.0f, 1.0f, 1.0f);
|
||||
vec3 norm;
|
||||
|
||||
// 1. Get Texture Color
|
||||
// Sample the texture at the given texture coordinates
|
||||
vec4 objColor = texture(uTexture, TexCoord);
|
||||
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);
|
||||
}
|
||||
|
||||
vec3 viewDir = normalize(uViewPos - FragPos);
|
||||
|
||||
// 2. Calculate Lighting using the Function
|
||||
vec3 result = CalcPointLight(uPointLight, norm, FragPos, viewDir);
|
||||
|
||||
// 3. Apply Texture Switch
|
||||
if (uUseTexture == 1) {
|
||||
|
||||
outputColor = vec4(result, 1.0) * texture(uTexture, TexCoord);
|
||||
} else {
|
||||
outputColor = vec4(result, 1.0);
|
||||
}
|
||||
|
||||
// 2. Ambient strength
|
||||
// A constant, dim light that ensure s object are not completely dark
|
||||
// It simply multiplies the light color by a small factor
|
||||
float ambientStrength = 0.1f;
|
||||
vec3 ambient = uMaterial.ambientColour * uPointLight.ambientColour;
|
||||
|
||||
// 3. Diffuse
|
||||
// Creates the "matte" effect by calculating the angle between the light direction and the surface normal
|
||||
|
||||
// Normalize the normal vector and calculate the light direction
|
||||
vec3 norm = normalize(Normal);
|
||||
vec3 lightDir = normalize(uPointLight.position - FragPos);
|
||||
|
||||
// The dot product gives us the cosine of the angle between the two vectors
|
||||
// The max function ensures we don't get negative values (light coming from behind the surface)
|
||||
float diff = max(dot(norm, lightDir), 0.0f);
|
||||
vec3 diffuse = (uPointLight.diffuseColour * diff) * uMaterial.diffuseColour;
|
||||
|
||||
// 4. Specular
|
||||
// Creates the shiny highlights on the surface
|
||||
float shininess = 32.0f;
|
||||
// Calculate the view direction and the reflection direction
|
||||
vec3 viewDirection = normalize(uViewPos - FragPos);
|
||||
// If the light is coming from the light direction, we need to negate it for reflection
|
||||
vec3 reflectDirection = reflect(-lightDir, normalize(Normal));
|
||||
|
||||
// Calculate the specular component using the dot product and shininess factor
|
||||
float spec = pow(max(dot(viewDirection, reflectDirection), 0.0f), shininess);
|
||||
vec3 specular = uMaterial.specularColour * spec * uPointLight.specularColour;
|
||||
|
||||
// 5. Combine
|
||||
// We multiply (Ambient + Diffuse) by the Texture Color.
|
||||
// We ADD Specular afterwards so the highlights look bright white (like plastic/metal).
|
||||
vec3 result = (ambient + diffuse) * objColor.rgb + specular;
|
||||
|
||||
outputColor = vec4(result, objColor.a);
|
||||
}
|
||||
@ -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));
|
||||
|
||||
|
||||
@ -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<Vertex> vertices = new List<Vertex>();
|
||||
List<uint> indices = new List<uint>();
|
||||
|
||||
// --- 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<float> finalFloats = new List<float>();
|
||||
|
||||
return new Mesh(vertices, indices, Mesh.VertexLayout.PosTexNormal);
|
||||
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(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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
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