using System; using System.IO; using System.Text; using OpenTK.Graphics.OpenGL; namespace RecrownedAthenaeum.Graphics.Render.Shader { public class Shader : IDisposable { int handle; public bool IsDisposed { get; private set; } public Shader(string vertexPath, string fragmentPath) { IsDisposed = false; int vertShader = 0; int fragShader = 0; string vertShaderSource; string fragShaderSource; using (StreamReader stream = new StreamReader(vertexPath, Encoding.UTF8)) { vertShaderSource = stream.ReadToEnd(); } using (StreamReader stream = new StreamReader(fragmentPath, Encoding.UTF8)) { fragShaderSource = stream.ReadToEnd(); } vertShader = GL.CreateShader(ShaderType.VertexShader); GL.ShaderSource(vertShader, vertShaderSource); fragShader = GL.CreateShader(ShaderType.FragmentShader); GL.ShaderSource(fragShader, fragShaderSource); string log; GL.CompileShader(vertShader); if ((log = GL.GetShaderInfoLog(vertShader)) == "") { throw new ArgumentException("Error while compiling vertex shader: " + log, "vertexPath"); } GL.CompileShader(fragShader); if ((log = GL.GetShaderInfoLog(fragShader)) == "") { throw new ArgumentException("Error while compiling fragment shader: " + log, "fragmentPath"); } handle = GL.CreateProgram(); GL.AttachShader(handle, vertShader); GL.AttachShader(handle, fragShader); GL.LinkProgram(handle); GL.DetachShader(handle, vertShader); GL.DetachShader(handle, fragShader); GL.DeleteShader(vertShader); GL.DeleteShader(fragShader); } public void Use() { GL.UseProgram(handle); } protected virtual void Dispose(bool disposing) { if (IsDisposed) { return; } if (disposing) { } GL.DeleteProgram(handle); IsDisposed = true; } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } ~Shader() { Dispose(false); } } }