Last active
August 9, 2023 09:15
-
-
Save caverna/c099a7c9ead4366651ce4f7ab522fd66 to your computer and use it in GitHub Desktop.
OpenGL shader compiler from embedded resources
This file contains hidden or 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.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