public override IEnumerable <CompilerParameters> Generate(AssetCompilerContext context, CompilerParameters baseParameters, ILogger log)
        {
            var allMaterialParameters = new List <ParameterCollection>();

            if (baseParameters.Get(MaterialAssetKeys.GenerateShader))
            {
                var assetManager = new AssetManager();
                var settings     = new AssetManagerLoaderSettings()
                {
                    ContentFilter = AssetManagerLoaderSettings.NewContentFilterByType(typeof(MaterialData)),
                };

                var hashParameters = new HashSet <ObjectId>();

                foreach (var materialAssetItem in context.Package.Assets.Where(item => item.Asset is MaterialAsset))
                {
                    var assetPath = materialAssetItem.Location.GetDirectoryAndFileName();
                    try
                    {
                        var materialData = assetManager.Load <MaterialData>(assetPath, settings);
                        if (materialData != null && materialData.Parameters != null && materialData.Parameters.Count > 0)
                        {
                            var materialParameters = new ParameterCollection();
                            AddToParameters(materialData.Parameters, materialParameters);
                            if (materialParameters.Count > 0)
                            {
                                byte[] buffer1;
                                var    id = ObjectId.FromObject(materialParameters, out buffer1);
                                if (!hashParameters.Contains(id))
                                {
                                    hashParameters.Add(id);
                                    allMaterialParameters.Add(materialParameters);
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        log.Error("Error while loading material [{0}]", ex, assetPath);
                    }
                }
            }

            if (allMaterialParameters.Count != 0)
            {
                foreach (var materialParams in allMaterialParameters)
                {
                    var compilerParameters = baseParameters.Clone();
                    materialParams.CopyTo(compilerParameters);
                    yield return(compilerParameters);
                }
            }
            else
            {
                yield return(baseParameters.Clone());
            }
        }
Beispiel #2
0
        protected override Task <ResultStatus> DoCommandOverride(ICommandContext commandContext)
        {
            var compiler = GetOrCreateEffectCompiler(context);

            // Get main effect name (before the first dot)
            var isSdfx = ShaderMixinManager.Contains(effectName);
            var source = isSdfx ?
                         new ShaderMixinGeneratorSource(effectName) :
                         (ShaderSource) new ShaderClassSource(effectName);

            int permutationCount;

            lock (PermutationCount)
            {
                PermutationCount.TryGetValue(effectName, out permutationCount);
                permutationCount++;
                PermutationCount[effectName] = permutationCount;
            }
            commandContext.Logger.Verbose($"Trying permutation #{permutationCount} for effect [{effectName}]: \n{compilerParameters.ToStringPermutationsDetailed()}");

            var compilerResults = compiler.Compile(source, compilerParameters);

            // Copy logs and if there are errors, exit directly
            compilerResults.CopyTo(commandContext.Logger);
            if (compilerResults.HasErrors)
            {
                return(Task.FromResult(ResultStatus.Failed));
            }

            // Wait for result an check compilation status
            var completedTask = compilerResults.Bytecode.WaitForResult();

            completedTask.CompilationLog.CopyTo(commandContext.Logger);
            if (completedTask.CompilationLog.HasErrors)
            {
                return(Task.FromResult(ResultStatus.Failed));
            }

            // Register all dependencies
            var allSources = new HashSet <string>(
                completedTask.Bytecode.HashSources.Select(keyPair => keyPair.Key));

            foreach (var className in allSources)
            {
                commandContext.RegisterInputDependency(new ObjectUrl(UrlType.Content, EffectCompilerBase.GetStoragePathFromShaderType(className)));
            }

            // Generate sourcecode if configured
            if (compilerParameters.ContainsKey(EffectSourceCodeKeys.Enable))
            {
                var outputDirectory = UPath.Combine(package.RootDirectory, baseUrl);

                var fieldName = compilerParameters.Get(EffectSourceCodeKeys.FieldName);
                if (fieldName.StartsWith("binary"))
                {
                    fieldName = fieldName.Substring("binary".Length);
                    if (char.IsUpper(fieldName[0]))
                    {
                        fieldName = char.ToLower(fieldName[0]) + fieldName.Substring(1);
                    }
                }

                var outputClassFile     = effectName + "." + fieldName + "." + compilerParameters.EffectParameters.Platform + "." + compilerParameters.EffectParameters.Profile + ".cs";
                var fullOutputClassFile = Path.Combine(outputDirectory.ToWindowsPath(), outputClassFile);

                commandContext.Logger.Verbose($"Writing shader bytecode to .cs source [{fullOutputClassFile}].");
                using (var stream = new FileStream(fullOutputClassFile, FileMode.Create, FileAccess.Write, FileShare.Write))
                    EffectByteCodeToSourceCodeWriter.Write(effectName, compilerParameters, compilerResults.Bytecode.WaitForResult().Bytecode, new StreamWriter(stream, System.Text.Encoding.UTF8));
            }

            return(Task.FromResult(ResultStatus.Successful));
        }
        public static void Write(string name, CompilerParameters parameters, EffectBytecode effectData, TextWriter writer)
        {
            const string codeTemplate         = @"//------------------------------------------------------------------------------
// <auto-generated>
//     Paradox Effect Compiler File Generated:
{0}//
//     Command Line: {7}
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace {1} 
{{
    {2} class {3}
    {{
        {4} static readonly byte[] {5} = new byte[] {{
{6}
        }};
    }}
}}
";
            var          effectToGenerateText = new StringBuilder();

            effectToGenerateText.AppendFormat("//     Effect [{0}]\r\n", name);

            var buffer = new MemoryStream();

            effectData.WriteTo(buffer);

            var bufferAsText = new StringBuilder();
            var bufferArray  = buffer.ToArray();

            for (int i = 0; i < bufferArray.Length; i++)
            {
                bufferAsText.Append(bufferArray[i]).Append(", ");
                if (i > 0 && (i % 64) == 0)
                {
                    bufferAsText.AppendLine();
                }
            }

            var classDeclaration = parameters.Get(EffectSourceCodeKeys.ClassDeclaration);
            var fieldDeclaration = parameters.Get(EffectSourceCodeKeys.FieldDeclaration);
            var nameSpace        = parameters.Get(EffectSourceCodeKeys.Namespace);
            var className        = parameters.Get(EffectSourceCodeKeys.ClassName) ?? name;
            var fieldName        = parameters.Get(EffectSourceCodeKeys.FieldName);

            var commandLine = string.Join(" ", Environment.GetCommandLineArgs());

            var    graphicsPlatform = parameters.Get(CompilerParameters.GraphicsPlatformKey);
            string paradoxDefine    = "undefined";

            switch (graphicsPlatform)
            {
            case GraphicsPlatform.Direct3D11:
                paradoxDefine = "SILICONSTUDIO_PARADOX_GRAPHICS_API_DIRECT3D11";
                break;

            case GraphicsPlatform.OpenGL:
                paradoxDefine = "SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGLCORE";
                break;

            case GraphicsPlatform.OpenGLES:
                paradoxDefine = "SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGLES";
                break;
            }

            writer.WriteLine("#if {0}", paradoxDefine);
            writer.Write(codeTemplate,
                         effectToGenerateText, // {0}
                         nameSpace,            // {1}
                         classDeclaration,     // {2}
                         className,            // {3}
                         fieldDeclaration,     // {4}
                         fieldName,            // {5}
                         bufferAsText,         // {6}
                         commandLine);         // {7}

            writer.WriteLine("#endif");

            writer.Flush();
        }
        public override IEnumerable <CompilerParameters> Generate(AssetCompilerContext context, CompilerParameters baseParameters, ILogger log)
        {
            // Cache all the entity parameters once
            List <EntityParameters> entityParametersList;
            var entityParametersSet = (ConcurrentDictionary <Guid, List <EntityParameters> >)context.Properties.GetOrAdd(EntityParametersKey, key => new ConcurrentDictionary <Guid, List <EntityParameters> >());

            entityParametersList = entityParametersSet.GetOrAdd(context.Package.Id, key =>
            {
                var assetManager = new AssetManager();

                var settings = new AssetManagerLoaderSettings()
                {
                    ContentFilter = AssetManagerLoaderSettings.NewContentFilterByType(typeof(ModelData), typeof(MeshData), typeof(MaterialData), typeof(LightingConfigurationsSetData)),
                };

                var allEntityParameters = new List <EntityParameters>();
                foreach (var entityAssetItem in context.Package.Assets.Where(item => item.Asset is EntityAsset))
                {
                    var assetPath = entityAssetItem.Location.GetDirectoryAndFileName();
                    try
                    {
                        var entity = assetManager.Load <EntityData>(assetPath, settings);

                        foreach (var modelComponent in entity.Components.Select(x => x.Value).OfType <ModelComponentData>())
                        {
                            foreach (var meshData in modelComponent.Model.Value.Meshes)
                            {
                                var lightingParameters = GetLightingParameters(meshData);
                                var materialParameters = GetMeshMaterialParameters(meshData);

                                if (lightingParameters == null || lightingParameters.Count == 0)
                                {
                                    EntityParameters entityParameters;
                                    entityParameters.MaterialParameters = materialParameters;
                                    entityParameters.ModelParameters    = modelComponent.Parameters;
                                    entityParameters.MeshParameters     = meshData != null ? meshData.Parameters : null;
                                    entityParameters.LightingParameters = null;
                                    allEntityParameters.Add(entityParameters);
                                }
                                else
                                {
                                    foreach (var lightConfig in lightingParameters)
                                    {
                                        EntityParameters entityParameters;
                                        entityParameters.MaterialParameters = materialParameters;
                                        entityParameters.ModelParameters    = modelComponent.Parameters;
                                        entityParameters.MeshParameters     = meshData != null ? meshData.Parameters : null;
                                        entityParameters.LightingParameters = lightConfig;
                                        allEntityParameters.Add(entityParameters);
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        log.Error("Error while loading model mesh [{0}]", ex, assetPath);
                    }
                }

                return(allEntityParameters);
            });

            var useMeshParameters     = baseParameters.Get(MeshKeys.UseParameters);
            var useMaterialParameters = baseParameters.Get(MaterialAssetKeys.UseParameters) && !baseParameters.Get(MaterialAssetKeys.GenerateShader);

            if ((useMeshParameters || useMaterialParameters) && entityParametersList.Count != 0)
            {
                var hashParameters = new HashSet <ObjectId>();

                foreach (var entityParameters in entityParametersList)
                {
                    // Add parameters in this order
                    // 1. Material
                    // 2. ModelComponent (Entity)
                    // 3. Mesh
                    // 4. Lighting

                    var newParameters = new ParameterCollection();
                    if (useMaterialParameters)
                    {
                        AddToParameters(entityParameters.MaterialParameters, newParameters);
                    }

                    AddToParameters(entityParameters.ModelParameters, newParameters);

                    if (useMeshParameters)
                    {
                        AddToParameters(entityParameters.MeshParameters, newParameters);
                    }

                    AddToParameters(entityParameters.LightingParameters, newParameters);

                    byte[] buffer1;
                    var    id = ObjectId.FromObject(newParameters, out buffer1);
                    if (!hashParameters.Contains(id))
                    {
                        hashParameters.Add(id);
                        var compilerParameters = baseParameters.Clone();
                        newParameters.CopyTo(compilerParameters);
                        yield return(compilerParameters);
                    }
                }
            }
            else
            {
                yield return(baseParameters.Clone());
            }
        }
        // Module defining this command


        // Optional custom code for this activity


        /// <summary>
        /// Returns a configured instance of System.Management.Automation.PowerShell, pre-populated with the command to run.
        /// </summary>
        /// <param name="context">The NativeActivityContext for the currently running activity.</param>
        /// <returns>A populated instance of System.Management.Automation.PowerShell</returns>
        /// <remarks>The infrastructure takes responsibility for closing and disposing the PowerShell instance returned.</remarks>
        protected override ActivityImplementationContext GetPowerShell(NativeActivityContext context)
        {
            System.Management.Automation.PowerShell invoker       = global::System.Management.Automation.PowerShell.Create();
            System.Management.Automation.PowerShell targetCommand = invoker.AddCommand(PSCommandName);

            // Initialize the arguments

            if (CodeDomProvider.Expression != null)
            {
                targetCommand.AddParameter("CodeDomProvider", CodeDomProvider.Get(context));
            }

            if (CompilerParameters.Expression != null)
            {
                targetCommand.AddParameter("CompilerParameters", CompilerParameters.Get(context));
            }

            if (TypeDefinition.Expression != null)
            {
                targetCommand.AddParameter("TypeDefinition", TypeDefinition.Get(context));
            }

            if (Name.Expression != null)
            {
                targetCommand.AddParameter("Name", Name.Get(context));
            }

            if (MemberDefinition.Expression != null)
            {
                targetCommand.AddParameter("MemberDefinition", MemberDefinition.Get(context));
            }

            if (Namespace.Expression != null)
            {
                targetCommand.AddParameter("Namespace", Namespace.Get(context));
            }

            if (UsingNamespace.Expression != null)
            {
                targetCommand.AddParameter("UsingNamespace", UsingNamespace.Get(context));
            }

            if (Path.Expression != null)
            {
                targetCommand.AddParameter("Path", Path.Get(context));
            }

            if (LiteralPath.Expression != null)
            {
                targetCommand.AddParameter("LiteralPath", LiteralPath.Get(context));
            }

            if (AssemblyName.Expression != null)
            {
                targetCommand.AddParameter("AssemblyName", AssemblyName.Get(context));
            }

            if (Language.Expression != null)
            {
                targetCommand.AddParameter("Language", Language.Get(context));
            }

            if (ReferencedAssemblies.Expression != null)
            {
                targetCommand.AddParameter("ReferencedAssemblies", ReferencedAssemblies.Get(context));
            }

            if (OutputAssembly.Expression != null)
            {
                targetCommand.AddParameter("OutputAssembly", OutputAssembly.Get(context));
            }

            if (OutputType.Expression != null)
            {
                targetCommand.AddParameter("OutputType", OutputType.Get(context));
            }

            if (PassThru.Expression != null)
            {
                targetCommand.AddParameter("PassThru", PassThru.Get(context));
            }

            if (IgnoreWarnings.Expression != null)
            {
                targetCommand.AddParameter("IgnoreWarnings", IgnoreWarnings.Get(context));
            }


            return(new ActivityImplementationContext()
            {
                PowerShellInstance = invoker
            });
        }