Final source code of Chapter 1, Tutorial 2.
using System;
using System.Drawing;
using Silk.NET.Maths;
using Silk.NET.Windowing;
using Silk.NET.OpenGL;
namespace MyProgram;
public class Program
{
private static IWindow _window;
private static GL _gl;
private static uint _vao;
private static uint _vbo;
private static uint _ebo;
private static uint _program;
public static void Main(string[] args)
{
WindowOptions options = WindowOptions.Default;
options.Size = new Vector2D<int>(800, 600);
options.Title = "1.2 - Drawing a Quad";
_window = Window.Create(options);
_window.Load += OnLoad;
_window.Update += OnUpdate;
_window.Render += OnRender;
_window.Run();
}
private static unsafe void OnLoad()
{
_gl = _window.CreateOpenGL();
_gl.ClearColor(Color.CornflowerBlue);
// Create the VAO.
_vao = _gl.GenVertexArray();
_gl.BindVertexArray(_vao);
// The quad vertices data.
float[] vertices =
{
0.5f, 0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
-0.5f, 0.5f, 0.0f
};
// Create the VBO.
_vbo = _gl.GenBuffer();
_gl.BindBuffer(BufferTargetARB.ArrayBuffer, _vbo);
// Upload the vertices data to the VBO.
fixed (float* buf = vertices)
_gl.BufferData(BufferTargetARB.ArrayBuffer, (nuint) (vertices.Length * sizeof(float)), buf, BufferUsageARB.StaticDraw);
// The quad indices data.
uint[] indices =
{
0u, 1u, 3u,
1u, 2u, 3u
};
// Create the EBO.
_ebo = _gl.GenBuffer();
_gl.BindBuffer(BufferTargetARB.ElementArrayBuffer, _ebo);
// Upload the indices data to the EBO.
fixed (uint* buf = indices)
_gl.BufferData(BufferTargetARB.ElementArrayBuffer, (nuint) (indices.Length * sizeof(uint)), buf, BufferUsageARB.StaticDraw);
const string vertexCode = @"
#version 330 core
layout (location = 0) in vec3 aPosition;
void main()
{
gl_Position = vec4(aPosition, 1.0);
}";
const string fragmentCode = @"
#version 330 core
out vec4 out_color;
void main()
{
out_color = vec4(1.0, 0.5, 0.2, 1.0);
}";
uint vertexShader = _gl.CreateShader(ShaderType.VertexShader);
_gl.ShaderSource(vertexShader, vertexCode);
_gl.CompileShader(vertexShader);
_gl.GetShader(vertexShader, ShaderParameterName.CompileStatus, out int vStatus);
if (vStatus != (int) GLEnum.True)
throw new Exception("Vertex shader failed to compile: " + _gl.GetShaderInfoLog(vertexShader));
uint fragmentShader = _gl.CreateShader(ShaderType.FragmentShader);
_gl.ShaderSource(fragmentShader, fragmentCode);
_gl.CompileShader(fragmentShader);
_gl.GetShader(fragmentShader, ShaderParameterName.CompileStatus, out int fStatus);
if (fStatus != (int) GLEnum.True)
throw new Exception("Fragment shader failed to compile: " + _gl.GetShaderInfoLog(fragmentShader));
_program = _gl.CreateProgram();
_gl.AttachShader(_program, vertexShader);
_gl.AttachShader(_program, fragmentShader);
_gl.LinkProgram(_program);
_gl.GetProgram(_program, ProgramPropertyARB.LinkStatus, out int lStatus);
if (lStatus != (int) GLEnum.True)
throw new Exception("Program failed to link: " + _gl.GetProgramInfoLog(_program));
_gl.DetachShader(_program, vertexShader);
_gl.DetachShader(_program, fragmentShader);
_gl.DeleteShader(vertexShader);
_gl.DeleteShader(fragmentShader);
const uint positionLoc = 0;
_gl.EnableVertexAttribArray(positionLoc);
_gl.VertexAttribPointer(positionLoc, 3, VertexAttribPointerType.Float, false, 3 * sizeof(float), (void*) 0);
_gl.BindVertexArray(0);
_gl.BindBuffer(BufferTargetARB.ArrayBuffer, 0);
_gl.BindBuffer(BufferTargetARB.ElementArrayBuffer, 0);
}
private static void OnUpdate(double deltaTime) { }
private static unsafe void OnRender(double deltaTime)
{
_gl.Clear(ClearBufferMask.ColorBufferBit);
_gl.BindVertexArray(_vao);
_gl.UseProgram(_program);
_gl.DrawElements(PrimitiveType.Triangles, 6, DrawElementsType.UnsignedInt, (void*) 0);
}
}
Khronos®, Vulkan® are registered trademarks, and OpenXR™ is a trademark of The Khronos Group Inc. and is registered as a trademark in China, the European Union, Japan and the United Kingdom. OpenCL™, OpenGL®, and the OpenGL ES™ logos are registered trademarks or trademarks used under license by Khronos. Microsoft® and DirectX® are registered trademarks of Microsoft Corporation, used solely for identification. All other product names, trademarks, and/or company names are also used solely for identification and belong to their respective owners. Use of external images, trademarks, and/or resources are not endorsements, and no information in or regarding any of these external resources has been endorsed or approved by Silk.NET or the .NET Foundation.
Powered by Statiq Framework