From 4514509c62f1511027021d13720040631db78c28 Mon Sep 17 00:00:00 2001 From: Colin McMillen Date: Thu, 3 Aug 2023 19:32:53 -0400 Subject: [PATCH] pull out Shader into its own file --- Program.cs | 121 ++--------------------------------------------------- Shader.cs | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 119 insertions(+), 118 deletions(-) create mode 100644 Shader.cs diff --git a/Program.cs b/Program.cs index d46ae9b..b036337 100644 --- a/Program.cs +++ b/Program.cs @@ -192,124 +192,6 @@ public class CropTool : ITool { } } -// FIXME: switch to immediate mode?? -// https://gamedev.stackexchange.com/questions/198805/opentk-immediate-mode-on-net-core-doesnt-work -// https://www.youtube.com/watch?v=Q23Kf9QEaO4 -public class Shader : IDisposable { - public int Handle; - private bool init = false; - - public Shader() {} - - public void Init() { - init = true; - int VertexShader; - int FragmentShader; - - string VertexShaderSource = @" -#version 330 - -layout(location = 0) in vec3 aPosition; -layout(location = 1) in vec2 aTexCoord; - -out vec2 texCoord; - -uniform mat4 projection; - -void main(void) { - texCoord = aTexCoord; - gl_Position = vec4(aPosition, 1.0) * projection; -}"; - - string FragmentShaderSource = @" -#version 330 - -out vec4 outputColor; -in vec2 texCoord; -uniform sampler2D texture0; -uniform vec4 color; - -void main() { - outputColor = texture(texture0, texCoord) * color; -}"; - - VertexShader = GL.CreateShader(ShaderType.VertexShader); - GL.ShaderSource(VertexShader, VertexShaderSource); - - FragmentShader = GL.CreateShader(ShaderType.FragmentShader); - GL.ShaderSource(FragmentShader, FragmentShaderSource); - - GL.CompileShader(VertexShader); - - int success; - GL.GetShader(VertexShader, ShaderParameter.CompileStatus, out success); - if (success == 0) { - string infoLog = GL.GetShaderInfoLog(VertexShader); - Console.WriteLine(infoLog); - } - - GL.CompileShader(FragmentShader); - - GL.GetShader(FragmentShader, ShaderParameter.CompileStatus, out success); - if (success == 0) { - string infoLog = GL.GetShaderInfoLog(FragmentShader); - Console.WriteLine(infoLog); - } - 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() { - if (!init) { - Console.WriteLine("Shader.Use(): must call Init() first"); - } - GL.UseProgram(Handle); - } - - private bool disposedValue = false; - - protected virtual void Dispose(bool disposing) { - if (!disposedValue) { - GL.DeleteProgram(Handle); - disposedValue = true; - } - } - - ~Shader() { - if (disposedValue == false) { - Console.WriteLine("~Shader(): resource leak? Dispose() should be called manually."); - } - } - - public void Dispose() { - Dispose(true); - GC.SuppressFinalize(this); - } - - public int GetAttribLocation(string name) { - return GL.GetAttribLocation(Handle, name); - } - - public int GetUniformLocation(string name) { - return GL.GetUniformLocation(Handle, name); - } -} - // FIXME: this should probably be IDisposable? public class Photo { public string Filename; @@ -1008,6 +890,9 @@ public class Game : GameWindow { photoIndex = Math.Max(0, photoIndex); } + // FIXME: switch to immediate mode?? + // https://gamedev.stackexchange.com/questions/198805/opentk-immediate-mode-on-net-core-doesnt-work + // https://www.youtube.com/watch?v=Q23Kf9QEaO4 protected override void OnLoad() { base.OnLoad(); diff --git a/Shader.cs b/Shader.cs new file mode 100644 index 0000000..f0134d2 --- /dev/null +++ b/Shader.cs @@ -0,0 +1,116 @@ +using OpenTK.Graphics.OpenGL4; + +public class Shader : IDisposable { + public int Handle; + private bool init = false; + + public Shader() {} + + public void Init() { + init = true; + int VertexShader; + int FragmentShader; + + string VertexShaderSource = @" +#version 330 + +layout(location = 0) in vec3 aPosition; +layout(location = 1) in vec2 aTexCoord; + +out vec2 texCoord; + +uniform mat4 projection; + +void main(void) { + texCoord = aTexCoord; + gl_Position = vec4(aPosition, 1.0) * projection; +}"; + + string FragmentShaderSource = @" +#version 330 + +out vec4 outputColor; +in vec2 texCoord; +uniform sampler2D texture0; +uniform vec4 color; + +void main() { + outputColor = texture(texture0, texCoord) * color; +}"; + + VertexShader = GL.CreateShader(ShaderType.VertexShader); + GL.ShaderSource(VertexShader, VertexShaderSource); + + FragmentShader = GL.CreateShader(ShaderType.FragmentShader); + GL.ShaderSource(FragmentShader, FragmentShaderSource); + + GL.CompileShader(VertexShader); + + int success; + GL.GetShader(VertexShader, ShaderParameter.CompileStatus, out success); + if (success == 0) { + string infoLog = GL.GetShaderInfoLog(VertexShader); + Console.WriteLine(infoLog); + } + + GL.CompileShader(FragmentShader); + + GL.GetShader(FragmentShader, ShaderParameter.CompileStatus, out success); + if (success == 0) { + string infoLog = GL.GetShaderInfoLog(FragmentShader); + Console.WriteLine(infoLog); + } + 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() { + if (!init) { + Console.WriteLine("Shader.Use(): must call Init() first"); + } + GL.UseProgram(Handle); + } + + private bool disposedValue = false; + + protected virtual void Dispose(bool disposing) { + if (!disposedValue) { + GL.DeleteProgram(Handle); + disposedValue = true; + } + } + + ~Shader() { + if (disposedValue == false) { + Console.WriteLine("~Shader(): resource leak? Dispose() should be called manually."); + } + } + + public void Dispose() { + Dispose(true); + GC.SuppressFinalize(this); + } + + public int GetAttribLocation(string name) { + return GL.GetAttribLocation(Handle, name); + } + + public int GetUniformLocation(string name) { + return GL.GetUniformLocation(Handle, name); + } +}