From ced63735a5c02f37c7ab955782cb957fee60878a Mon Sep 17 00:00:00 2001 From: zyb3rwolfi Date: Tue, 7 Oct 2025 12:53:30 +0100 Subject: [PATCH] Added cylinder class --- TheRepo/TheLabs/MyExampleWindow.cs | 7 +- TheRepo/TheLabs/Shapes/Circle.cs | 21 +++-- TheRepo/TheLabs/Shapes/Cylinder.cs | 124 +++++++++++++++++++++++++++++ 3 files changed, 142 insertions(+), 10 deletions(-) create mode 100644 TheRepo/TheLabs/Shapes/Cylinder.cs diff --git a/TheRepo/TheLabs/MyExampleWindow.cs b/TheRepo/TheLabs/MyExampleWindow.cs index d05d4ef..fc87e25 100644 --- a/TheRepo/TheLabs/MyExampleWindow.cs +++ b/TheRepo/TheLabs/MyExampleWindow.cs @@ -36,6 +36,7 @@ namespace TheLabs private Cube _cube; private Circle _circle; + private Cylinder _cylinder; private Shader _shader; private float _rotation; @@ -58,6 +59,7 @@ namespace TheLabs // Create a cube _cube = new Cube(); _circle = new Circle(); + _cylinder = new Cylinder(); // Use the shader program. This is similar to "activating" the shader program. _shader.Use(); @@ -93,8 +95,9 @@ namespace TheLabs GL.UniformMatrix4(projLoc, false, ref projection); // Draw the cube - _cube.Draw(_shader, model); - _circle.Draw(_shader, model); + //_cube.Draw(_shader, model); + //_circle.Draw(_shader, model); + _cylinder.Draw(_shader, model); SwapBuffers(); GL.GetError(); } diff --git a/TheRepo/TheLabs/Shapes/Circle.cs b/TheRepo/TheLabs/Shapes/Circle.cs index ccb2b28..9a05f00 100644 --- a/TheRepo/TheLabs/Shapes/Circle.cs +++ b/TheRepo/TheLabs/Shapes/Circle.cs @@ -18,9 +18,10 @@ public class Circle }; private int _maxVert = 100; - public Circle() + public Circle(float z = 0f, int segments = 100, Vector4? color = null) { - for (int i = 0; i <= _maxVert; i++) + Vector4 col = color ?? new Vector4(0f, 0f, 1f, 1f); + for (int i = 0; i <= segments; i++) { float angle = i * 2.0f * MathF.PI / _maxVert; @@ -30,11 +31,11 @@ public class Circle Array.Resize(ref _vertices, _vertices.Length + 7); _vertices[^7] = x; _vertices[^6] = y; - _vertices[^5] = 0.0f; - _vertices[^4] = 1f; - _vertices[^3] = 0f; - _vertices[^2] = 0f; - _vertices[^1] = 1f; + _vertices[^5] = z; + _vertices[^4] = col.X; + _vertices[^3] = col.Y; + _vertices[^2] = col.Z; + _vertices[^1] = col.W; } // The Vertex Array Object @@ -66,12 +67,16 @@ public class Circle GL.BindVertexArray(0); } + public float[] GetVertices() + { + return _vertices; + } public void Draw(Shader shader, Matrix4 matrix4) { shader.SetMatrix4("model", matrix4); GL.BindVertexArray(_vao); GL.DrawArrays(PrimitiveType.TriangleFan, 0, _vertices.Length / 7); - + } public void Dispose() diff --git a/TheRepo/TheLabs/Shapes/Cylinder.cs b/TheRepo/TheLabs/Shapes/Cylinder.cs new file mode 100644 index 0000000..fdba6d7 --- /dev/null +++ b/TheRepo/TheLabs/Shapes/Cylinder.cs @@ -0,0 +1,124 @@ +using LearnOpenTK.Common; +using OpenTK.Graphics.OpenGL4; +using OpenTK.Mathematics; +using OpenTK.Windowing.Desktop; + +namespace TheLabs.Shapes; + +public class Cylinder +{ + // Vertex Array Object, Vertex Buffer Object, Element Buffer Object + private int _vao; + private int _vbo; + private int _ebo; + private int _vertexCount; + private Circle _topCircle; + private Circle _bottomCircle; + private float _radius = 0.5f; + private float _height = 1.0f; + + private float[] _vertices = + { + }; + + private uint[] _indices = + { + + }; + public Cylinder() + { + // The number of vertices to draw + _vertexCount = _indices.Length; + _topCircle = new Circle(0.5f, 100, new Vector4(1f, 1f, 0f, 1f)); + _bottomCircle = new Circle(-0.5f, 100, new Vector4(1f, 0f, 0f, 1f)); + GenerateCylinder(101); + + } + + private void GenerateCylinder(int segments) + { + var vertices = new List(); + var indices = new List(); + + for (int i = 0; i < segments; i++) + { + float angle1 = 2.0f * MathF.PI * i / segments; + float angle2 = 2.0f * MathF.PI * ((i + 1) % segments) / segments; + + float x1 = _radius * MathF.Cos(angle1); + float y1 = _radius * MathF.Sin(angle1); + float x2 = _radius * MathF.Cos(angle2); + float y2 = _radius * MathF.Sin(angle2); + + float zTop = _height / 2f; + float zBottom = -_height / 2f; + + Vector4 sideColor = new Vector4(0f, 1f, 1f, 1f); // side color + + // Add vertices: top1, bottom1, top2, bottom2 + int top1Index = vertices.Count / 7; + vertices.AddRange(new float[] { x1, y1, zTop, sideColor.X, sideColor.Y, sideColor.Z, sideColor.W }); + + int bottom1Index = vertices.Count / 7; + vertices.AddRange(new float[] { x1, y1, zBottom, sideColor.X, sideColor.Y, sideColor.Z, sideColor.W }); + + int top2Index = vertices.Count / 7; + vertices.AddRange(new float[] { x2, y2, zTop, sideColor.X, sideColor.Y, sideColor.Z, sideColor.W }); + + int bottom2Index = vertices.Count / 7; + vertices.AddRange(new float[] { x2, y2, zBottom, sideColor.X, sideColor.Y, sideColor.Z, sideColor.W }); + + // First triangle + indices.Add((uint)top1Index); + indices.Add((uint)bottom1Index); + indices.Add((uint)top2Index); + + // Second triangle + indices.Add((uint)top2Index); + indices.Add((uint)bottom1Index); + indices.Add((uint)bottom2Index); + } + + _vertices = vertices.ToArray(); + _indices = indices.ToArray(); + _vertexCount = indices.Count; + + // OpenGL setup + _vao = GL.GenVertexArray(); + _vbo = GL.GenBuffer(); + _ebo = GL.GenBuffer(); + + GL.BindVertexArray(_vao); + + GL.BindBuffer(BufferTarget.ArrayBuffer, _vbo); + GL.BufferData(BufferTarget.ArrayBuffer, vertices.Count * sizeof(float), vertices.ToArray(), BufferUsageHint.StaticDraw); + + GL.BindBuffer(BufferTarget.ElementArrayBuffer, _ebo); + GL.BufferData(BufferTarget.ElementArrayBuffer, indices.Count * sizeof(uint), indices.ToArray(), BufferUsageHint.StaticDraw); + + var stride = 7 * sizeof(float); + GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, stride, 0); + GL.EnableVertexAttribArray(0); + GL.VertexAttribPointer(1, 4, VertexAttribPointerType.Float, false, stride, 3 * sizeof(float)); + GL.EnableVertexAttribArray(1); + + GL.BindVertexArray(0); + } + + public void Draw(Shader shader, Matrix4 matrix4) + { + shader.SetMatrix4("model", matrix4); + + GL.BindVertexArray(_vao); + GL.DrawElements(PrimitiveType.Triangles, _indices.Length, DrawElementsType.UnsignedInt, 0); + _topCircle.Draw(shader, matrix4); + _bottomCircle.Draw(shader, matrix4); + } + + public void Dispose() + { + GL.DeleteBuffer(_vbo); + GL.DeleteBuffer(_ebo); + GL.DeleteVertexArray(_vao); + } +} \ No newline at end of file