public static Shader LoadShader(string shaderName, ArgumentDependencies modelArguments) { var shaderFileName = GetShaderFileByName(shaderName); var shaderCacheHash = (shaderFileName + modelArguments).GetHashCode(); // shader collision roulette Shader shader; #if !DEBUG_SHADERS || !DEBUG if (CachedShaders.TryGetValue(shaderCacheHash, out shader)) { return shader; } #endif /* Vertex shader */ var vertexShader = GL.CreateShader(ShaderType.VertexShader); var assembly = Assembly.GetExecutingAssembly(); #if DEBUG_SHADERS && DEBUG using (var stream = File.Open($"../../../{ShaderDirectory.Replace('.', '/')}{shaderFileName}.vert", FileMode.Open)) //<-- reloading at runtime #else using (var stream = assembly.GetManifestResourceStream($"{ShaderDirectory}{shaderFileName}.vert")) #endif using (var reader = new StreamReader(stream)) { var shaderSource = reader.ReadToEnd(); GL.ShaderSource(vertexShader, PreprocessVertexShader(shaderSource, modelArguments)); } GL.CompileShader(vertexShader); int shaderStatus; GL.GetShader(vertexShader, ShaderParameter.CompileStatus, out shaderStatus); if (shaderStatus != 1) { string vsInfo; GL.GetShaderInfoLog(vertexShader, out vsInfo); throw new Exception($"Error setting up Vertex Shader \"{shaderName}\": {vsInfo}"); } /* Fragment shader */ var fragmentShader = GL.CreateShader(ShaderType.FragmentShader); #if DEBUG_SHADERS && DEBUG using (var stream = File.Open($"../../../{ShaderDirectory.Replace('.', '/')}{shaderFileName}.frag", FileMode.Open)) //<-- reloading at runtime #else using (var stream = assembly.GetManifestResourceStream($"{ShaderDirectory}{shaderFileName}.frag")) #endif using (var reader = new StreamReader(stream)) { GL.ShaderSource(fragmentShader, reader.ReadToEnd()); } GL.CompileShader(fragmentShader); GL.GetShader(fragmentShader, ShaderParameter.CompileStatus, out shaderStatus); if (shaderStatus != 1) { string fsInfo; GL.GetShaderInfoLog(fragmentShader, out fsInfo); throw new Exception($"Error setting up Fragment Shader \"{shaderName}\": {fsInfo}"); } shader = new Shader(); shader.Program = GL.CreateProgram(); GL.AttachShader(shader.Program, vertexShader); GL.AttachShader(shader.Program, fragmentShader); GL.LinkProgram(shader.Program); var programInfoLog = GL.GetProgramInfoLog(shader.Program); Console.Write(programInfoLog); GL.ValidateProgram(shader.Program); int linkStatus; GL.GetProgram(shader.Program, GetProgramParameterName.LinkStatus, out linkStatus); if (linkStatus != 1) { string linkInfo; GL.GetProgramInfoLog(shader.Program, out linkInfo); throw new Exception("Error linking shaders: " + linkInfo); } GL.DetachShader(shader.Program, vertexShader); GL.DeleteShader(vertexShader); GL.DetachShader(shader.Program, fragmentShader); GL.DeleteShader(fragmentShader); #if !DEBUG_SHADERS || !DEBUG CachedShaders[shaderCacheHash] = shader; Console.WriteLine("Shader #{0} ({1}) compiled and linked succesfully", CachedShaders.Count, shaderName); #endif return shader; }