private void Compile() { if (!IsLoaded) { throw new Exception($"Shader.Compile ({Name}) not loaded."); } GL.ShaderSource(Handle, Source); GL.CompileShader(Handle); string infoLog = GL.GetShaderInfoLog(Handle).TrimEnd(); int compileStatus; GL.GetShader(Handle, ShaderParameter.CompileStatus, out compileStatus); if (compileStatus != 1) { var ex = new ShaderCompileException(Name, infoLog, Source); LogError($"{ex.DetailedError}"); throw ex; } else { LogTrace($"{infoLog}"); } }
/// <summary> /// Reads the contents of a file into a string /// </summary> /// <param name="shaderFile">path to the shader file</param> /// <param name="testCompileInclude">should includes be compiled (for error checking) before being pasted into the including shader</param> /// <returns> /// string with contents of shaderFile /// </returns> /// <exception cref="FileNotFoundException"> /// Could not find shader file '" + shaderFile + "' /// or /// Could not find include-file '" + sIncludeFileName + "' for shader '" + shaderFile + "'. /// </exception> public static string ShaderStringFromFileWithIncludes(string shaderFile, bool testCompileInclude) { string sShader = null; if (!File.Exists(shaderFile)) { throw new FileNotFoundException("Could not find shader file '" + shaderFile + "'"); } sShader = File.ReadAllText(shaderFile); //handle includes string sCurrentPath = Path.GetDirectoryName(shaderFile) + Path.DirectorySeparatorChar; // get path to current shader string sName = Path.GetFileName(shaderFile); //split into lines var lines = sShader.Split(new[] { Environment.NewLine }, StringSplitOptions.None); var pattern = @"^\s*#include\s+""([^""]+)"""; //match everything inside " except " so we get shortest ".+" match int lineNr = 1; foreach (var line in lines) { // Search for include pattern (e.g. #include raycast.glsl) (nested not supported) foreach (Match match in Regex.Matches(line, pattern, RegexOptions.Singleline)) { string sFullMatch = match.Value; string sIncludeFileName = match.Groups[1].ToString(); // get the filename to include string sIncludePath = sCurrentPath + sIncludeFileName; // build path to file if (!File.Exists(sIncludePath)) { throw new FileNotFoundException("Could not find include-file '" + sIncludeFileName + "' for shader '" + shaderFile + "'."); } string sIncludeShd = File.ReadAllText(sIncludePath); // read include as string if (testCompileInclude) { using (var shader = new ShaderProgramGL()) { try { shader.Compile(sIncludeShd, ShaderType.FragmentShader); //test compile include shader } catch (ShaderCompileException e) { var ce = new ShaderCompileException(e.ShaderType, "include compile '" + sIncludePath + "'", e.ShaderLog, sIncludeShd); ce.Data.Add(ExceptionDataFileName, sIncludePath); throw ce; } } } sIncludeShd += Environment.NewLine + "#line " + lineNr.ToString() + Environment.NewLine; sShader = sShader.Replace(sFullMatch, sIncludeShd); // replace #include with actual include } ++lineNr; } return(sShader); }
/// <summary> /// Compiles the specified shader source code. /// </summary> /// <param name="shaderSourceCode">The shader source code.</param> /// <param name="type">The type.</param> /// <exception cref="ShaderCompileException"></exception> public void Compile(string shaderSourceCode, ShaderType type) { var shader = new ShaderGL(type); if (!shader.Compile(shaderSourceCode)) { var e = new ShaderCompileException(type, shader.Log, shaderSourceCode); shader.Dispose(); throw e; } Attach(shader); }
public void Compile() { if (this.Init() != -1) { GL.ShaderSource(this.Handle, this.Source); GL.CompileShader(this.Handle); string infoLog = GL.GetShaderInfoLog(this.Handle).TrimEnd(); int compileStatus; GL.GetShader(this.Handle, ShaderParameter.CompileStatus, out compileStatus); if (compileStatus != 1) { var ex = new ShaderCompileException(this.Name, infoLog, this.Source); log.Error("Shader.Compile ({0}): {1}", this.Name, ex.DetailedError); throw ex; } else { log.Trace("Shader.Compile ({0}): {1}", this.Name, infoLog); } } }