public static uint LoadShaderProgram( IOpenGl gl, ReadOnlySpan <byte> vertexSource, ReadOnlySpan <byte> fragmentSource) { var vertexShader = LoadShader(gl, vertexSource, Gl.VertexShader); try { var fragmentShader = LoadShader(gl, fragmentSource, Gl.FragmentShader); try { var program = gl.CreateProgram(); gl.AttachShader(program, vertexShader); gl.AttachShader(program, fragmentShader); gl.LinkProgram(program); gl.DeleteShader(fragmentShader); gl.DeleteShader(vertexShader); gl.GetProgramiv(program, Gl.LinkStatus, out var result); if (result == Gl.False) { gl.GetProgramiv(program, Gl.InfoLogLength, out var logLength); var buffer = new byte[logLength]; gl.GetProgramInfoLog(program, buffer.Length, out _, buffer); var errors = Encoding.UTF8.GetString(buffer); throw new OpenGlException("Error linking program: " + errors); } return(program); } finally { gl.DeleteShader(fragmentShader); } } finally { gl.DeleteShader(vertexShader); } }
public static uint LoadShader( IOpenGl gl, ReadOnlySpan <byte> source, uint shaderType) { unsafe { fixed(byte *pointer = source) { var shader = gl.CreateShader(shaderType); try { var ptr = new IntPtr(pointer); gl.ShaderSource(shader, 1, ptr, source.Length); gl.CompileShader(shader); gl.GetShaderiv(shader, Gl.CompileStatus, out var result); if (result == Gl.False) { gl.GetShaderiv(shader, Gl.InfoLogLength, out var logLength); var buffer = new byte[logLength]; gl.GetShaderInfoLog(shader, buffer.Length, out var actualLength, buffer); // We can disregard the actual length because we queried the actual length up above. var errors = Encoding.UTF8.GetString(buffer); throw new OpenGlException("Error compiling shader: " + errors); } return(shader); } catch { gl.DeleteShader(shader); throw; } } } }