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
167 lines
6.2 KiB
C#
167 lines
6.2 KiB
C#
namespace TheLabs;
|
|
using LearnOpenTK.Common;
|
|
using OpenTK.Graphics.OpenGL4;
|
|
using OpenTK.Mathematics;
|
|
using System;
|
|
|
|
public class Mesh : IDisposable
|
|
{
|
|
private readonly int _vao;
|
|
private readonly int _vbo;
|
|
private readonly int _ebo;
|
|
private readonly int _vertexCount;
|
|
private readonly bool _useIndices;
|
|
|
|
public enum VertexLayout { PosColor, PosTex, PosTexNormal, PosTexNormalTangent }
|
|
|
|
public Mesh(float[] vertices, uint[] indices, VertexLayout layout)
|
|
{
|
|
_vertexCount = indices.Length;
|
|
_useIndices = true;
|
|
|
|
_vao = GL.GenVertexArray();
|
|
GL.BindVertexArray(_vao);
|
|
|
|
_vbo = GL.GenBuffer();
|
|
GL.BindBuffer(BufferTarget.ArrayBuffer, _vbo);
|
|
GL.BufferData(BufferTarget.ArrayBuffer, vertices.Length * sizeof(float), vertices, BufferUsageHint.StaticDraw);
|
|
|
|
_ebo = GL.GenBuffer();
|
|
GL.BindBuffer(BufferTarget.ElementArrayBuffer, _ebo);
|
|
GL.BufferData(BufferTarget.ElementArrayBuffer, indices.Length * sizeof(uint), indices, BufferUsageHint.StaticDraw);
|
|
|
|
SetupAttributes(layout); // Refactored into a helper method to avoid duplication
|
|
|
|
GL.BindVertexArray(0);
|
|
}
|
|
|
|
public Mesh(float[] vertices, VertexLayout layout)
|
|
{
|
|
// Calculate vertex count based on the layout size
|
|
int strideCount = 0;
|
|
if (layout == VertexLayout.PosColor) strideCount = 7;
|
|
else if (layout == VertexLayout.PosTex) strideCount = 5;
|
|
else if (layout == VertexLayout.PosTexNormal) strideCount = 8;
|
|
|
|
_vertexCount = vertices.Length / strideCount;
|
|
_useIndices = false;
|
|
_ebo = 0;
|
|
|
|
_vao = GL.GenVertexArray();
|
|
GL.BindVertexArray(_vao);
|
|
|
|
_vbo = GL.GenBuffer();
|
|
GL.BindBuffer(BufferTarget.ArrayBuffer, _vbo);
|
|
GL.BufferData(BufferTarget.ArrayBuffer, vertices.Length * sizeof(float), vertices, BufferUsageHint.StaticDraw);
|
|
|
|
SetupAttributes(layout);
|
|
|
|
GL.BindVertexArray(0);
|
|
}
|
|
|
|
// Helper method to set up pointers (shared by both constructors)
|
|
private void SetupAttributes(VertexLayout layout)
|
|
{
|
|
if (layout == VertexLayout.PosColor)
|
|
{
|
|
// Stride = 7 floats (3 Pos + 4 Color)
|
|
var stride = 14 * sizeof(float);
|
|
|
|
// Location 0: Position
|
|
GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, stride, 0);
|
|
GL.EnableVertexAttribArray(0);
|
|
|
|
// Location 1: Color
|
|
GL.VertexAttribPointer(1, 4, VertexAttribPointerType.Float, false, stride, 3 * sizeof(float));
|
|
GL.EnableVertexAttribArray(1);
|
|
|
|
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)
|
|
{
|
|
// Stride = 5 floats (3 Pos + 2 Tex)
|
|
var stride = 5 * sizeof(float);
|
|
|
|
// Location 0: Position
|
|
GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, stride, 0);
|
|
GL.EnableVertexAttribArray(0);
|
|
|
|
// Location 2: TexCoord (I used 2 to match the Normal layout below, but 1 works too if you change shader)
|
|
// Let's keep it at 1 for now to break less code, but for lighting we usually move Tex to 2.
|
|
// For now, let's assume your shader uses Location 2 for Texture if using Normals.
|
|
GL.VertexAttribPointer(2, 2, VertexAttribPointerType.Float, false, stride, 3 * sizeof(float));
|
|
GL.EnableVertexAttribArray(2);
|
|
}
|
|
else if (layout == VertexLayout.PosTexNormal)
|
|
{
|
|
// Stride = 8 floats (3 Pos + 3 Normal + 2 Tex)
|
|
var stride = 14 * sizeof(float);
|
|
|
|
// Location 0: Position
|
|
GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, stride, 0);
|
|
GL.EnableVertexAttribArray(0);
|
|
|
|
// Location 1: Normal (Offset 3 floats)
|
|
GL.VertexAttribPointer(1, 3, VertexAttribPointerType.Float, false, stride, 3 * sizeof(float));
|
|
GL.EnableVertexAttribArray(1);
|
|
|
|
// 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);
|
|
}
|
|
}
|
|
|
|
public void Draw()
|
|
{
|
|
GL.BindVertexArray(_vao);
|
|
if (_useIndices)
|
|
{
|
|
GL.DrawElements(PrimitiveType.Triangles, _vertexCount, DrawElementsType.UnsignedInt, 0);
|
|
}
|
|
else
|
|
{
|
|
GL.DrawArrays(PrimitiveType.TriangleFan, 0, _vertexCount);
|
|
}
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
GL.DeleteBuffer(_vbo);
|
|
GL.DeleteBuffer(_ebo);
|
|
GL.DeleteVertexArray(_vao);
|
|
}
|
|
} |