private static void Update(ShaderProgramGL shaderProgram, IEnumerable <NamedStream> namedStreams, bool solutionMode) { string ShaderCode(Stream stream) { using (var reader = new StreamReader(stream, true)) { var code = reader.ReadToEnd(); if (solutionMode) { code = code.Replace("#ifdef SOLUTION", "#if 1"); } return(code); } } var count = namedStreams.Count(); if (2 > count) { return; } foreach (var res in namedStreams) { var shaderType = GetShaderTypeFromExtension(Path.GetExtension(res.Name)); var shaderCode = ShaderCode(res.Stream); shaderProgram.Compile(shaderCode, shaderType); } shaderProgram.Link(); }
/// <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); }
private static void Update(ShaderProgramGL shaderProgram, IEnumerable <NamedStream> namedStreams) { var count = namedStreams.Count(); if (2 > count) { return; } foreach (var res in namedStreams) { var shaderType = GetShaderTypeFromExtension(Path.GetExtension(res.Name)); shaderProgram.Compile(ShaderCode(res.Stream), shaderType); } shaderProgram.Link(); }