private static TextureContent CompileTexture(IAssetFsFile assetFile, TargetPlatform platform, TextureContent monogameOutput, string[] importOptions, bool allowResizeToPowerOfTwo, bool allowMakeSquare, PipelineManager manager)
        {
            var dictionary = new OpaqueDataDictionary();

            dictionary["GenerateMipmaps"]    = importOptions.Contains("GenerateMipmaps");
            dictionary["ResizeToPowerOfTwo"] = allowResizeToPowerOfTwo && !importOptions.Contains("NoResizeToPowerOfTwo");
            dictionary["MakeSquare"]         = allowMakeSquare && !importOptions.Contains("MakeSquare");
            dictionary["TextureFormat"]      = importOptions.Contains("NoCompress") ? TextureProcessorOutputFormat.Color : TextureProcessorOutputFormat.Compressed;
            var            processor = manager.CreateProcessor("TextureProcessor", dictionary);
            var            context   = new DummyContentProcessorContext(TargetPlatformCast.ToMonoGamePlatform(platform));
            TextureContent content;

            try
            {
                content = (TextureContent)processor.Process(monogameOutput, context);
            }
            catch (AccessViolationException)
            {
                // Sometimes the nvtt compressor crashes on some textures.  Workaround by turning off compression
                // in this case.
                Console.WriteLine("WARNING: Disabling texture compression on " + assetFile.Name + " due to nvtt bugs");
                dictionary["TextureFormat"] = TextureProcessorOutputFormat.Color;
                processor = manager.CreateProcessor("TextureProcessor", dictionary);
                context   = new DummyContentProcessorContext(TargetPlatformCast.ToMonoGamePlatform(platform));
                content   = (TextureContent)processor.Process(monogameOutput, context);
            }

            return(content);
        }
        public async Task CompileAsync(IAssetFsFile assetFile, IAssetDependencies assetDependencies, TargetPlatform platform, IWritableSerializedAsset output)
        {
            if (IntPtr.Size == 4)
            {
                throw new NotSupportedException("Font compilation is only supported under a 64-bit process.");
            }

            var json = string.Empty;

            using (var reader = new StreamReader(await assetFile.GetContentStream().ConfigureAwait(false)))
            {
                json = await reader.ReadToEndAsync().ConfigureAwait(false);
            }

            var fontDefinition = JsonConvert.DeserializeObject <FontDefinition>(json);

            foreach (var fontDesc in this.GetDescriptionsForAsset(fontDefinition))
            {
                try
                {
                    var manager = new PipelineManager(
                        Environment.CurrentDirectory,
                        Environment.CurrentDirectory,
                        Environment.CurrentDirectory);
                    var dictionary = new OpaqueDataDictionary();
                    var processor  = manager.CreateProcessor("FontDescriptionProcessor", dictionary);
                    var context    = new DummyContentProcessorContext(TargetPlatformCast.ToMonoGamePlatform(platform));
                    var content    = processor.Process(fontDesc, context);

                    output.SetLoader <IAssetLoader <FontAsset> >();
                    output.SetPlatform(platform);
                    output.SetByteArray("Data", CompileAndGetBytes(content));
                    output.SetString("FontName", fontDesc.FontName);
                    output.SetFloat("FontSize", fontDesc.Size);
                    output.SetBoolean("UseKerning", fontDesc.UseKerning);
                    output.SetFloat("Spacing", fontDesc.Spacing);

                    // Font compilation was successful.
                    return;
                }
                catch (ArgumentOutOfRangeException)
                {
                    // The user might not have the font installed...
                }
                catch (NullReferenceException)
                {
                    // The user might not have the font installed...
                }
            }

            throw new InvalidOperationException("Unable to locate any font with one of the names: " + fontDefinition.FontName);
        }
        public async Task CompileAsync(IAssetFsFile assetFile, IAssetDependencies assetDependencies, TargetPlatform platform, IWritableSerializedAsset output)
        {
            string level;

            using (var reader = new StreamReader(await assetFile.GetContentStream().ConfigureAwait(false)))
            {
                level = await reader.ReadToEndAsync().ConfigureAwait(false);
            }

            output.SetLoader <IAssetLoader <LevelAsset> >();
            output.SetString("LevelData", level);
            output.SetString("LevelDataFormat", "OgmoEditor");
        }
Exemple #4
0
        private async Task WriteAssetFsFileToStream(BinaryWriter writer, IAssetFsFile assetFsFile)
        {
            writer.Write((string)assetFsFile.Name);
            writer.Write((string)assetFsFile.Extension);
            writer.Write((Int64)assetFsFile.ModificationTimeUtcTimestamp.Ticks);
            var dependents = await assetFsFile.GetDependentOnAssetFsFileNames().ConfigureAwait(false);

            writer.Write((Int32)dependents.Length);
            for (var i = 0; i < dependents.Length; i++)
            {
                writer.Write((string)dependents[i]);
            }
        }
Exemple #5
0
        public async Task CompileAsync(IAssetFsFile assetFile, IAssetDependencies assetDependencies, TargetPlatform platform, IWritableSerializedAsset output)
        {
            TilesetJson tilesetJson;

            using (var stream = new StreamReader(await assetFile.GetContentStream().ConfigureAwait(false)))
            {
                tilesetJson = JsonConvert.DeserializeObject <TilesetJson>(await stream.ReadToEndAsync().ConfigureAwait(false));
            }

            output.SetLoader <IAssetLoader <TilesetAsset> >();
            output.SetString("TextureName", tilesetJson.TextureName);
            output.SetInt32("CellWidth", tilesetJson.CellWidth);
            output.SetInt32("CellHeight", tilesetJson.CellHeight);
        }
        public async Task CompileAsync(IAssetFsFile assetFile, IAssetDependencies assetDependencies, TargetPlatform platform, IWritableSerializedAsset output)
        {
            using (var reader = new StreamReader(await assetFile.GetContentStream().ConfigureAwait(false)))
            {
                var content = await reader.ReadToEndAsync().ConfigureAwait(false);

                // Validate that the XML is valid so we don't throw exceptions at runtime.
                var document = new XmlDocument();
                document.LoadXml(content);

                output.SetLoader <IAssetLoader <UserInterfaceAsset> >();
                output.SetString("UserInterfaceFormat", "XmlVersion2");
                output.SetString("UserInterfaceData", content);
            }
        }
Exemple #7
0
        public async Task CompileAsync(IAssetFsFile assetFile, IAssetDependencies assetDependencies, TargetPlatform platform, IWritableSerializedAsset output)
        {
            using (var content = await assetFile.GetContentStream().ConfigureAwait(false))
            {
                // Currently we just copy the raw data.  According to the XNA documentation:

                /*
                 * The Stream object must point to the head of a valid PCM wave file. Also, this wave file must be in the RIFF bitstream format.
                 * The audio format has the following restrictions:
                 * Must be a PCM wave file
                 * Can only be mono or stereo
                 * Must be 8 or 16 bit
                 * Sample rate must be between 8,000 Hz and 48,000 Hz
                 */
                output.SetLoader <IAssetLoader <AudioAsset> >();
                var bytes = new byte[content.Length];
                await content.ReadAsync(bytes, 0, bytes.Length).ConfigureAwait(false);

                output.SetByteArray("Data", bytes);
            }
        }
Exemple #8
0
        public async Task CompileAsync(IAssetFsFile assetFile, IAssetDependencies assetDependencies, TargetPlatform platform, IWritableSerializedAsset output)
        {
            var otherAnimations = new Dictionary <string, byte[]>();

            if (assetFile.Extension != "x")
            {
                var otherFiles = (await assetDependencies.GetAvailableCompileTimeFiles())
                                 .Where(x => x.Name.StartsWith(assetFile.Name + "-"))
                                 .ToArray();
                foreach (var otherAnim in otherFiles)
                {
                    using (var otherStream = await otherAnim.GetContentStream().ConfigureAwait(false))
                    {
                        var b = new byte[otherStream.Length];
                        await otherStream.ReadAsync(b, 0, b.Length).ConfigureAwait(false);

                        otherAnimations[otherAnim.Name.Substring((assetFile.Name + "-").Length)] = b;
                    }
                }
            }

            var nameComponents = assetFile.Name.Split('.');

            nameComponents[nameComponents.Length - 1] = "_FolderOptions";
            var folderOptionsFile = await assetDependencies.GetOptionalCompileTimeFileDependency(string.Join(".", nameComponents)).ConfigureAwait(false);

            string[] importFolderOptions = null;
            if (folderOptionsFile != null)
            {
                using (var optionsReader = new StreamReader(await folderOptionsFile.GetContentStream().ConfigureAwait(false)))
                {
                    importFolderOptions = optionsReader.ReadToEnd()
                                          .Trim()
                                          .Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
                                          .Select(x => x.Trim())
                                          .Where(x => !x.StartsWith("#"))
                                          .ToArray();
                }
            }

            var optionsFile = await assetDependencies.GetOptionalCompileTimeFileDependency(assetFile.Name + ".Options").ConfigureAwait(false);

            string[] importOptions = null;
            if (optionsFile != null)
            {
                using (var optionsReader = new StreamReader(await optionsFile.GetContentStream().ConfigureAwait(false)))
                {
                    importOptions = optionsReader.ReadToEnd()
                                    .Trim()
                                    .Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
                                    .Select(x => x.Trim())
                                    .Where(x => !x.StartsWith("#"))
                                    .ToArray();
                }
            }

            if (importOptions == null)
            {
                importOptions = importFolderOptions;
            }

            byte[] modelData;
            using (var stream = await assetFile.GetContentStream().ConfigureAwait(false))
            {
                modelData = new byte[stream.Length];
                await stream.ReadAsync(modelData, 0, modelData.Length).ConfigureAwait(false);
            }

            var reader = new AssimpReader(_modelRenderConfigurations, _renderBatcher);
            var model  = reader.Load(modelData, assetFile.Name, assetFile.Extension, otherAnimations, importOptions);
            var data   = _modelSerializer.Serialize(model);

            output.SetLoader <IAssetLoader <ModelAsset> >();
            output.SetByteArray("Data", data);
        }
 protected virtual void OnCompileFailure(IAssetFsFile assetFile, Exception exception, TargetPlatform targetPlatform)
 {
 }
 protected virtual void OnCompileFinish(IAssetFsFile assetFile, IAssetFsFile compiledAssetFile, TargetPlatform targetPlatform)
 {
 }
 protected virtual void OnCompilerMissing(IAssetFsFile assetFile, TargetPlatform targetPlatform)
 {
 }
 protected virtual void OnCompileStart(IAssetFsFile assetFile, TargetPlatform targetPlatform)
 {
 }
Exemple #13
0
 protected override void OnCompilerMissing(IAssetFsFile assetFile, TargetPlatform targetPlatform)
 {
     Console.WriteLine("No compiler available for " + assetFile.Name);
 }
        public async Task CompileAsync(IAssetFsFile assetFile, IAssetDependencies assetDependencies, TargetPlatform platform, IWritableSerializedAsset output)
        {
            var tempPath = System.IO.Path.GetTempFileName();

            try
            {
                using (var stream = new FileStream(tempPath, FileMode.Create, FileAccess.Write, FileShare.None))
                {
                    using (var sourceStream = await assetFile.GetContentStream().ConfigureAwait(false))
                    {
                        await sourceStream.CopyToAsync(stream).ConfigureAwait(false);
                    }
                }

                var importer       = new TextureImporter();
                var monogameOutput = importer.Import(tempPath, new DummyContentImporterContext());

                var originalWidth  = monogameOutput.Faces[0][0].Width;
                var originalHeight = monogameOutput.Faces[0][0].Height;

                var nameComponents = assetFile.Name.Split('.');
                nameComponents[nameComponents.Length - 1] = "_FolderOptions";
                var folderOptionsFile = await assetDependencies.GetOptionalCompileTimeFileDependency(string.Join(".", nameComponents)).ConfigureAwait(false);

                string[] importFolderOptions = null;
                if (folderOptionsFile != null)
                {
                    using (var optionsReader = new StreamReader(await folderOptionsFile.GetContentStream().ConfigureAwait(false)))
                    {
                        importFolderOptions = optionsReader.ReadToEnd()
                                              .Trim()
                                              .Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
                                              .Select(x => x.Trim())
                                              .Where(x => !x.StartsWith("#"))
                                              .ToArray();
                    }
                }

                var optionsFile = await assetDependencies.GetOptionalCompileTimeFileDependency(assetFile.Name + ".Options").ConfigureAwait(false);

                string[] importOptions = null;
                if (optionsFile != null)
                {
                    using (var optionsReader = new StreamReader(await optionsFile.GetContentStream().ConfigureAwait(false)))
                    {
                        importOptions = optionsReader.ReadToEnd()
                                        .Trim()
                                        .Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
                                        .Select(x => x.Trim())
                                        .Where(x => !x.StartsWith("#"))
                                        .ToArray();
                    }
                }

                if (importOptions == null)
                {
                    importOptions = importFolderOptions;
                }
                if (importOptions == null)
                {
                    importOptions = new string[0];
                }

                var allowResizeToPowerOfTwo = !IsPowerOfTwo((ulong)originalWidth) || !IsPowerOfTwo((ulong)originalHeight);
                var allowMakeSquare         = originalWidth != originalHeight;

                var manager = new PipelineManager(
                    Environment.CurrentDirectory,
                    Environment.CurrentDirectory,
                    Environment.CurrentDirectory);
                TextureContent content = CompileTexture(assetFile, platform, monogameOutput, importOptions, allowResizeToPowerOfTwo, allowMakeSquare, manager);

                Console.WriteLine("Texture " + assetFile.Name + " resized " + originalWidth + "x" + originalHeight + " -> " + content.Faces[0][0].Width + "x" + content.Faces[0][0].Height);

                output.SetLoader <IAssetLoader <TextureAsset> >();
                output.SetPlatform(platform);
                output.SetByteArray("Data", CompileAndGetBytes(content));
                output.SetInt32("OriginalWidth", originalWidth);
                output.SetInt32("OriginalHeight", originalHeight);
            }
            finally
            {
                try
                {
                    File.Delete(tempPath);
                }
                catch
                {
                }
            }
        }
        public async Task CompileAsync(IAssetFsFile assetFile, IAssetDependencies assetDependencies, TargetPlatform platform, IWritableSerializedAsset output)
        {
            var code = string.Empty;

            using (var reader = new StreamReader(await assetFile.GetContentStream().ConfigureAwait(false)))
            {
                code = await reader.ReadToEndAsync().ConfigureAwait(false);
            }

            if (code.Contains("// uber"))
            {
                // Do nothing with this file.
                return;
            }

            var dirName = Path.GetDirectoryName(assetFile.Name.Replace(".", "/"));

            code = await ResolveIncludes(assetDependencies, dirName.Replace(Path.DirectorySeparatorChar, '.'), code).ConfigureAwait(false);

            var effectContent = new EffectContent();

            effectContent.EffectCode = this.GetEffectPrefixCode() + code;

            var tempPath = Path.GetTempFileName();

            using (var writer = new StreamWriter(tempPath))
            {
                writer.Write(effectContent.EffectCode);
            }

            effectContent.Identity = new ContentIdentity(tempPath);

            var tempOutputPath = Path.GetTempFileName();

            var debugContent = EffectCompilerHelper.Compile(
                effectContent,
                tempOutputPath,
                platform,
                true,
                string.Empty);
            var releaseContent = EffectCompilerHelper.Compile(
                effectContent,
                tempOutputPath,
                platform,
                false,
                string.Empty);

            using (var stream = new MemoryStream())
            {
                using (var writer = new BinaryWriter(stream))
                {
                    // Magic flag that indicates new compiled effect format.
                    writer.Write((uint)0x12345678);

                    // Version 1 of new effect format.
                    writer.Write((uint)1);

                    var debugCode   = debugContent.GetEffectCode();
                    var releaseCode = releaseContent.GetEffectCode();

                    writer.Write(debugCode.Length);
                    writer.Write(debugCode);
                    writer.Write(releaseCode.Length);
                    writer.Write(releaseCode);

                    var p = stream.Position;
                    var b = new byte[p];
                    stream.Seek(0, SeekOrigin.Begin);
                    stream.Read(b, 0, b.Length);

                    output.SetLoader <IAssetLoader <EffectAsset> >();
                    output.SetPlatform(platform);
                    output.SetByteArray("Data", b);
                }
            }

            File.Delete(tempPath);
            File.Delete(tempOutputPath);
        }
        public async Task CompileAsync(IAssetFsFile assetFile, IAssetDependencies assetDependencies, TargetPlatform platform, IWritableSerializedAsset output)
        {
            var code = string.Empty;

            using (var reader = new StreamReader(await assetFile.GetContentStream().ConfigureAwait(false)))
            {
                code = await reader.ReadToEndAsync().ConfigureAwait(false);
            }

            if (!code.Contains("// uber"))
            {
                // Do nothing with this file.
                return;
            }

            var dirName = Path.GetDirectoryName(assetFile.Name.Replace(".", "/"));

            code = await ResolveIncludes(assetDependencies, dirName.Replace(Path.DirectorySeparatorChar, '.'), code).ConfigureAwait(false);

            var allPassed   = true;
            var effectCodes = new Dictionary <string, Tuple <string, byte[], byte[]> >();

            foreach (var rawLine in code.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries))
            {
                var line = rawLine.Trim();
                if (line.StartsWith("#line"))
                {
                    continue;
                }
                if (!line.StartsWith("// uber "))
                {
                    break;
                }

                var components = line.Substring("// uber ".Length).Split(':');
                var name       = components[0].Trim();
                var defines    = components[1].Trim();

                Console.WriteLine();
                Console.Write("Compiling uber shader variant " + name + "... ");

                var effectOutput = new EffectContent();
                effectOutput.EffectCode = this.GetEffectPrefixCode() + code;

                string tempPath = null, tempOutputPath = null;
                try
                {
                    tempPath       = Path.GetTempFileName();
                    tempOutputPath = Path.GetTempFileName();

                    using (var writer = new StreamWriter(tempPath))
                    {
                        writer.Write(effectOutput.EffectCode);
                    }

                    effectOutput.Identity = new ContentIdentity(tempPath);

                    var debugContent = EffectCompilerHelper.Compile(
                        effectOutput,
                        tempOutputPath,
                        platform,
                        true,
                        defines);
                    var releaseContent = EffectCompilerHelper.Compile(
                        effectOutput,
                        tempOutputPath,
                        platform,
                        false,
                        defines);

                    effectCodes[name] = new Tuple <string, byte[], byte[]>(defines, debugContent.GetEffectCode(), releaseContent.GetEffectCode());
                    Console.Write("done.");
                }
                catch (InvalidContentException ex)
                {
                    Console.WriteLine("failed.");
                    Console.Write(ex.Message.Trim());
                    allPassed = false;
                }
                finally
                {
                    if (tempOutputPath != null)
                    {
                        File.Delete(tempOutputPath);
                    }

                    if (tempOutputPath != null)
                    {
                        File.Delete(tempPath);
                    }
                }
            }

            Console.WriteLine();
            Console.Write("Finalizing uber shader compilation... ");

            if (!allPassed)
            {
                throw new Exception("One or more uber shader variants failed to compile (see above!)");
            }

            using (var memory = new MemoryStream())
            {
                using (var writer = new BinaryWriter(memory))
                {
                    writer.Write((uint)2);
                    writer.Write((uint)effectCodes.Count);
                    foreach (var kv in effectCodes)
                    {
                        writer.Write(kv.Key);
                        writer.Write(kv.Value.Item1);
                        writer.Write(kv.Value.Item2.Length);
                        writer.Write(kv.Value.Item2);
                        writer.Write(kv.Value.Item3.Length);
                        writer.Write(kv.Value.Item3);
                    }

                    var len  = memory.Position;
                    var data = new byte[len];
                    memory.Seek(0, SeekOrigin.Begin);
                    memory.Read(data, 0, data.Length);

                    output.SetLoader <IAssetLoader <UberEffectAsset> >();
                    output.SetPlatform(platform);
                    output.SetByteArray("Data", data);
                }
            }
        }
Exemple #17
0
 protected override void OnCompileFinish(IAssetFsFile assetFile, IAssetFsFile compiledAssetFile, TargetPlatform targetPlatform)
 {
     Console.WriteLine("Compiled " + assetFile.Name + " for " + targetPlatform.ToString());
 }
        private async Task <IAssetFsFile> EnsureCompiled(IAssetFsFile file)
        {
            if (file == null)
            {
                return(null);
            }

            if (file.Extension == "bin")
            {
                return(file);
            }

            SemaphoreSlim localCompilerLock;
            await _compilerLock.WaitAsync().ConfigureAwait(false);

            try
            {
                if (_compiledOverlay.ContainsKey(file.Name))
                {
                    return(_compiledOverlay[file.Name]);
                }

                if (_compilerLocks.ContainsKey(file.Name))
                {
                    localCompilerLock = _compilerLocks[file.Name];
                }
                else
                {
                    localCompilerLock         = new SemaphoreSlim(1);
                    _compilerLocks[file.Name] = localCompilerLock;
                }
            }
            finally
            {
                _compilerLock.Release();
            }

            await localCompilerLock.WaitAsync().ConfigureAwait(false);

            try
            {
                await _compilerLock.WaitAsync().ConfigureAwait(false);

                try
                {
                    if (_compiledOverlay.ContainsKey(file.Name))
                    {
                        return(_compiledOverlay[file.Name]);
                    }
                }
                finally
                {
                    _compilerLock.Release();
                }

                var compilers = _compilers.Where(x => x.Extensions.Contains(file.Extension)).ToArray();
                if (compilers.Length == 0)
                {
                    // No compiler available for this type.
                    OnCompilerMissing(file, _targetPlatform);
                    return(null);
                }

                OnCompileStart(file, _targetPlatform);
                var serializedAsset = new WritableSerializedAsset();
                try
                {
                    foreach (var compiler in compilers)
                    {
                        await compiler.CompileAsync(file, new AssetDependencies(this, serializedAsset), _targetPlatform, serializedAsset).ConfigureAwait(false);
                    }
                }
                catch (Exception ex)
                {
                    OnCompileFailure(file, ex, _targetPlatform);
                    throw;
                }

                var memory = new MemoryStream();
                serializedAsset.WriteTo(memory);
                var compiledFsFile = new CompiledFsFile(file.Name, DateTimeOffset.UtcNow, memory);
                OnCompileFinish(file, compiledFsFile, _targetPlatform);
                _compiledOverlay[file.Name] = compiledFsFile;
                return(_compiledOverlay[file.Name]);
            }
            finally
            {
                localCompilerLock.Release();
            }
        }
 protected override void OnCompileFailure(IAssetFsFile assetFile, Exception ex, TargetPlatform targetPlatform)
 {
     Console.WriteLine("Compile of " + assetFile.Name + " failed for " + targetPlatform.ToString() + ": " + ex);
 }
Exemple #20
0
 protected override void OnCompileStart(IAssetFsFile assetFile, TargetPlatform targetPlatform)
 {
     Console.WriteLine("Compiling " + assetFile.Name + " for " + targetPlatform.ToString() + "...");
 }