public ShaderGenerator( Compilation compilation, LanguageBackend[] languages, IShaderSetProcessor[] processors) { if (compilation == null) { throw new ArgumentNullException(nameof(compilation)); } if (languages == null) { throw new ArgumentNullException(nameof(languages)); } if (processors == null) { throw new ArgumentNullException(nameof(processors)); } if (languages.Length == 0) { throw new ArgumentException("At least one LanguageBackend must be provided."); } _compilation = compilation; _languages = new List <LanguageBackend>(languages); ShaderSetDiscoverer ssd = new ShaderSetDiscoverer(); foreach (SyntaxTree tree in _compilation.SyntaxTrees) { ssd.Visit(tree.GetRoot()); } _shaderSets.AddRange(ssd.GetShaderSets()); _processors = processors; }
public ShaderGenerator( Compilation compilation, LanguageBackend[] languages, string vertexFunctionName = null, string fragmentFunctionName = null, string computeFunctionName = null, params IShaderSetProcessor[] processors) { if (languages == null) { throw new ArgumentNullException(nameof(languages)); } if (languages.Length < 1) { throw new ArgumentException("At least one LanguageBackend must be provided."); } _compilation = compilation ?? throw new ArgumentNullException(nameof(compilation)); _languages = languages.ToArray(); _processors = processors; // If we've not specified any names, we're auto-discovering if (string.IsNullOrWhiteSpace(vertexFunctionName) && string.IsNullOrWhiteSpace(fragmentFunctionName) && string.IsNullOrWhiteSpace(computeFunctionName)) { ShaderSetDiscoverer ssd = new ShaderSetDiscoverer(); foreach (SyntaxTree tree in _compilation.SyntaxTrees) { ssd.Visit(tree.GetRoot()); } _shaderSets = ssd.GetShaderSets(); return; } // We've explicitly specified shaders so find them directly. List <ShaderSetInfo> shaderSets = new List <ShaderSetInfo>(); TypeAndMethodName vertex = null; if (!string.IsNullOrWhiteSpace(vertexFunctionName) && !TypeAndMethodName.Get(vertexFunctionName, out vertex)) { throw new ShaderGenerationException( $"The name passed to {nameof(vertexFunctionName)} must be a fully-qualified type and method."); } TypeAndMethodName fragment = null; if (!string.IsNullOrWhiteSpace(fragmentFunctionName) && !TypeAndMethodName.Get(fragmentFunctionName, out fragment)) { throw new ShaderGenerationException( $"The name passed to {nameof(fragmentFunctionName)} must be a fully-qualified type and method."); } if (vertex != null || fragment != null) { // We have either a vertex or fragment, so create a graphics shader set. string setName = string.Empty; if (vertex != null) { setName = vertexFunctionName; } if (fragment != null) { if (setName == string.Empty) { setName = fragmentFunctionName; } else { setName += "+" + fragmentFunctionName; } } shaderSets.Add(new ShaderSetInfo(setName, vertex, fragment)); } TypeAndMethodName compute = null; if (!string.IsNullOrWhiteSpace(computeFunctionName) && !TypeAndMethodName.Get(computeFunctionName, out compute)) { throw new ShaderGenerationException( $"The name passed to {nameof(computeFunctionName)} must be a fully-qualified type and method."); } if (compute != null) { shaderSets.Add(new ShaderSetInfo(computeFunctionName, compute)); } _shaderSets = shaderSets.ToArray(); }