Skip to content

Instantly share code, notes, and snippets.

@caverna
Last active August 9, 2023 09:15
Show Gist options
  • Select an option

  • Save caverna/c099a7c9ead4366651ce4f7ab522fd66 to your computer and use it in GitHub Desktop.

Select an option

Save caverna/c099a7c9ead4366651ce4f7ab522fd66 to your computer and use it in GitHub Desktop.
OpenGL shader compiler from embedded resources
using System.Text;
using OpenTK.Graphics.OpenGL4;
public static class ShaderCompiler
{
public static int GetShaderHandle(string vertexName, string fragmentName)
{
var shaderHandle = GL.CreateProgram();
var vertexShader = CompileShader(vertexName, ShaderType.VertexShader);
var fragmentShader = CompileShader(fragmentName, ShaderType.FragmentShader);
var success = LinkShaders(shaderHandle, vertexShader, fragmentShader);
GL.DeleteShader(vertexShader);
GL.DeleteShader(fragmentShader);
if (success == 0) Environment.Exit(-1);
GL.UseProgram(shaderHandle);
return shaderHandle;
}
private static int CompileShader(string shaderName, ShaderType shaderType)
{
var shaderSource = GetShaderSource(shaderName);
var shader = GL.CreateShader(shaderType);
GL.ShaderSource(shader, shaderSource);
GL.CompileShader(shader);
return shader;
}
private static int LinkShaders(int shaderHandle, int vertexShader, int fragmentShader)
{
GL.AttachShader(shaderHandle, vertexShader);
GL.AttachShader(shaderHandle, fragmentShader);
GL.LinkProgram(shaderHandle);
var success = CheckErrors(shaderHandle, vertexShader, fragmentShader);
GL.DetachShader(shaderHandle, vertexShader);
GL.DetachShader(shaderHandle, fragmentShader);
return success;
}
private static string GetShaderSource(string shaderName)
{
using var stream = GetShaderStream(shaderName);
using var reader = new StreamReader(stream, Encoding.UTF8);
var shaderSource = reader.ReadToEnd();
return shaderSource;
}
private static Stream GetShaderStream(string shaderName)
{
var assembly = typeof(ShaderCompiler).Assembly;
var stream = assembly
.GetManifestResourceNames()
.Where(p => p.EndsWith(shaderName))
.Select(assembly.GetManifestResourceStream)
.FirstOrDefault();
if (stream == null)
{
Console.WriteLine("shader not found: " + shaderName);
Environment.Exit(-1);
}
return stream;
}
private static int CheckErrors(int shaderHandle, int vertexShader, int fragmentShader)
{
GL.GetProgram(shaderHandle, GetProgramParameterName.LinkStatus, out int success);
if (success != 0) return success;
Console.Error.WriteLine("shaders link failed");
Console.Error.WriteLine(GL.GetProgramInfoLog(shaderHandle));
var vertexShaderInfoLog = GL.GetShaderInfoLog(vertexShader);
if (!string.IsNullOrWhiteSpace(vertexShaderInfoLog))
{
Console.Error.WriteLine("vs info-log: ");
Console.Error.WriteLine(vertexShaderInfoLog);
}
var fragmentShaderInfoLog = GL.GetShaderInfoLog(fragmentShader);
if (!string.IsNullOrWhiteSpace(fragmentShaderInfoLog))
{
Console.Error.WriteLine("fs info-log: ");
Console.Error.WriteLine(fragmentShaderInfoLog);
}
return success;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment