_getShaderCode(ParsedShader shader) { var header = new StringBuilder(); foreach (var uniform in shader.Uniforms.Values) { if (uniform.DefaultValue != null) { header.AppendFormat("uniform {0} {1} = {2};", uniform.Type.GetNativeType(), uniform.Name, uniform.DefaultValue); } else { header.AppendFormat("uniform {0} {1};", uniform.Type.GetNativeType(), uniform.Name); } } // TODO: Varyings. ShaderFunctionDefinition fragmentMain = null; ShaderFunctionDefinition vertexMain = null; foreach (var function in shader.Functions) { if (function.Name == "fragment") { fragmentMain = function; continue; } if (function.Name == "vertex") { vertexMain = function; continue; } header.AppendFormat("{0} {1}(", function.ReturnType.GetNativeType(), function.Name); var first = true; foreach (var parameter in function.Parameters) { if (!first) { header.Append(", "); } first = false; header.AppendFormat("{0} {1} {2}", parameter.Qualifiers.GetString(), parameter.Type.GetNativeType(), parameter.Name); } header.AppendFormat(") {{\n{0}\n}}\n", function.Body); } return(header.ToString(), vertexMain?.Body ?? "", fragmentMain?.Body ?? ""); }
private (string vertBody, string fragBody) GetShaderCode(ParsedShader shader) { var headerUniforms = new StringBuilder(); foreach (var constant in shader.Constants.Values) { headerUniforms.AppendFormat("const {0} {1} = {2};\n", constant.Type.GetNativeType(), constant.Name, constant.Value); } foreach (var uniform in shader.Uniforms.Values) { if (uniform.DefaultValue != null) { headerUniforms.AppendFormat("uniform {0} {1} = {2};\n", uniform.Type.GetNativeType(), uniform.Name, uniform.DefaultValue); } else { headerUniforms.AppendFormat("uniform {0} {1};\n", uniform.Type.GetNativeType(), uniform.Name); } } var varyingsFragment = new StringBuilder(); var varyingsVertex = new StringBuilder(); foreach (var(name, varying) in shader.Varyings) { varyingsFragment.AppendFormat("in {0} {1};\n", varying.Type.GetNativeType(), name); varyingsVertex.AppendFormat("out {0} {1};\n", varying.Type.GetNativeType(), name); } ShaderFunctionDefinition fragmentMain = null; ShaderFunctionDefinition vertexMain = null; var functionsBuilder = new StringBuilder(); foreach (var function in shader.Functions) { if (function.Name == "fragment") { fragmentMain = function; continue; } if (function.Name == "vertex") { vertexMain = function; continue; } functionsBuilder.AppendFormat("{0} {1}(", function.ReturnType.GetNativeType(), function.Name); var first = true; foreach (var parameter in function.Parameters) { if (!first) { functionsBuilder.Append(", "); } first = false; functionsBuilder.AppendFormat("{0} {1} {2}", parameter.Qualifiers.GetString(), parameter.Type.GetNativeType(), parameter.Name); } functionsBuilder.AppendFormat(") {{\n{0}\n}}\n", function.Body); } var(wrapVert, wrapFrag) = shader.Preset switch { ShaderPreset.Default => (_shaderWrapCodeDefaultVert, _shaderWrapCodeDefaultFrag), ShaderPreset.Raw => (_shaderWrapCodeRawVert, _shaderWrapCodeRawFrag), _ => throw new NotSupportedException() }; var vertexHeader = $"{headerUniforms}\n{varyingsVertex}\n{functionsBuilder}"; var fragmentHeader = $"{headerUniforms}\n{varyingsFragment}\n{functionsBuilder}"; // These are prefixed with comments because the syntax highlighter I'm using doesn't like the brackets. // And it's producing a lot of squigly lines. var vertexSource = wrapVert.Replace("// [SHADER_HEADER_CODE]", vertexHeader); var fragmentSource = wrapFrag.Replace("// [SHADER_HEADER_CODE]", fragmentHeader); if (vertexMain != null) { vertexSource = vertexSource.Replace("// [SHADER_CODE]", vertexMain.Body); } if (fragmentMain != null) { fragmentSource = fragmentSource.Replace("// [SHADER_CODE]", fragmentMain.Body); } return(vertexSource, fragmentSource); }