diff --git a/Program.cs b/Program.cs new file mode 100644 index 0000000..73b2979 --- /dev/null +++ b/Program.cs @@ -0,0 +1,14 @@ +using Voxel; + +internal class Program +{ + private static void Main(string[] args) + { + int sizeX = 800; + int sizeY = 600; + string title = "Game"; + + Window window = new Window(sizeX, sizeY, title); + window.Run(); + } +} \ No newline at end of file diff --git a/Shader.cs b/Shader.cs new file mode 100644 index 0000000..058865c --- /dev/null +++ b/Shader.cs @@ -0,0 +1,93 @@ +using OpenTK.Graphics.OpenGL4; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection.Metadata; +using System.Text; +using System.Threading.Tasks; + +namespace Voxel +{ + public class Shader + { + int handle; + private bool disposedValue = false; + + public Shader(string vertexPath, string fragmentPath) + { + string vertexShaderSource = File.ReadAllText(vertexPath); + string fragmentShaderSource = File.ReadAllText(fragmentPath); + + int vertexShader = GL.CreateShader(ShaderType.VertexShader); + int fragmentShader = GL.CreateShader(ShaderType.FragmentShader); + + GL.ShaderSource(vertexShader, vertexShaderSource); + GL.ShaderSource(fragmentShader, fragmentShaderSource); + + GL.CompileShader(vertexShader); + GL.GetShader(vertexShader, ShaderParameter.CompileStatus, out int success); + if (success == 0) + { + string infoLog = GL.GetShaderInfoLog(vertexShader); + Console.WriteLine(infoLog); + } + + GL.CompileShader(fragmentShader); + if (success == 0) + { + string infoLog = GL.GetShaderInfoLog(fragmentShader); + Console.WriteLine(infoLog); + } + + // attach + + handle = GL.CreateProgram(); + + GL.AttachShader(handle, vertexShader); + GL.AttachShader(handle, fragmentShader); + + GL.LinkProgram(handle); + + GL.GetProgram(handle, GetProgramParameterName.LinkStatus, out success); + if (success == 0) + { + string infoLog = GL.GetProgramInfoLog(handle); + Console.WriteLine(infoLog); + } + + GL.DetachShader(handle, vertexShader); + GL.DetachShader(handle, fragmentShader); + GL.DeleteShader(fragmentShader); + GL.DeleteShader(vertexShader); + } + + public void Use() + { + GL.UseProgram(handle); + } + + protected virtual void Dispose(bool disposing) + { + if (!disposedValue) + { + GL.DeleteProgram(handle); + + disposedValue = true; + } + } + + ~Shader() + { + if (disposedValue == false) + { + Console.WriteLine("GPU Resource leak! Did you forget to call Dispose()?"); + } + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + } +} diff --git a/Shaders/shader.frag b/Shaders/shader.frag new file mode 100644 index 0000000..ea6443e --- /dev/null +++ b/Shaders/shader.frag @@ -0,0 +1,9 @@ +#version 330 core +out vec4 FragColor; + +in vec4 vertexColor; + +void main() +{ + FragColor = vertexColor; +} \ No newline at end of file diff --git a/Shaders/shader.vert b/Shaders/shader.vert new file mode 100644 index 0000000..80339d4 --- /dev/null +++ b/Shaders/shader.vert @@ -0,0 +1,10 @@ +#version 330 core +layout (location = 0) in vec3 aPosition; + +out vec4 vertexColor; + +void main() +{ + gl_Position = vec4(aPosition, 1.0); + vertexColor = vec4(aPosition + vec3(0.5,0.5,0.5), 1.0); +} \ No newline at end of file diff --git a/Triangle.cs b/Triangle.cs new file mode 100644 index 0000000..ceb6017 --- /dev/null +++ b/Triangle.cs @@ -0,0 +1,48 @@ +using OpenTK.Graphics.OpenGL4; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Voxel +{ + + public class Triangle + { + private int _vao; + private Shader _shader; + + public Triangle() + { + string vertexPath = "Shaders/shader.vert"; + string fragmentPath = "Shaders/shader.frag"; + _shader = new Shader(vertexPath, fragmentPath); + + float[] vertices = + { + -0.5f, -0.5f, 0.0f, //top + 0.5f, -0.5f, 0.0f, // bottom right + 0.0f, 0.5f, 0.0f // bottom left + }; + + _vao = GL.GenVertexArray(); + GL.BindVertexArray(_vao); + + int vbo = GL.GenBuffer(); + GL.BindBuffer(BufferTarget.ArrayBuffer, vbo); + GL.BufferData(BufferTarget.ArrayBuffer, vertices.Length * sizeof(float), vertices, BufferUsageHint.StaticDraw); + + GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 3 * sizeof(float), 0); + GL.EnableVertexAttribArray(0); + + _shader.Use(); + } + + public void Draw() + { + GL.BindVertexArray(_vao); + GL.DrawArrays(PrimitiveType.Triangles, 0, 3); + } + } +} diff --git a/Voxel.csproj b/Voxel.csproj new file mode 100644 index 0000000..207476f --- /dev/null +++ b/Voxel.csproj @@ -0,0 +1,23 @@ + + + + Exe + net8.0 + enable + enable + + + + + + + + + Always + + + Always + + + + diff --git a/Voxel.sln b/Voxel.sln new file mode 100644 index 0000000..d2c1af7 --- /dev/null +++ b/Voxel.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.14.36414.22 d17.14 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Voxel", "Voxel.csproj", "{E47B0EBF-E55C-4AD9-A928-0CFEA626FF71}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E47B0EBF-E55C-4AD9-A928-0CFEA626FF71}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E47B0EBF-E55C-4AD9-A928-0CFEA626FF71}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E47B0EBF-E55C-4AD9-A928-0CFEA626FF71}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E47B0EBF-E55C-4AD9-A928-0CFEA626FF71}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {AD41EC00-CB7C-4622-816F-9F2E4FD10EC0} + EndGlobalSection +EndGlobal diff --git a/Window.cs b/Window.cs new file mode 100644 index 0000000..33e04c7 --- /dev/null +++ b/Window.cs @@ -0,0 +1,48 @@ +using OpenTK.Graphics.OpenGL4; +using OpenTK.Windowing.Common; +using OpenTK.Windowing.Desktop; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Voxel +{ + public class Window(int width, int height, string title) : GameWindow(GameWindowSettings.Default, new NativeWindowSettings() { Size = (width, height), Title = title }) + { + private Triangle _triangle; + + protected override void OnUpdateFrame(FrameEventArgs args) + { + base.OnUpdateFrame(args); + } + + protected override void OnRenderFrame(FrameEventArgs args) + { + base.OnRenderFrame(args); + + GL.Clear(ClearBufferMask.ColorBufferBit); + + _triangle.Draw(); + + SwapBuffers(); + } + + protected override void OnFramebufferResize(FramebufferResizeEventArgs e) + { + base.OnFramebufferResize(e); + + GL.Viewport(0, 0, e.Width, e.Height); + } + + protected override void OnLoad() + { + base.OnLoad(); + + _triangle = new Triangle(); + + GL.ClearColor(0.5f, 0.5f, 0.5f, 1f); + } + } +}