Created
February 12, 2012 20:52
-
-
Save Jessidhia/1810798 to your computer and use it in GitHub Desktop.
OpenTK shader loading / handling partial wrapper
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using OpenTK; | |
using OpenTK.Graphics.OpenGL; | |
using OpenTK.Graphics; | |
using System.Drawing; | |
namespace GLTut | |
{ | |
public class Program : IDisposable | |
{ | |
public Program(params Shader[] shaders) | |
{ | |
program_id = GL.CreateProgram(); | |
this.shaders = new List<Shader>(shaders.Length); | |
Attach(shaders); | |
} | |
public IDisposable Use() | |
{ | |
IDisposable r = new Program.Handle(curr_program); | |
if (curr_program != ID) | |
{ | |
GL.UseProgram(ID); | |
curr_program = ID; | |
} | |
return r; | |
} | |
public static void Clear() | |
{ | |
GL.UseProgram(curr_program = 0); | |
} | |
public void Link() | |
{ | |
unifmap = new Dictionary<string, int>(); | |
GL.LinkProgram(ID); | |
int status; | |
GL.GetProgram(ID, ProgramParameter.LinkStatus, out status); | |
if (status == 0) | |
throw new GraphicsException( | |
String.Format("Error linking program: {0}", GL.GetProgramInfoLog(ID))); | |
} | |
public void DisposeShaders() | |
{ | |
foreach (Shader s in Shaders) | |
s.Dispose(); | |
Shaders.Clear(); | |
} | |
public void BindAttribLocation(int index, string name) | |
{ | |
GL.BindAttribLocation(ID, index, name); | |
} | |
public void BindAttribLocation(params Tuple<int, string>[] attribs) | |
{ | |
foreach (Tuple<int, string> t in attribs) | |
{ | |
BindAttribLocation(t.Item1, t.Item2); | |
} | |
} | |
public void BindFragDataLocation(int color, string name) | |
{ | |
GL.BindFragDataLocation(ID, color, name); | |
} | |
public void BindFragDataLocation(params Tuple<int, string>[] attribs) | |
{ | |
foreach (Tuple<int, string> t in attribs) | |
{ | |
BindFragDataLocation(t.Item1, t.Item2); | |
} | |
} | |
public void TransformFeedbackVaryings(TransformFeedbackMode mode, params string[] varyings) | |
{ | |
GL.TransformFeedbackVaryings(ID, varyings.Length, varyings, mode); | |
} | |
public void Detach(params Shader[] shaders) | |
{ | |
foreach (Shader s in shaders) | |
{ | |
Shaders.Remove(s); | |
GL.DetachShader(ID, s.ID); | |
} | |
} | |
public void Attach(params Shader[] shaders) | |
{ | |
foreach (Shader s in shaders) | |
{ | |
Shaders.Add(s); | |
GL.AttachShader(ID, s.ID); | |
} | |
} | |
private int program_id; | |
public int ID | |
{ | |
get | |
{ | |
return program_id; | |
} | |
} | |
private List<Shader> shaders; | |
public List<Shader> Shaders | |
{ | |
get | |
{ | |
return shaders; | |
} | |
} | |
private static int curr_program = 0; | |
private Dictionary<string, int> unifmap; | |
public object this[string uniform] | |
{ | |
set | |
{ | |
Use(); | |
int uid; | |
if (unifmap.ContainsKey(uniform)) | |
uid = unifmap[uniform]; | |
else | |
uid = unifmap[uniform] = GL.GetUniformLocation(ID, uniform); | |
int len = 0; | |
Type t = value.GetType(); | |
if (t.IsArray) | |
len = ((Array)value).Length; | |
if (false) | |
{ } // just aligning the else ifs | |
else if (t == typeof(int)) | |
GL.Uniform1(uid, (int)value); | |
else if (t == typeof(uint)) | |
GL.Uniform1(uid, (uint)value); | |
else if (t == typeof(float)) | |
GL.Uniform1(uid, (float)value); | |
else if (t == typeof(Vector2)) | |
GL.Uniform2(uid, (Vector2)value); | |
else if (t == typeof(Vector3)) | |
GL.Uniform3(uid, (Vector3)value); | |
else if (t == typeof(Vector4)) | |
GL.Uniform4(uid, (Vector4)value); | |
else if (t == typeof(Quaternion)) | |
GL.Uniform4(uid, (Quaternion)value); | |
else if (t == typeof(Color4)) | |
GL.Uniform4(uid, (Color4)value); | |
else if (t == typeof(int[])) | |
GL.Uniform1(uid, len, (int[])value); | |
else if (t == typeof(uint[])) | |
GL.Uniform1(uid, len, (uint[])value); | |
else if (t == typeof(float[])) | |
GL.Uniform1(uid, len, (float[])value); | |
else if (t == typeof(Color)) | |
{ | |
Color c = (Color)value; // why must I do this? OpenTK-- | |
GL.Uniform4(uid, new Color4(c.R, c.G, c.B, c.A)); | |
} | |
else | |
Console.Error.WriteLine("Unhandled type {0} for glUniform", t.FullName); | |
} | |
} | |
public void Dispose() | |
{ | |
if (ID >= 0) | |
GL.DeleteProgram(ID); | |
Shaders.Clear(); | |
program_id = -1; | |
} | |
private class Handle : IDisposable | |
{ | |
private int prev; | |
public Handle(int prev) | |
{ | |
this.prev = prev; | |
} | |
public void Dispose() | |
{ | |
if (Program.curr_program != prev) | |
{ | |
Program.curr_program = prev; | |
GL.UseProgram(prev); | |
} | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.IO; | |
using System.Text; | |
using OpenTK; | |
using OpenTK.Graphics.OpenGL; | |
namespace GLTut | |
{ | |
public abstract class Shader : IDisposable | |
{ | |
public Shader(ShaderType type, params string[] source) | |
{ | |
CompileShader(type, source); | |
} | |
public Shader(ShaderType type, FileInfo f) | |
: this(type, File.ReadAllText(f.FullName, Encoding.UTF8)) | |
{ } | |
private int shader_id; | |
public int ID | |
{ | |
get | |
{ | |
return shader_id; | |
} | |
} | |
protected void CompileShader(ShaderType type, string[] source) | |
{ | |
shader_id = GL.CreateShader(type); | |
int[] lens = new int[source.Length]; | |
for (int i = 0; i < lens.Length; i++) | |
lens[i] = -1; | |
GL.ShaderSource(ID, source.Length, source, ref lens[0]); | |
GL.CompileShader(ID); | |
int status; | |
GL.GetShader(ID, ShaderParameter.CompileStatus, out status); | |
if (status == 0) | |
throw new GraphicsException( | |
String.Format("Error compiling {0} shader: {1}", type.ToString(), GL.GetShaderInfoLog(ID))); | |
} | |
public void Dispose() | |
{ | |
if (shader_id >= 0) | |
GL.DeleteShader(ID); | |
shader_id = -1; | |
} | |
} | |
public class VertexShader : Shader | |
{ | |
public VertexShader(params string[] source) | |
: base(ShaderType.VertexShader, source) | |
{ } | |
public VertexShader(FileInfo f) | |
: base(ShaderType.VertexShader, f) | |
{ } | |
} | |
public class FragShader : Shader | |
{ | |
public FragShader(params string[] source) | |
: base(ShaderType.FragmentShader, source) | |
{ } | |
public FragShader(FileInfo f) | |
: base(ShaderType.FragmentShader, f) | |
{ } | |
} | |
public class GeomShader : Shader | |
{ | |
public GeomShader(params string[] source) | |
: base(ShaderType.GeometryShader, source) | |
{ } | |
public GeomShader(FileInfo f) | |
: base(ShaderType.GeometryShader, f) | |
{ } | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment