using System; using System.IO; using System.Text; using GL = OpenTK.Graphics.ES30.GL; using ShaderType = OpenTK.Graphics.ES30.ShaderType; namespace OpenTKTutorial { public class Shader : IDisposable { public int Handle; public Shader(string vertexPath, string fragmentPath) { string vertex, fragment; using (StreamReader reader = new StreamReader(vertexPath, Encoding.UTF8)) vertex = reader.ReadToEnd(); using (StreamReader reader = new StreamReader(fragmentPath, Encoding.UTF8)) fragment = reader.ReadToEnd(); int vertexShader = GL.CreateShader(ShaderType.VertexShader); GL.ShaderSource(vertexShader, vertex); int fragmentShader = GL.CreateShader(ShaderType.FragmentShader); GL.ShaderSource(fragmentShader, fragment); GL.CompileShader(vertexShader); string infoLogVert = GL.GetShaderInfoLog(vertexShader); if (infoLogVert != String.Empty) throw new Exception("Could not compile vertex shader: " + infoLogVert); GL.CompileShader(fragmentShader); string infoLogFrag = GL.GetShaderInfoLog(fragmentShader); if (infoLogFrag != String.Empty) throw new Exception("Could not compile fragment shader: " + infoLogFrag); Handle = GL.CreateProgram(); GL.AttachShader(Handle, vertexShader); GL.AttachShader(Handle, fragmentShader); GL.LinkProgram(Handle); GL.DetachShader(Handle, vertexShader); GL.DetachShader(Handle, fragmentShader); GL.DeleteShader(fragmentShader); GL.DeleteShader(vertexShader); } public void Use() { GL.UseProgram(Handle); } private bool disposedValue = false; protected virtual void Dispose(bool disposing) { if (!disposedValue) { GL.DeleteProgram(Handle); disposedValue = true; } } ~Shader() { GL.DeleteProgram(Handle); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } } }