From 4e7875bed331e9d91a98c9649d6e45fd56fcc8a6 Mon Sep 17 00:00:00 2001 From: zyb3rwolfi Date: Thu, 13 Nov 2025 11:55:07 +0000 Subject: [PATCH] added shapes cewl --- TheRepo/TheLabs/Camera.cs | 24 +++++ TheRepo/TheLabs/MyExampleWindow.cs | 60 +++++++----- TheRepo/TheLabs/ShapeFactory.cs | 146 ++++++++++++++++++++++++++++- 3 files changed, 203 insertions(+), 27 deletions(-) create mode 100644 TheRepo/TheLabs/Camera.cs diff --git a/TheRepo/TheLabs/Camera.cs b/TheRepo/TheLabs/Camera.cs new file mode 100644 index 0000000..3eb72b1 --- /dev/null +++ b/TheRepo/TheLabs/Camera.cs @@ -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); + } + + +} \ No newline at end of file diff --git a/TheRepo/TheLabs/MyExampleWindow.cs b/TheRepo/TheLabs/MyExampleWindow.cs index 21c6fc2..28cebc2 100644 --- a/TheRepo/TheLabs/MyExampleWindow.cs +++ b/TheRepo/TheLabs/MyExampleWindow.cs @@ -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; } diff --git a/TheRepo/TheLabs/ShapeFactory.cs b/TheRepo/TheLabs/ShapeFactory.cs index a148011..300b176 100644 --- a/TheRepo/TheLabs/ShapeFactory.cs +++ b/TheRepo/TheLabs/ShapeFactory.cs @@ -65,6 +65,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(); + + 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() { @@ -110,9 +164,93 @@ public static class ShapeFactory return new Mesh(vertices, indices, Mesh.VertexLayout.PosColor); } + + public static Mesh CreateTexturedCylinder(int segments = 32, float height = 1.0f, float radius = 0.5f) + { + var vertices = new List(); + var indices = new List(); + 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); + } + - // 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. } \ No newline at end of file