Added cylinder class

This commit is contained in:
zyb3rwolfi 2025-10-07 12:53:30 +01:00
parent 825bdb0b59
commit ced63735a5
3 changed files with 142 additions and 10 deletions

View File

@ -36,6 +36,7 @@ namespace TheLabs
private Cube _cube; private Cube _cube;
private Circle _circle; private Circle _circle;
private Cylinder _cylinder;
private Shader _shader; private Shader _shader;
private float _rotation; private float _rotation;
@ -58,6 +59,7 @@ namespace TheLabs
// Create a cube // Create a cube
_cube = new Cube(); _cube = new Cube();
_circle = new Circle(); _circle = new Circle();
_cylinder = new Cylinder();
// Use the shader program. This is similar to "activating" the shader program. // Use the shader program. This is similar to "activating" the shader program.
_shader.Use(); _shader.Use();
@ -93,8 +95,9 @@ namespace TheLabs
GL.UniformMatrix4(projLoc, false, ref projection); GL.UniformMatrix4(projLoc, false, ref projection);
// Draw the cube // Draw the cube
_cube.Draw(_shader, model); //_cube.Draw(_shader, model);
_circle.Draw(_shader, model); //_circle.Draw(_shader, model);
_cylinder.Draw(_shader, model);
SwapBuffers(); SwapBuffers();
GL.GetError(); GL.GetError();
} }

View File

@ -18,9 +18,10 @@ public class Circle
}; };
private int _maxVert = 100; 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; float angle = i * 2.0f * MathF.PI / _maxVert;
@ -30,11 +31,11 @@ public class Circle
Array.Resize(ref _vertices, _vertices.Length + 7); Array.Resize(ref _vertices, _vertices.Length + 7);
_vertices[^7] = x; _vertices[^7] = x;
_vertices[^6] = y; _vertices[^6] = y;
_vertices[^5] = 0.0f; _vertices[^5] = z;
_vertices[^4] = 1f; _vertices[^4] = col.X;
_vertices[^3] = 0f; _vertices[^3] = col.Y;
_vertices[^2] = 0f; _vertices[^2] = col.Z;
_vertices[^1] = 1f; _vertices[^1] = col.W;
} }
// The Vertex Array Object // The Vertex Array Object
@ -66,6 +67,10 @@ public class Circle
GL.BindVertexArray(0); GL.BindVertexArray(0);
} }
public float[] GetVertices()
{
return _vertices;
}
public void Draw(Shader shader, Matrix4 matrix4) public void Draw(Shader shader, Matrix4 matrix4)
{ {
shader.SetMatrix4("model", matrix4); shader.SetMatrix4("model", matrix4);

View File

@ -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<float>();
var indices = new List<uint>();
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);
}
}