public Shader(string name) { var vertexShader = CompileShaderObject(ShaderType.VertexShader, name); var fragmentShader = CompileShaderObject(ShaderType.FragmentShader, name); // Assemble program program = GL.CreateProgram(); ErrorHandler.CheckGlError(); GL.AttachShader(program, vertexShader); ErrorHandler.CheckGlError(); GL.AttachShader(program, fragmentShader); ErrorHandler.CheckGlError(); GL.LinkProgram(program); ErrorHandler.CheckGlError(); int success; GL.GetProgram(program, ProgramParameter.LinkStatus, out success); ErrorHandler.CheckGlError(); if (success == (int)All.False) { int len; GL.GetProgram(program, ProgramParameter.InfoLogLength, out len); var log = new StringBuilder(len); unsafe { GL.GetProgramInfoLog(program, len, null, log); } Log.Write("graphics", "GL Info Log:\n{0}", log.ToString()); throw new InvalidProgramException("Link error in shader program '{0}'".F(name)); } GL.UseProgram(program); ErrorHandler.CheckGlError(); int numUniforms; GL.GetProgram(program, ProgramParameter.ActiveUniforms, out numUniforms); ErrorHandler.CheckGlError(); var nextTexUnit = 0; for (var i = 0; i < numUniforms; i++) { int length, size; ActiveUniformType type; var sb = new StringBuilder(128); GL.GetActiveUniform(program, i, 128, out length, out size, out type, sb); var sampler = sb.ToString(); ErrorHandler.CheckGlError(); if (type == ActiveUniformType.Sampler2D) { samplers.Add(sampler, nextTexUnit); var loc = GL.GetUniformLocation(program, sampler); ErrorHandler.CheckGlError(); GL.Uniform1(loc, nextTexUnit); ErrorHandler.CheckGlError(); nextTexUnit++; } } }