I have a rather strange exception on my application using OpenTK on Linux (ArchLinux with Mono 3.2.8) with GL.UseProgram()
. I wrote a class to combine multiple files to one program:
public sealed class Shader : IContent
{
public string Name
{
get { return name; }
}
readonly string name;
readonly ShaderElement[] elements;
int programId;
public Shader(string name, params ShaderElement[] elements)
{
this.name = name;
this.elements = elements;
this.programId = -1;
}
public void Compile()
{
programId = GL.CreateProgram();
for (int i = 0; i < elements.Length; i++)
{
var info = new FileInfo(elements[i].File);
if (info.Exists)
{
int shaderId = GL.CreateShader(elements[i].Type);
using (var reader = info.OpenText())
GL.ShaderSource(shaderId, reader.ReadToEnd());
GL.AttachShader(programId, shaderId);
}
else
throw new FileNotFoundException("Shader file not found.", info.Name);
}
GL.LinkProgram(programId);
}
public void Apply()
{
if (programId == -1)
throw new InvalidOperationException("Compile() has to be called before Apply()");
GL.UseProgram(programId);
}
public void Unapply()
{
GL.UseProgram(0);
}
public void Dispose()
{
GL.DeleteProgram(programId);
}
}
My sample shader is very short because I try to understand how OpenGL works:
Vertex:
precision highp float;
void main()
{
gl_FrontColor = gl_Color;
gl_Position = ftransform();
}
Fragment:
precision highp float;
void main()
{
gl_FragColor = gl_Color * (1-clamp(gl_FragCoord.z - 0.05, 0, 1));
gl_FragColor.w = 1;
}
A sample call for Apply()
:
public override void Draw(double interpolation)
{
GL.MatrixMode(MatrixMode.Modelview);
GL.LoadMatrix(ref translate);
GL.MatrixMode(MatrixMode.Projection);
GL.LoadMatrix(ref projection);
GL.Color3(Color.Red);
simpleShader.Apply();
sphere.Draw();
simpleShader.Unapply();
}
Running the application under Windows does not generate any exception.
The following is crashing running under Linux:
First call of Draw()
-> First call of Shader.Apply()
-> Draws geometry for first frame
-> First call of Shader.Unapply()
Second call of Draw()
-> Second call of Shader.Apply()
-> GL throws InvalidOperation Error.
Any ideas why Windows behaves different to Linux and how this can be resolved?