public List <EFVariant> Apply(List <EFVariant> source) { var result = new List <EFVariant>(); foreach (var sourceVariant in source) { foreach (var define in Defines) { var variant = new EFVariant { Platform = sourceVariant.Platform, Defines = sourceVariant.Defines != null ? new Dictionary <string, string>(sourceVariant.Defines) : new Dictionary <string, string>() }; variant.Defines[define.Name] = define.Value; result.Add(variant); } } foreach (var entry in Children) { result = entry.Apply(result); } return(result); }
public Effect GetEffect(GraphicsDevice device, Dictionary <string, string> defines) { var key = EFVariant.BuildKey(EFUtils.CurrentPlatform, defines); Effect result; if (_effects.TryGetValue(key, out result)) { return(result); } EFSource source; if (!_sources.TryGetValue(key, out source)) { return(null); } var bytes = new byte[source.Size]; using (var stream = _streamOpener()) { stream.Seek(source.Offset, SeekOrigin.Begin); stream.Read(bytes, 0, source.Size); } result = new Effect(device, bytes); _effects[key] = result; return(result); }
public static Dictionary <string, EFSource> LocateSources(Stream input) { var result = new Dictionary <string, EFSource>(); using (var reader = new BinaryReader(input)) { // Signature var sig = Encoding.UTF8.GetString(reader.ReadBytes(3)); if (sig != EfbSignature) { throw new Exception("Wrong signature."); } var version = reader.ReadInt32(); if (version != EfbVersion) { throw new Exception(string.Format("Wrong efb version. File version: {0}, supported version: {1}.", version, EfbVersion)); } while (true) { try { var source = new EFSource(); var data = reader.ReadString(); source.Variant = EFVariant.FromString(data); var size = reader.ReadInt32(); source.Offset = (int)input.Position; source.Size = size; // Skip data input.Seek(size, SeekOrigin.Current); result[data] = source; } catch (EndOfStreamException) { break; } } } return(result); }
static ShaderMacro[] ToMacroses(EFVariant variant) { var result = new List <ShaderMacro>(); if (variant.Defines != null) { var orderedKeys = from k in variant.Defines.Keys where !string.IsNullOrEmpty(k) orderby k select k; foreach (var k in orderedKeys) { result.Add(new ShaderMacro(k, variant.Defines[k])); } } return(result.ToArray()); }
public bool Equals(EFVariant v) { return(ToString() == v.ToString()); }
static void Main(string[] args) { Log("Effect farm compiler to efb {0}.", EFParser.EfbVersion); if (args.Length < 2) { Log("Usage: efc <input_file> <config_file> [output_file]"); return; } try { var inputFile = args[0]; if (!File.Exists(inputFile)) { Log("Could not find '0'.", inputFile); return; } var configFile = args[1]; if (!File.Exists(inputFile)) { Log("Could not find '0'.", inputFile); return; } var doc = XDocument.Parse(File.ReadAllText(configFile)); // Parse config var config = new Config { Targets = ParseTargets(doc) }; if (config.Targets.Length == 0) { GenerateError("No target platforms."); } var rootEntry = (from n in doc.Descendants("RootEntry") select n).FirstOrDefault(); if (rootEntry == null) { GenerateError("Could not find 'RootEntry' node."); } config.Root = ParseEntry(rootEntry); var variants = config.BuildVariants().ToArray(); var outputFile = string.Empty; if (args.Length < 3) { outputFile = Path.ChangeExtension(inputFile, "efb"); } else { outputFile = Path.ChangeExtension(args[2], "efb"); } var outputLwt = File.GetLastWriteTime(outputFile); if (File.Exists(outputFile) && outputLwt > File.GetLastWriteTime(inputFile) && outputLwt > File.GetLastWriteTime(configFile)) { var resultVariants = Substract(variants, outputFile); if (resultVariants.Length == 0) { Log("{0} is up to date.", Path.GetFileName(outputFile)); return; } } var workingFolder = Path.GetDirectoryName(inputFile); var includeFx = new IncludeFX(workingFolder); var importerContext = new ImporterContext(); var processorContext = new ProcessorContext(); var effectImporter = new EffectImporter(); var effectProcesor = new EffectProcessor(); Log("{0} variants of effects are going to be compiled.", variants.Length); using (var stream = File.Open(outputFile, FileMode.Create)) using (var writer = new BinaryWriter(stream)) { writer.Write(Encoding.UTF8.GetBytes(EFParser.EfbSignature)); writer.Write(EFParser.EfbVersion); var idx = 0; foreach (var variant in variants) { Log("#" + idx + ": " + variant.ToString()); switch (variant.Platform) { case EFPlatform.MonoGameDirectX: case EFPlatform.MonoGameOpenGL: { var content = effectImporter.Import(inputFile, importerContext); processorContext._targetPlatform = variant.Platform == EFPlatform.MonoGameDirectX ? TargetPlatform.Windows : TargetPlatform.DesktopGL; effectProcesor.Defines = EFVariant.BuildKey(variant.Defines); var result = effectProcesor.Process(content, processorContext); WriteOutput(writer, variant, result.GetEffectCode()); } break; case EFPlatform.FNA: { var result = ShaderBytecode.CompileFromFile(inputFile, "fx_2_0", ShaderFlags.OptimizationLevel3, EffectFlags.None, ToMacroses(variant), includeFx); if (result.ResultCode != Result.Ok) { GenerateError(result.Message); } WriteOutput(writer, variant, result.Bytecode); } break; } ++idx; } } Log("Compilation to {0} was succesful.", Path.GetFileName(outputFile)); } catch (Exception ex) { Log(ex.ToString()); } }
static void WriteOutput(BinaryWriter writer, EFVariant variant, byte[] data) { writer.Write(variant.ToString()); writer.Write(data.Length); writer.Write(data); }