added shapes cewl

This commit is contained in:
zyb3rwolfi 2025-11-13 11:55:07 +00:00
parent 87804fc932
commit 4e7875bed3
3 changed files with 203 additions and 27 deletions

24
TheRepo/TheLabs/Camera.cs Normal file
View File

@ -0,0 +1,24 @@
using OpenTK.Mathematics;
namespace TheLabs;
public class Camera
{
public Vector3 _position = new Vector3(0.0f, 0.0f, -3.0f);
public Vector3 _target = new Vector3(0.0f, 0.0f, -1.0f);
public Vector3 _up;
public Camera(Vector3 position, Vector3 target, Vector3 up)
{
_position = position;
_target = target;
_up = up;
}
public Matrix4 LookAt()
{
return Matrix4.LookAt(_position, _position + _target, _up);
}
}

View File

@ -17,9 +17,11 @@ namespace TheLabs
// OpenGL only supports rendering in 3D, so to create a flat triangle, the Z coordinate will be kept as 0.
private Shader _shader;
private Camera _camera;
// - Resources that only need to be created once
private Mesh _cubeMesh;
private Mesh _circleMesh;
private Mesh _cylinderMesh;
private Texture _cubeTexture;
private Texture _cubeTexture2;
private float _rotation;
@ -27,6 +29,8 @@ namespace TheLabs
// -- Scene Objects
private RenderObject _cubeObject;
private RenderObject _cubeObject2;
private RenderObject _circleObject;
private RenderObject _cylinderObject;
private Vector3 _cameraPosition = new Vector3(0.0f, 0.0f, -3.0f);
private Vector3 _cameraFront = new Vector3(0.0f, 0.0f, -1.0f);
@ -60,15 +64,22 @@ namespace TheLabs
// Set The background color to a nice blue.
GL.ClearColor(0.2f, 0.3f, 0.3f, 1.0f);
GL.Enable(EnableCap.DepthTest);
_camera = new Camera(_cameraPosition, _cameraFront, _cameraUp);
CursorState = CursorState.Grabbed;
_shader = new Shader("Shaders/shader.vert", "Shaders/shader.frag");
_cubeMesh = ShapeFactory.CreateTexturedCube();
_circleMesh = ShapeFactory.CreateTexturedCircle();
_cylinderMesh = ShapeFactory.CreateTexturedCylinder();
_cubeTexture = new Texture("Textures/stone.jpg");
_cubeTexture2 = new Texture("Textures/placeholder.png");
_cubeObject = new RenderObject(_cubeMesh, _shader, _cubeTexture);
_cubeObject2 = new RenderObject(_cubeMesh, _shader, _cubeTexture2);
_circleObject = new RenderObject(_circleMesh, _shader, _cubeTexture);
_cylinderObject = new RenderObject(_cylinderMesh, _shader, _cubeTexture2);
_cylinderObject.Position = new Vector3(-2.5f, 0.0f, 0.0f);
_cubeObject.Position = new Vector3(-1.5f, 0.0f, 0.0f);
_cubeObject2.Position = new Vector3(1.5f, 0.0f, 0.0f);
_circleObject.Position = new Vector3(2.5f, 0.0f, 0.0f);
_cubeObject.Scale = new Vector3(0.5f, 0.5f, 0.5f);
_cubeObject2.Scale = new Vector3(0.5f, 0.5f, 0.5f);
@ -86,7 +97,7 @@ namespace TheLabs
_cubeObject2.Rotation = Quaternion.FromEulerAngles(-_rotation * 0.5f, -_rotation, 0);
// --- Set up Camera ---
Matrix4 view = Matrix4.LookAt(_cameraPosition, _cameraPosition + _cameraFront, _cameraUp);
Matrix4 view = _camera.LookAt();
float aspectRatio = (float)Size.X / Size.Y;
// 2. Add a safety check for divide-by-zero
@ -103,6 +114,8 @@ namespace TheLabs
_cubeObject.Draw(view, projection);
_cubeObject2.Draw(view, projection);
_circleObject.Draw(view, projection);
_cylinderObject.Draw(view, projection);
SwapBuffers();
}
@ -148,29 +161,30 @@ namespace TheLabs
{
_yaw -= _rotationSpeed * (float)e.Time;
}
if (input.IsKeyDown(Keys.Right))
{
_yaw += _rotationSpeed * (float)e.Time;
}
if (input.IsKeyDown(Keys.Up))
{
_pitch += _rotationSpeed * (float)e.Time;
}
if (input.IsKeyDown(Keys.Down))
{
_pitch -= _rotationSpeed * (float)e.Time;
}
if (input.IsKeyDown(Keys.Right))
{
_yaw += _rotationSpeed * (float)e.Time;
}
if (input.IsKeyDown(Keys.Up))
{
_pitch += _rotationSpeed * (float)e.Time;
}
if (input.IsKeyDown(Keys.Down))
{
_pitch -= _rotationSpeed * (float)e.Time;
}
_pitch = MathHelper.Clamp(_pitch, -89.0f, 89.0f);
Vector3 front;
front.X = MathF.Cos(MathHelper.DegreesToRadians(_yaw)) * MathF.Cos(MathHelper.DegreesToRadians(_pitch));
front.Y = MathF.Sin(MathHelper.DegreesToRadians(_pitch));
front.Z = MathF.Sin(MathHelper.DegreesToRadians(_yaw)) * MathF.Cos(MathHelper.DegreesToRadians(_pitch));
_cameraFront = Vector3.Normalize(front);
var _cameraRight = Vector3.Normalize(Vector3.Cross(_cameraFront, _cameraUp));
if (input.IsKeyDown(Keys.W)) _cameraPosition += _cameraFront * _cameraSpeed * (float)e.Time;
if (input.IsKeyDown(Keys.S)) _cameraPosition -= _cameraFront * _cameraSpeed * (float)e.Time;
if (input.IsKeyDown(Keys.A)) _cameraPosition -= _cameraRight * _cameraSpeed * (float)e.Time;
if (input.IsKeyDown(Keys.D)) _cameraPosition += _cameraRight * _cameraSpeed * (float)e.Time;
_camera._target.X = MathF.Cos(MathHelper.DegreesToRadians(_yaw)) * MathF.Cos(MathHelper.DegreesToRadians(_pitch));
_camera._target.Y = MathF.Sin(MathHelper.DegreesToRadians(_pitch));
_camera._target.Z = MathF.Sin(MathHelper.DegreesToRadians(_yaw)) * MathF.Cos(MathHelper.DegreesToRadians(_pitch));
_cameraFront = Vector3.Normalize(_camera._target);
var _cameraRight = Vector3.Normalize(Vector3.Cross(_cameraFront, _camera._up));
if (input.IsKeyDown(Keys.W)) _camera._position += _cameraFront * _cameraSpeed * (float)e.Time;
if (input.IsKeyDown(Keys.S)) _camera._position -= _cameraFront * _cameraSpeed * (float)e.Time;
if (input.IsKeyDown(Keys.A)) _camera._position -= _cameraRight * _cameraSpeed * (float)e.Time;
if (input.IsKeyDown(Keys.D)) _camera._position += _cameraRight * _cameraSpeed * (float)e.Time;
}

View File

@ -66,6 +66,60 @@ public static class ShapeFactory
return new Mesh(vertices, indices, Mesh.VertexLayout.PosTex);
}
public static Mesh CreateColouredCircle()
{
float[] vertices = {
};
int segments = 100;
for (int i = 0; i <= segments; i++)
{
float angle = i * 2.0f * MathF.PI / segments;
float x = 0.5f * MathF.Cos(angle);
float y = 0.5f * MathF.Sin(angle);
Array.Resize(ref vertices, vertices.Length + 7);
vertices[^7] = x;
vertices[^6] = y;
vertices[^5] = 0f;
}
return new Mesh(vertices, Mesh.VertexLayout.PosColor);
}
public static Mesh CreateTexturedCircle()
{
var vertices = new List<float>();
int segments = 100;
vertices.Add(0f); // Center X
vertices.Add(0f); // Center Y
vertices.Add(0f); // Center Z
vertices.Add(0.5f); // Center U
vertices.Add(0.5f); // Center V
for (int i = 0; i <= segments; i++)
{
float angle = i * 2.0f * MathF.PI / segments;
float x = 0.5f * MathF.Cos(angle);
float y = 0.5f * MathF.Sin(angle);
vertices.Add(x); // X
vertices.Add(y); // Y
vertices.Add(0f); // Z
vertices.Add((x + 0.5f)); // U
vertices.Add((y + 0.5f)); // V
}
return new Mesh(vertices.ToArray(), Mesh.VertexLayout.PosTex);
}
public static Mesh CreateColorCube()
{
float[] vertices = {
@ -111,8 +165,92 @@ public static class ShapeFactory
return new Mesh(vertices, indices, Mesh.VertexLayout.PosColor);
}
// You'd also add CreateCircle, CreateCylinder, etc.
// Your Cylinder should be ONE mesh, not 3 draw calls.
// Generate the top, bottom, and side vertices into one
// big array and use one EBO for all of it.
public static Mesh CreateTexturedCylinder(int segments = 32, float height = 1.0f, float radius = 0.5f)
{
var vertices = new List<float>();
var indices = new List<uint>();
uint vertexIndex = 0;
float halfHeight = height / 2.0f;
uint topCenterIndex = vertexIndex;
vertices.AddRange(new[]
{
0.0f, halfHeight, 0.0f, // Position
0.5f, 0.5f
}); // Top center vertex
vertexIndex++;
uint topStartIndex = vertexIndex;
for (int i = 0; i <= segments; i++)
{
float angle = i * 2.0f * MathF.PI / segments;
float x = radius * MathF.Cos(angle);
float z = radius * MathF.Sin(angle);
// UV coordinates are mapped from model space (-0.5 to +0.5)
// to texture space (0.0 to 1.0)
float u = x / (radius * 2) + 0.5f;
float v = z / (radius * 2) + 0.5f;
vertices.AddRange(new[] { x, halfHeight, z, u, v });
vertexIndex++;
}
// Add Top Cap Indices (Triangle Fan)
for (int i = 0; i < segments; i++)
{
indices.Add(topCenterIndex);
indices.Add(topStartIndex + (uint)i);
indices.Add(topStartIndex + (uint)((i + 1) % segments)); // Wrap around
}
uint sideStartIndex = vertexIndex;
// Loop from 0 to segments (inclusive) to get (segments + 1)
// vertices for wrapping the texture seamlessly.
for (int i = 0; i <= segments; i++)
{
float angle = i * 2.0f * MathF.PI / segments;
float x = radius * MathF.Cos(angle);
float z = radius * MathF.Sin(angle);
// The U coordinate goes from 0.0 to 1.0 around the cylinder
float u = (float)i / segments;
// Add Top Side Vertex
vertices.AddRange(new[] { x, halfHeight, z, u, 1.0f }); // V = 1.0 (top)
vertexIndex++;
// Add Bottom Side Vertex
vertices.AddRange(new[] { x, -halfHeight, z, u, 0.0f }); // V = 0.0 (bottom)
vertexIndex++;
}
// Add Side Wall Indices (Quad Strip)
for (int i = 0; i < segments; i++)
{
// Each segment has 2 vertices (top, bottom)
// We reference the vertices we just created.
uint topCurrent = sideStartIndex + (uint)(i * 2);
uint bottomCurrent = topCurrent + 1;
uint topNext = sideStartIndex + (uint)((i + 1) * 2);
uint bottomNext = topNext + 1;
// Triangle 1 (CCW)
indices.Add(topCurrent);
indices.Add(bottomCurrent);
indices.Add(topNext);
// Triangle 2 (CCW)
indices.Add(bottomCurrent);
indices.Add(bottomNext);
indices.Add(topNext);
}
// --- 4. Create the Mesh ---
return new Mesh(vertices.ToArray(), indices.ToArray(), Mesh.VertexLayout.PosTex);
}
}