using LearnOpenTK.Common; using OpenTK.Graphics.OpenGL4; using OpenTK.Mathematics; namespace TheLabs.Shapes; public class Circle { // Vertex Array Object, Vertex Buffer Object, Element Buffer Object private int _vao; private int _vbo; private readonly float[] _vertices = { }; public Circle(float z = 0f, int segments = 100, Vector4? color = null) { Vector4 col = color ?? new Vector4(0f, 0f, 1f, 1f); 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] = z; _vertices[^4] = col.X; _vertices[^3] = col.Y; _vertices[^2] = col.Z; _vertices[^1] = col.W; } // The Vertex Array Object // This stores the confifuration of vertex atributes _vao = GL.GenVertexArray(); // The Vertex Buffer Object // This stores the actual vertex data e.g. positions, colors, normals, texture coordinates _vbo = GL.GenBuffer(); // We bind the VAO GL.BindVertexArray(_vao); GL.BindBuffer(BufferTarget.ArrayBuffer, _vbo); // Specifying the type of buffer // Uploading the vertex data to the GPU GL.BufferData(BufferTarget.ArrayBuffer, _vertices.Length * sizeof(float), _vertices, BufferUsageHint.StaticDraw); // We tell opengl how to interpret the vertex data. // The Location 0 corresponds to the layout(location = 0) in the vertex shader // How many components (x, y, z) -> 3 // Data type -> float // Not normalized // The Stride -> The total size of a vertex (in bytes) // The offset -> The position data starts at the beginning of the vertex data so 0 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 float[] GetVertices() { return _vertices; } public void Draw(Shader shader, Matrix4 view, Matrix4 projection, Matrix4 model) { //shader.SetMatrix4("model", matrix4); int modelLoc = GL.GetUniformLocation(shader.Handle, "model"); int viewLoc = GL.GetUniformLocation(shader.Handle, "view"); int projLoc = GL.GetUniformLocation(shader.Handle, "projection"); // Send the matrices to the shader GL.UniformMatrix4(modelLoc, false, ref model); GL.UniformMatrix4(viewLoc, false, ref view); GL.UniformMatrix4(projLoc, false, ref projection); shader.Use(); GL.BindVertexArray(_vao); GL.DrawArrays(PrimitiveType.TriangleFan, 0, _vertices.Length / 7); } public void Dispose() { GL.DeleteBuffer(_vbo); GL.DeleteVertexArray(_vao); } }