From e45344c18901cece9ccb491cbef4d00f52bdc55b Mon Sep 17 00:00:00 2001 From: Chris Bell Date: Thu, 16 Jan 2025 16:45:52 -0600 Subject: [PATCH] Render a triangle for testing purposes --- .../GLTFViewer/Engine/Rendering/Renderer.cs | 113 +++++++++++++++++- 1 file changed, 107 insertions(+), 6 deletions(-) diff --git a/GLTFViewer/GLTFViewer/Engine/Rendering/Renderer.cs b/GLTFViewer/GLTFViewer/Engine/Rendering/Renderer.cs index c0b1aff..a70f855 100644 --- a/GLTFViewer/GLTFViewer/Engine/Rendering/Renderer.cs +++ b/GLTFViewer/GLTFViewer/Engine/Rendering/Renderer.cs @@ -8,23 +8,125 @@ namespace GLTFViewer.Rendering; public class Renderer { + private int _vao; + private int _vbo; + private int _shaderProgram; + public void Initialize(GlInterface gl) { GLLoader.LoadBindings(new AvaloniaBindingsContext(gl)); - GL.ClearColor(1,1,1,1); + GL.ClearColor(1, 1, 1, 1); + + // Vertex data for a triangle + float[] vertices = { + 0.0f, 0.5f, 0.0f, // Top vertex + -0.5f, -0.5f, 0.0f, // Bottom left vertex + 0.5f, -0.5f, 0.0f // Bottom right vertex + }; + + // Create and bind the VAO + _vao = GL.GenVertexArray(); + GL.BindVertexArray(_vao); + + // Create and bind the VBO + _vbo = GL.GenBuffer(); + GL.BindBuffer(BufferTarget.ArrayBuffer, _vbo); + GL.BufferData(BufferTarget.ArrayBuffer, vertices.Length * sizeof(float), vertices, BufferUsage.StaticDraw); + + // Vertex shader source code + string vertexShaderSource = @" + #version 330 core + layout(location = 0) in vec3 aPos; + void main() + { + gl_Position = vec4(aPos, 1.0); + }"; + + // Fragment shader source code + string fragmentShaderSource = @" + #version 330 core + out vec4 FragColor; + void main() + { + FragColor = vec4(0.0, 0.0, 1.0, 1.0); // Blue color + }"; + + // Compile vertex shader + int vertexShader = GL.CreateShader(ShaderType.VertexShader); + GL.ShaderSource(vertexShader, vertexShaderSource); + GL.CompileShader(vertexShader); + CheckShaderCompileStatus(vertexShader); + + // Compile fragment shader + int fragmentShader = GL.CreateShader(ShaderType.FragmentShader); + GL.ShaderSource(fragmentShader, fragmentShaderSource); + GL.CompileShader(fragmentShader); + CheckShaderCompileStatus(fragmentShader); + + // Link shaders into a program + _shaderProgram = GL.CreateProgram(); + GL.AttachShader(_shaderProgram, vertexShader); + GL.AttachShader(_shaderProgram, fragmentShader); + GL.LinkProgram(_shaderProgram); + CheckProgramLinkStatus(_shaderProgram); + + // Clean up shaders as they are no longer needed + GL.DeleteShader(vertexShader); + GL.DeleteShader(fragmentShader); + + // Specify the layout of the vertex data + GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 3 * sizeof(float), 0); + GL.EnableVertexAttribArray(0); + + // Unbind the VAO + GL.BindVertexArray(0); } - + public void Render(GlInterface gl, int width, int height, int fbo) { GL.Viewport(0, 0, width, height); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); + + // Use the shader program + GL.UseProgram(_shaderProgram); + + // Bind the VAO + GL.BindVertexArray(_vao); + + // Draw the triangle + GL.DrawArrays(PrimitiveType.Triangles, 0, 3); + + // Unbind the VAO + GL.BindVertexArray(0); } - + public void Deinitialize(GlInterface gl) { - + GL.DeleteVertexArray(_vao); + GL.DeleteBuffer(_vbo); + GL.DeleteProgram(_shaderProgram); } - + + private void CheckShaderCompileStatus(int shader) + { + GL.GetShaderi(shader, ShaderParameterName.CompileStatus, out int status); + if (status == (int)All.False) + { + GL.GetShaderInfoLog(shader, out var infoLog); + throw new Exception($"Shader compilation failed: {infoLog}"); + } + } + + private void CheckProgramLinkStatus(int program) + { + GL.GetProgrami(program, ProgramProperty.LinkStatus, out int status); + if (status == (int)All.False) + { + GL.GetProgramInfoLog(program, out var infoLog); + throw new Exception($"Program linking failed: {infoLog}"); + } + } + private class AvaloniaBindingsContext : IBindingsContext { private readonly GlInterface _gl; @@ -39,5 +141,4 @@ public class Renderer return _gl.GetProcAddress(procName); } } - } \ No newline at end of file