/// <summary> /// Iterates all of the tile sets and builds external references to the textures. Useful if you want to just /// load the resulting map and not have to also load up textures. The external reference is stored on the /// TileSet's Texture field so make sure you serialize that if you call this method. /// </summary> public static void BuildTileSetTextures(MapContent input, ContentProcessorContext context, string textureRoot = "") { foreach (var tileSet in input.TileSets) { // get the real path to the image string path = Path.Combine(textureRoot, tileSet.Image); // the asset name is the entire path, minus extension, after the content directory string asset = string.Empty; if (path.StartsWith(Directory.GetCurrentDirectory())) asset = path.Remove(tileSet.Image.LastIndexOf('.')).Substring(Directory.GetCurrentDirectory().Length + 1); else asset = Path.GetFileNameWithoutExtension(path); // build the asset as an external reference OpaqueDataDictionary data = new OpaqueDataDictionary(); data.Add("GenerateMipmaps", false); data.Add("ResizeToPowerOfTwo", false); data.Add("TextureFormat", TextureProcessorOutputFormat.Color); data.Add("ColorKeyEnabled", tileSet.ColorKey.HasValue); data.Add("ColorKeyColor", tileSet.ColorKey.HasValue ? tileSet.ColorKey.Value : Microsoft.Xna.Framework.Color.Magenta); tileSet.Texture = context.BuildAsset<Texture2DContent, Texture2DContent>( new ExternalReference<Texture2DContent>(path), null, data, null, asset); } }
protected override MaterialContent ConvertMaterial(MaterialContent material, ContentProcessorContext context) { var customMaterial = new EffectMaterialContent(); customMaterial.Effect = new ExternalReference<EffectContent>(effectPath); //var basicMaterial = (BasicMaterialContent) material; //if (basicMaterial.Texture != null) //{ // customMaterial.Textures.Add(skyMapKey, basicMaterial.Texture); //} foreach (var texture in material.Textures) { customMaterial.Textures.Add(texture.Key, texture.Value); } var parameters = new OpaqueDataDictionary(); parameters["ColorKeyColor"] = ColorKeyColor; parameters["ColorKeyEnabled"] = ColorKeyEnabled; parameters["TextureFormat"] = TextureFormat; parameters["GenerateMipmaps"] = GenerateMipmaps; parameters["ResizeTexturesToPowerOfTwo"] = ResizeTexturesToPowerOfTwo; return context.Convert<MaterialContent, MaterialContent>( customMaterial, typeof(MaterialProcessor).Name, parameters); }
public OpaqueDataDictionaryElementPropertyDescriptor(string propertyName, Type propertyType, OpaqueDataDictionary target) : base(propertyName, new Attribute[] { }) { _propertyType = propertyType; _propertyName = propertyName; _componentType = typeof(OpaqueDataDictionary); _target = target; }
protected override ExternalReference<CompiledEffectContent> BuildEffect(ExternalReference<EffectContent> effect, ContentProcessorContext context) { OpaqueDataDictionary processorParameters = new OpaqueDataDictionary(); if (context.Parameters.ContainsKey("Defines")) processorParameters.Add("Defines", context.Parameters["Defines"]); return context.BuildAsset<EffectContent, CompiledEffectContent>(effect, "DeferredRendererFXProcessor", processorParameters, "EffectImporter", effect.Name); }
public PipelineBuildEvent() { SourceFile = string.Empty; DestFile = string.Empty; Importer = string.Empty; Processor = string.Empty; Parameters = new OpaqueDataDictionary(); ParametersXml = new List<Pair>(); Dependancies = new List<string>(); BuildAsset = new List<string>(); }
/// <summary> /// Use our custom material processor /// to convert selected materials in this model. /// </summary> protected override MaterialContent ConvertMaterial(MaterialContent material, ContentProcessorContext context) { if (CustomMaterialProcessor == "") return base.ConvertMaterial(material, context); OpaqueDataDictionary processorParameters = new OpaqueDataDictionary(); processorParameters.Add("Section", section); return context.Convert<MaterialContent, MaterialContent>(material, CustomMaterialProcessor, processorParameters); }
/// <summary> /// Use our custom EnvironmentMappedMaterialProcessor /// to convert all the materials on this model. /// </summary> protected override MaterialContent ConvertMaterial(MaterialContent material, ContentProcessorContext context) { OpaqueDataDictionary processorParameters = new OpaqueDataDictionary(); processorParameters["ColorKeyColor"] = ColorKeyColor; processorParameters["ColorKeyEnabled"] = ColorKeyEnabled; processorParameters["TextureFormat"] = TextureFormat; processorParameters["GenerateMipmaps"] = GenerateMipmaps; processorParameters["ResizeTexturesToPowerOfTwo"] = ResizeTexturesToPowerOfTwo; return context.Convert<MaterialContent, MaterialContent>(material, "TankModelMaterialProcessor", processorParameters); }
/// <summary> /// Use the CustomEffectMaterialProcessor for all of the materials in the model. /// We pass the processor parameter along to the material processor for the /// effect file name. /// </summary> protected override MaterialContent ConvertMaterial(MaterialContent material, ContentProcessorContext context) { OpaqueDataDictionary processorParameters = new OpaqueDataDictionary(); processorParameters.Add("CustomEffect", customEffect); processorParameters["ColorKeyColor"] = this.ColorKeyColor; processorParameters["ColorKeyEnabled"] = this.ColorKeyEnabled; processorParameters["TextureFormat"] = this.TextureFormat; processorParameters["GenerateMipmaps"] = this.GenerateMipmaps; processorParameters["ResizeTexturesToPowerOfTwo"] = this.ResizeTexturesToPowerOfTwo; return context.Convert<MaterialContent, MaterialContent>(material, "CustomEffectMaterialProcessor", processorParameters); }
protected override MaterialContent ConvertMaterial(MaterialContent material, ContentProcessorContext context) { var customMaterial = new EffectMaterialContent(); var effectPath = Path.GetFullPath(effectFilename); customMaterial.Effect = new ExternalReference<EffectContent>(effectPath); var parameters = new OpaqueDataDictionary(); parameters["ColorKeyColor"] = ColorKeyColor; parameters["ColorKeyEnabled"] = ColorKeyEnabled; parameters["TextureFormat"] = TextureFormat; parameters["GenerateMipmaps"] = GenerateMipmaps; parameters["ResizeTexturesToPowerOfTwo"] = ResizeTexturesToPowerOfTwo; return context.Convert<MaterialContent, MaterialContent>( customMaterial, typeof(MaterialProcessor).Name, parameters); }
protected override ExternalReference<TextureContent> BuildTexture(string textureName, ExternalReference<TextureContent> texture, ContentProcessorContext context) { // Fallback if we aren't buiding for iOS. var platform = ContentHelper.GetMonoGamePlatform(); if (platform != MonoGamePlatform.iOS) return base.BuildTexture(textureName, texture, context); var processorParameters = new OpaqueDataDictionary(); processorParameters.Add("ColorKeyColor", this.ColorKeyColor); processorParameters.Add("ColorKeyEnabled", this.ColorKeyEnabled); processorParameters.Add("TextureFormat", this.TextureFormat); processorParameters.Add("GenerateMipmaps", this.GenerateMipmaps); processorParameters.Add("ResizeToPowerOfTwo", this.ResizeTexturesToPowerOfTwo); processorParameters.Add("PremultiplyAlpha", this.PremultiplyTextureAlpha); return context.BuildAsset<TextureContent, TextureContent>(texture, typeof(MGTextureProcessor).Name, processorParameters, null, null); }
protected override MaterialContent ConvertMaterial(MaterialContent material, ContentProcessorContext context) { EffectMaterialContent lppMaterial = new EffectMaterialContent(); OpaqueDataDictionary processorParameters = new OpaqueDataDictionary(); processorParameters["ColorKeyColor"] = this.ColorKeyColor; processorParameters["ColorKeyEnabled"] = this.ColorKeyEnabled; processorParameters["TextureFormat"] = this.TextureFormat; processorParameters["GenerateMipmaps"] = this.GenerateMipmaps; processorParameters["ResizeTexturesToPowerOfTwo"] = this.ResizeTexturesToPowerOfTwo; processorParameters["PremultiplyTextureAlpha"] = false; processorParameters["ColorKeyEnabled"] = false; lppMaterial.Effect = new ExternalReference<EffectContent>("shaders/LPPMainEffect.fx"); lppMaterial.CompiledEffect = context.BuildAsset<EffectContent, CompiledEffectContent>(lppMaterial.Effect, "EffectProcessor"); //extract the extra parameters ExtractDefines(lppMaterial, material, context); // copy the textures in the original material to the new normal mapping // material. this way the diffuse texture is preserved. The // PreprocessSceneHierarchy function has already added the normal map // texture to the Textures collection, so that will be copied as well. foreach (KeyValuePair<String, ExternalReference<TextureContent>> texture in material.Textures) { lppMaterial.Textures.Add(texture.Key, texture.Value); } try { lppMaterial.OpaqueData.Add("DiffuseColor", new Vector4((Vector3)material.OpaqueData["DiffuseColor"], (float)material.OpaqueData["Alpha"])); lppMaterial.OpaqueData.Add("SpecularColor", material.OpaqueData["SpecularColor"]); lppMaterial.OpaqueData.Add("SpecularPower", material.OpaqueData["SpecularPower"]); } catch (Exception ex) { Console.WriteLine(ex); } // and convert the material using the NormalMappingMaterialProcessor, // who has something special in store for the normal map. return context.Convert<MaterialContent, MaterialContent> (lppMaterial, typeof(LightPrePassMaterialProcessor).Name, processorParameters); }
protected override MaterialContent ConvertMaterial(MaterialContent material, ContentProcessorContext context) { var basicMaterial = new EffectMaterialContent { Effect = new ExternalReference<EffectContent>("../HMEngineContent/Shaders/BasicShader.fx") }; var processorParameters = new OpaqueDataDictionary(); processorParameters["ColorKeyColor"] = ColorKeyColor; processorParameters["ColorKeyEnabled"] = ColorKeyEnabled; processorParameters["TextureFormat"] = TextureFormat; processorParameters["GenerateMipmaps"] = GenerateMipmaps; processorParameters["ResizeTexturesToPowerOfTwo"] = ResizeTexturesToPowerOfTwo; // Copy any textures already added to the built in material to our custom basicMaterial foreach (KeyValuePair<String, ExternalReference<TextureContent>> texture in material.Textures) { basicMaterial.Textures.Add(texture.Key, texture.Value); } // Convert the material using the HMMaterialProcessor. This will perform any special texture processing we need return context.Convert<MaterialContent, MaterialContent>(basicMaterial, typeof (HMMaterialProcessor).Name, processorParameters); }
public static ExternalReference<Texture2DContent> LoadTexture(string imagePath, Color? color_key, ContentProcessorContext context, string textureRoot = "") { string path = Path.Combine(textureRoot, imagePath); // the asset name is the entire path, minus extension, after the content directory string asset = string.Empty; if (path.StartsWith(Directory.GetCurrentDirectory())) asset = path.Remove(imagePath.LastIndexOf('.')).Substring(Directory.GetCurrentDirectory().Length + 1); else asset = Path.GetFileNameWithoutExtension(path); // build the asset as an external reference OpaqueDataDictionary data = new OpaqueDataDictionary(); data.Add("GenerateMipmaps", false); data.Add("ResizeToPowerOfTwo", false); data.Add("TextureFormat", TextureProcessorOutputFormat.Color); data.Add("ColorKeyEnabled", color_key.HasValue); data.Add("ColorKeyColor", color_key.HasValue ? color_key.Value : Microsoft.Xna.Framework.Color.Magenta); return context.BuildAsset<Texture2DContent, Texture2DContent>( new ExternalReference<Texture2DContent>(path), null, data, null, asset); }
public IContentProcessor CreateProcessor(string name, OpaqueDataDictionary processorParameters) { var processorType = GetProcessorType(name); if (processorType == null) return null; // Create the processor. var processor = (IContentProcessor)Activator.CreateInstance(processorType); // Convert and set the parameters on the processor. foreach (var param in processorParameters) { var propInfo = processorType.GetProperty(param.Key, BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.Instance); if (propInfo == null || propInfo.GetSetMethod(false) == null) continue; // If the property value is already of the correct type then set it. if (propInfo.PropertyType.IsInstanceOfType(param.Value)) propInfo.SetValue(processor, param.Value, null); else { // Find a type converter for this property. var typeConverter = TypeDescriptor.GetConverter(propInfo.PropertyType); if (typeConverter.CanConvertFrom(param.Value.GetType())) { var propValue = typeConverter.ConvertFrom(null, CultureInfo.InvariantCulture, param.Value); propInfo.SetValue(processor, propValue, null); } } } return processor; }
private void ProcessTextures(ThemeContent theme, ContentProcessorContext context) { theme.Textures = new NamedObjectCollection <ThemeTextureContent>(); var document = theme.Description; if (document.Root == null) { string message = string.Format("Root element \"<Theme>\" is missing in XML."); throw new InvalidContentException(message, theme.Identity); } if (document.Root.Elements("Texture").Any()) { // Issue error because theme file is using old alpha version format. throw new InvalidContentException("Given theme file is using a format which is no longer supported. All textures need to be defined inside a 'Textures' node.", theme.Identity); } var texturesElement = document.Root.Element("Textures"); if (texturesElement == null) { throw new InvalidContentException("Given theme file does not contain a 'Textures' node.", theme.Identity); } foreach (var textureElement in texturesElement.Elements("Texture")) { string name = GetMandatoryAttribute(textureElement, "Name", theme.Identity); bool isDefault = (bool?)textureElement.Attribute("IsDefault") ?? false; string filename = GetMandatoryAttribute(textureElement, "File", theme.Identity); bool premultiplyAlpha = (bool?)textureElement.Attribute("PremultiplyAlpha") ?? true; // Get path of texture relative to root directory without file extension. string textureSourcePath = FindFile(theme, filename); string relativeTextureSourcePath = _sourceRootDirectoryUri.MakeRelativeUri(new Uri(textureSourcePath)).OriginalString; relativeTextureSourcePath = Uri.UnescapeDataString(relativeTextureSourcePath); string extension = Path.GetExtension(relativeTextureSourcePath); relativeTextureSourcePath = relativeTextureSourcePath.Remove( relativeTextureSourcePath.Length - extension.Length, extension.Length); // Build Texture. var processorParameters = new OpaqueDataDictionary(); processorParameters.Add("PremultiplyAlpha", premultiplyAlpha); var textureReference = context.BuildAsset <TextureContent, TextureContent>( new ExternalReference <TextureContent>(textureSourcePath), "TextureProcessor", processorParameters, "TextureImporter", relativeTextureSourcePath); var texture = new ThemeTextureContent { Name = name, IsDefault = isDefault, Texture = textureReference, }; theme.Textures.Add(texture); } if (theme.Textures.Count == 0) { throw new InvalidContentException("The UI theme does not contain any textures. At least 1 texture is required.", theme.Identity); } }
protected override MaterialContent ConvertMaterial(MaterialContent material, ContentProcessorContext context) { string effectFile = this.effectFileName; if (string.IsNullOrEmpty(effectFile)) { if (string.IsNullOrEmpty(this.normalMapTexture)) { if (string.IsNullOrEmpty(this.diffuseTexture)) effectFile = "Effects\\DefaultSolidColor.fx"; else effectFile = "Effects\\Default.fx"; } else effectFile = "Effects\\DefaultNormalMap.fx"; } EffectMaterialContent normalMappingMaterial = new EffectMaterialContent(); normalMappingMaterial.Effect = new ExternalReference<EffectContent>(Path.Combine(directory, effectFile)); OpaqueDataDictionary processorParameters = new OpaqueDataDictionary(); processorParameters["ColorKeyColor"] = this.ColorKeyColor; processorParameters["ColorKeyEnabled"] = this.ColorKeyEnabled; processorParameters["TextureFormat"] = this.TextureFormat; processorParameters["PremultiplyTextureAlpha"] = this.PremultiplyTextureAlpha; processorParameters["PremultiplyVertexColors"] = this.PremultiplyVertexColors; processorParameters["GenerateMipmaps"] = this.GenerateMipmaps; processorParameters["ResizeTexturesToPowerOfTwo"] = this.ResizeTexturesToPowerOfTwo; // copy the textures in the original material to the new normal mapping // material. this way the diffuse texture is preserved. The // PreprocessSceneHierarchy function has already added the normal map // texture to the Textures collection, so that will be copied as well. foreach (KeyValuePair<String, ExternalReference<TextureContent>> texture in material.Textures) normalMappingMaterial.Textures.Add(texture.Key, texture.Value); if (!string.IsNullOrEmpty(diffuseTexture)) normalMappingMaterial.Textures.Add("DiffuseTexture", new ExternalReference<TextureContent>(Path.Combine(directory, diffuseTexture))); // and convert the material using the NormalMappingMaterialProcessor, // who has something special in store for the normal map. #if MONOGAME return context.Convert<MaterialContent, MaterialContent>(normalMappingMaterial, typeof(MGMaterialProcessor).Name, processorParameters); #else return context.Convert<MaterialContent, MaterialContent>(normalMappingMaterial, typeof(MaterialProcessor).Name, processorParameters); #endif }
public PipelineBuildEvent BuildContent(string sourceFilepath, string outputFilepath = null, string importerName = null, string processorName = null, OpaqueDataDictionary processorParameters = null) { sourceFilepath = PathHelper.Normalize(sourceFilepath); ResolveOutputFilepath(sourceFilepath, ref outputFilepath); ResolveImporterAndProcessor(sourceFilepath, ref importerName, ref processorName); // Record what we're building and how. var contentEvent = new PipelineBuildEvent { SourceFile = sourceFilepath, DestFile = outputFilepath, Importer = importerName, Processor = processorName, Parameters = ValidateProcessorParameters(processorName, processorParameters), }; // Load the previous content event if it exists. string eventFilepath; var cachedEvent = LoadBuildEvent(contentEvent.DestFile, out eventFilepath); BuildContent(contentEvent, cachedEvent, eventFilepath); return(contentEvent); }
protected override MaterialContent ConvertMaterial(MaterialContent material, ContentProcessorContext context) { EffectMaterialContent lppMaterial = new EffectMaterialContent(); OpaqueDataDictionary processorParameters = new OpaqueDataDictionary(); processorParameters["ColorKeyColor"] = this.ColorKeyColor; processorParameters["ColorKeyEnabled"] = false; processorParameters["TextureFormat"] = this.TextureFormat; processorParameters["GenerateMipmaps"] = this.GenerateMipmaps; processorParameters["ResizeTexturesToPowerOfTwo"] = this.ResizeTexturesToPowerOfTwo; processorParameters["PremultiplyTextureAlpha"] = false; processorParameters["ColorKeyEnabled"] = false; lppMaterial.Effect = new ExternalReference<EffectContent>(_customFx.Length == 0 ? "shaders/LPPMainEffect.fx" : _customFx); lppMaterial.CompiledEffect = context.BuildAsset<EffectContent, CompiledEffectContent>(lppMaterial.Effect, "EffectProcessor"); // copy the textures in the original material to the new lpp // material ExtractTextures(lppMaterial, material); //extract the extra parameters ExtractDefines(lppMaterial, material, context); // and convert the material using the NormalMappingMaterialProcessor, // who has something special in store for the normal map. return context.Convert<MaterialContent, MaterialContent> (lppMaterial, typeof(LightPrePassMaterialProcessor).Name, processorParameters); }
private static Tuple<string, TempDirectoryHelper> BuildXnb(IServiceLocator services, string applicationName, string fileName, bool createModelNode, bool recreateModelAndMaterialFiles) { Debug.Assert(services != null); Debug.Assert(applicationName != null); Debug.Assert(applicationName.Length > 0); Debug.Assert(fileName != null); Debug.Assert(fileName.Length > 0); var tempDirectoryHelper = new TempDirectoryHelper(applicationName, "ModelDocument"); try { var contentBuilder = new GameContentBuilder(services) { IntermediateFolder = tempDirectoryHelper.TempDirectoryName + "\\obj", OutputFolder = tempDirectoryHelper.TempDirectoryName + "\\bin", }; string processorName; var processorParams = new OpaqueDataDictionary(); if (createModelNode) { processorName = "GameModelProcessor"; processorParams.Add("RecreateModelDescriptionFile", recreateModelAndMaterialFiles); processorParams.Add("RecreateMaterialDefinitionFiles", recreateModelAndMaterialFiles); } else { processorName = "ModelProcessor"; } string errorMessage; bool success = contentBuilder.Build(Path.GetFullPath(fileName), null, processorName, processorParams, out errorMessage); if (!success) throw new EditorException(Invariant($"Could not process 3d model: {fileName}.\n See output window for details.")); // Return output folder into which we built the XNB. var outputFolder = contentBuilder.OutputFolder; if (!Path.IsPathRooted(outputFolder)) outputFolder = Path.GetFullPath(Path.Combine(contentBuilder.ExecutableFolder, contentBuilder.OutputFolder)); return Tuple.Create(outputFolder, tempDirectoryHelper); } catch { tempDirectoryHelper.Dispose(); throw; } }
public override ExternalReference <TOutput> BuildAsset <TInput, TOutput>(ExternalReference <TInput> sourceAsset, string processorName, OpaqueDataDictionary processorParameters, string importerName, string assetName) { throw new NotImplementedException(); }
internal static bool AreParametersEqual(OpaqueDataDictionary parameters0, OpaqueDataDictionary parameters1) { // Same reference or both null? if (parameters0 == parameters1) return true; // Are both dictionaries are empty? if ((parameters0 == null || parameters0.Count == 0) && (parameters1 == null || parameters1.Count == 0)) return true; // Is one dictionary empty? if (parameters0 == null || parameters1 == null) return false; // Is number of parameters different? // (This assumes that default values are always set the same way, i.e. // either parameters with default values are set in both dictionaries // or omitted in both dictionaries!) if (parameters0.Count != parameters1.Count) return false; // Compare parameter by parameter. foreach (var pair in parameters0) { object value0 = pair.Value; object value1; if (!parameters1.TryGetValue(pair.Key, out value1)) return false; // Are values equal or both null? if (Equals(value0, value1)) continue; // Is one value null? if (value0 == null || value1 == null) return false; // Values are of different type: Compare string representation. if (ConvertToString(value0) != ConvertToString(value1)) return false; } return true; }
public ContentItem() { opaqueData = new OpaqueDataDictionary(); }
/// <summary> /// Gets an automatic asset name, such as "AssetName_0". /// </summary> /// <param name="sourceFileName">The source file name.</param> /// <param name="importerName">The name of the content importer. Can be <see langword="null"/>.</param> /// <param name="processorName">The name of the content processor. Can be <see langword="null"/>.</param> /// <param name="processorParameters">The processor parameters. Can be <see langword="null"/>.</param> /// <returns>The asset name.</returns> public string GetAssetName(string sourceFileName, string importerName, string processorName, OpaqueDataDictionary processorParameters) { Debug.Assert(Path.IsPathRooted(sourceFileName), "Absolute path expected."); // Get source file name, which is used for lookup in _pipelineBuildEvents. sourceFileName = PathHelper.Normalize(sourceFileName); string relativeSourceFileName = PathHelper.GetRelativePath(ProjectDirectory, sourceFileName); List <PipelineBuildEvent> pipelineBuildEvents; if (_pipelineBuildEvents.TryGetValue(sourceFileName, out pipelineBuildEvents)) { // This source file has already been build. // --> Compare pipeline build events. ResolveImporterAndProcessor(sourceFileName, ref importerName, ref processorName); var matchingEvent = FindMatchingEvent(pipelineBuildEvents, null, importerName, processorName, processorParameters); if (matchingEvent != null) { // Matching pipeline build event found. string existingName = matchingEvent.DestFile; existingName = PathHelper.GetRelativePath(OutputDirectory, existingName); existingName = existingName.Substring(0, existingName.Length - 4); // Remove ".xnb". return(existingName); } Logger.LogMessage(string.Format("Warning: Asset {0} built multiple times with different settings.", relativeSourceFileName)); } // No pipeline build event with matching settings found. // Get default asset name (= output file name relative to output folder without ".xnb"). string directoryName = Path.GetDirectoryName(relativeSourceFileName); string fileName = Path.GetFileNameWithoutExtension(relativeSourceFileName); string assetName = Path.Combine(directoryName, fileName); assetName = PathHelper.Normalize(assetName); return(AppendAssetNameSuffix(assetName)); }
public OpaqueDataDictionary ValidateProcessorParameters(string name, OpaqueDataDictionary processorParameters) { var result = new OpaqueDataDictionary(); var processorType = GetProcessorType(name); if (processorType == null || processorParameters == null) { return result; } foreach (var param in processorParameters) { var propInfo = processorType.GetProperty(param.Key, BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.Instance); if (propInfo == null || propInfo.GetSetMethod(false) == null) continue; // Make sure we can assign the value. if (!propInfo.PropertyType.IsInstanceOfType(param.Value)) { // Make sure we can convert the value. var typeConverter = TypeDescriptor.GetConverter(propInfo.PropertyType); if (!typeConverter.CanConvertFrom(param.Value.GetType())) continue; } result.Add(param.Key, param.Value); } return result; }
public PipelineBuildEvent BuildContent(string sourceFilepath, string outputFilepath = null, string importerName = null, string processorName = null, OpaqueDataDictionary processorParameters = null) { sourceFilepath = PathHelper.Normalize(sourceFilepath); ResolveOutputFilepath(sourceFilepath, ref outputFilepath); // Resolve the importer name. if (string.IsNullOrEmpty(importerName)) importerName = FindImporterByExtension(Path.GetExtension(sourceFilepath)); // Resolve the processor name. if (string.IsNullOrEmpty(processorName)) processorName = FindDefaultProcessor(importerName); // Record what we're building and how. var contentEvent = new PipelineBuildEvent { SourceFile = PathHelper.Normalize(sourceFilepath), DestFile = outputFilepath, Importer = importerName, Processor = processorName, Parameters = ValidateProcessorParameters(processorName, processorParameters), }; // Load the previous content event if it exists. string eventFilepath; var cachedEvent = LoadBuildEvent(contentEvent.DestFile, out eventFilepath); BuildContent(contentEvent, cachedEvent, eventFilepath); return contentEvent; }
internal static bool AreParametersEqual(OpaqueDataDictionary parameters0, OpaqueDataDictionary parameters1) { // Same reference or both null? if (parameters0 == parameters1) { return(true); } // Are both dictionaries are empty? if ((parameters0 == null || parameters0.Count == 0) && (parameters1 == null || parameters1.Count == 0)) { return(true); } // Is one dictionary empty? if (parameters0 == null || parameters1 == null) { return(false); } // Is number of parameters different? // (This assumes that default values are always set the same way, i.e. // either parameters with default values are set in both dictionaries // or omitted in both dictionaries!) if (parameters0.Count != parameters1.Count) { return(false); } // Compare parameter by parameter. foreach (var pair in parameters0) { object value0 = pair.Value; object value1; if (!parameters1.TryGetValue(pair.Key, out value1)) { return(false); } // Are values equal or both null? if (Equals(value0, value1)) { continue; } // Is one value null? if (value0 == null || value1 == null) { return(false); } // Values are of different type: Compare string representation. if (ConvertToString(value0) != ConvertToString(value1)) { return(false); } } return(true); }
private static void CreateDictionaryIfNecessary() { if (dictionary == null) { dictionary = new OpaqueDataDictionary(); #if XNA4 dictionary.Add("ColorKeyColor", Color.Transparent); #else dictionary.Add("ColorKeyColor", Color.TransparentBlack); #endif dictionary.Add("ColorKeyEnabled", false); dictionary.Add("GenerateMipmaps", true); dictionary.Add("ResizeToPowerOfTwo", false); dictionary.Add("TextureFormat", TextureProcessorOutputFormat.Color); } }
/// <summary> /// Determines whether the specified list contains a matching pipeline build event. /// </summary> /// <param name="pipelineBuildEvents">The list of pipeline build events.</param> /// <param name="destFile">Absolute path to the output file. Can be <see langword="null"/>.</param> /// <param name="importerName">The name of the content importer. Can be <see langword="null"/>.</param> /// <param name="processorName">The name of the content processor. Can be <see langword="null"/>.</param> /// <param name="processorParameters">The processor parameters. Can be <see langword="null"/>.</param> /// <returns> /// The matching pipeline build event, or <see langword="null"/>. /// </returns> private PipelineBuildEvent FindMatchingEvent(List <PipelineBuildEvent> pipelineBuildEvents, string destFile, string importerName, string processorName, OpaqueDataDictionary processorParameters) { foreach (var existingBuildEvent in pipelineBuildEvents) { if ((destFile == null || existingBuildEvent.DestFile.Equals(destFile)) && existingBuildEvent.Importer == importerName && existingBuildEvent.Processor == processorName) { var defaultValues = GetProcessorDefaultValues(processorName); if (PipelineBuildEvent.AreParametersEqual(existingBuildEvent.Parameters, processorParameters, defaultValues)) { return(existingBuildEvent); } } } return(null); }
public override TOutput Convert <TInput, TOutput>(TInput input, string processorName, OpaqueDataDictionary processorParameters) { throw new NotImplementedException(); }
internal static bool AreParametersEqual(OpaqueDataDictionary parameters0, OpaqueDataDictionary parameters1, OpaqueDataDictionary defaultValues) { Debug.Assert(defaultValues != null, "defaultValues must not be empty."); Debug.Assert(EmptyParameters != null && EmptyParameters.Count == 0); // Same reference or both null? if (parameters0 == parameters1) { return(true); } if (parameters0 == null) { parameters0 = EmptyParameters; } if (parameters1 == null) { parameters1 = EmptyParameters; } // Are both dictionaries empty? if (parameters0.Count == 0 && parameters1.Count == 0) { return(true); } // Compare the values with the second dictionary or // the default values. if (parameters0.Count < parameters1.Count) { var dummy = parameters0; parameters0 = parameters1; parameters1 = dummy; } // Compare parameters0 with parameters1 or defaultValues. foreach (var pair in parameters0) { object value0 = pair.Value; object value1; // Search for matching parameter. if (!parameters1.TryGetValue(pair.Key, out value1) && !defaultValues.TryGetValue(pair.Key, out value1)) { return(false); } if (!AreEqual(value0, value1)) { return(false); } } // Compare parameters which are only in parameters1 with defaultValues. foreach (var pair in parameters1) { if (parameters0.ContainsKey(pair.Key)) { continue; } object defaultValue; if (!defaultValues.TryGetValue(pair.Key, out defaultValue)) { return(false); } if (!AreEqual(pair.Value, defaultValue)) { return(false); } } return(true); }
internal static bool AreParametersEqual(OpaqueDataDictionary parameters0, OpaqueDataDictionary parameters1, OpaqueDataDictionary defaultValues) { Debug.Assert(defaultValues != null, "defaultValues must not be empty."); Debug.Assert(EmptyParameters != null && EmptyParameters.Count == 0); // Same reference or both null? if (parameters0 == parameters1) return true; if (parameters0 == null) parameters0 = EmptyParameters; if (parameters1 == null) parameters1 = EmptyParameters; // Are both dictionaries empty? if (parameters0.Count == 0 && parameters1.Count == 0) return true; // Compare the values with the second dictionary or // the default values. if (parameters0.Count < parameters1.Count) { var dummy = parameters0; parameters0 = parameters1; parameters1 = dummy; } // Compare parameters0 with parameters1 or defaultValues. foreach (var pair in parameters0) { object value0 = pair.Value; object value1; // Search for matching parameter. if (!parameters1.TryGetValue(pair.Key, out value1) && !defaultValues.TryGetValue(pair.Key, out value1)) return false; if (!AreEqual(value0, value1)) return false; } // Compare parameters which are only in parameters1 with defaultValues. foreach (var pair in parameters1) { if (parameters0.ContainsKey(pair.Key)) continue; object defaultValue; if (!defaultValues.TryGetValue(pair.Key, out defaultValue)) return false; if (!AreEqual(pair.Value, defaultValue)) return false; } return true; }
public void RegisterContent(string sourceFilepath, string outputFilepath = null, string importerName = null, string processorName = null, OpaqueDataDictionary processorParameters = null) { sourceFilepath = PathHelper.Normalize(sourceFilepath); ResolveOutputFilepath(sourceFilepath, ref outputFilepath); ResolveImporterAndProcessor(sourceFilepath, ref importerName, ref processorName); var contentEvent = new PipelineBuildEvent { SourceFile = sourceFilepath, DestFile = outputFilepath, Importer = importerName, Processor = processorName, Parameters = ValidateProcessorParameters(processorName, processorParameters), }; // Register pipeline build event. (Required to correctly resolve external dependencies.) TrackPipelineBuildEvent(contentEvent); }
//-------------------------------------------------------------- /// <summary> /// Builds the specified source file. /// </summary> /// <param name="sourceFile"> /// The absolute path of the source file. The file format must be a supported 3D model file /// format. /// </param> /// <param name="importerName">The name of the content importer.</param> /// <param name="processorName">The name of the content processor.</param> /// <param name="processorParameters">The processor parameters.</param> /// <param name="errorMessage">The error message in case of failure.</param> /// <returns> /// <see langword="true"/> if the asset was successfully processed. <see langword="false"/> /// if an error has occurred, in which case the output window should contain useful /// information. /// </returns> /// <exception cref="ArgumentNullException"> /// <paramref name="sourceFile"/> is <see langword="null"/>. /// </exception> /// <exception cref="ArgumentException"> /// <paramref name="sourceFile"/> is empty or is not an absolute (rooted) path. /// </exception> public bool Build(string sourceFile, string importerName, string processorName, OpaqueDataDictionary processorParameters, out string errorMessage) { if (sourceFile == null) throw new ArgumentNullException(nameof(sourceFile)); if (sourceFile.Length == 0) throw new ArgumentException("Source file path must not be empty.", nameof(sourceFile)); if (!Path.IsPathRooted(sourceFile)) throw new ArgumentException("Source file path must be an absolute (rooted) path.", nameof(sourceFile)); string executableFolder = ExecutableFolder; string outputFolder = OutputFolder; if (!Path.IsPathRooted(outputFolder)) outputFolder = Path.GetFullPath(Path.Combine(executableFolder, outputFolder)); string intermediateFolder = IntermediateFolder; if (!Path.IsPathRooted(intermediateFolder)) intermediateFolder = PathHelper.Normalize(Path.GetFullPath(Path.Combine(executableFolder, intermediateFolder))); // No assets should lie outside the working folder because then some XNB are built // into parent folders. string workingFolder = Path.GetPathRoot(sourceFile); Directory.SetCurrentDirectory(workingFolder); var manager = new PipelineManager(workingFolder, outputFolder, intermediateFolder) { Logger = _logger, RethrowExceptions = false, CompressContent = false, Profile = GraphicsProfile.HiDef, Platform = TargetPlatform.Windows }; // Add references to content pipeline assemblies. // All assemblies are expected to lie in the executable folder. Therefore, this project // references the content pipeline DLLs, so that they are automatically copied to the // executable folder. // TODO: Make a public property to allow user to set references. manager.AddAssembly(Path.GetFullPath(Path.Combine(ExecutableFolder, "DigitalRune.Animation.Content.Pipeline.dll"))); manager.AddAssembly(Path.GetFullPath(Path.Combine(ExecutableFolder, "DigitalRune.Game.UI.Content.Pipeline.dll"))); manager.AddAssembly(Path.GetFullPath(Path.Combine(ExecutableFolder, "DigitalRune.Geometry.Content.Pipeline.dll"))); manager.AddAssembly(Path.GetFullPath(Path.Combine(ExecutableFolder, "DigitalRune.Graphics.Content.Pipeline.dll"))); manager.AddAssembly(Path.GetFullPath(Path.Combine(ExecutableFolder, "DigitalRune.Mathematics.Content.Pipeline.dll"))); // Add this assembly because it also contains model processors. manager.AddAssembly(Path.GetFullPath(Path.Combine(ExecutableFolder, "DigitalRune.Editor.Game.dll"))); _logger.LogMessage("----- Begin MonoGame content pipeline -----"); // Remove any previous build content to force a full rebuild. manager.CleanContent(sourceFile); try { manager.BuildContent(sourceFile, null, importerName, processorName, processorParameters); errorMessage = null; return true; } catch (Exception exception) { _logger.LogMessage("Exception in MonoGame content pipeline:"); _logger.LogWarning(null, null, exception.Message); _logger.LogMessage(exception.StackTrace); if (exception.Message.StartsWith("Value cannot be null.", StringComparison.OrdinalIgnoreCase)) _logger.LogWarning(null, null, "This can happen if the FBX references a texture but the filename is null. Check the referenced texture file paths in a 3D modeling tool."); errorMessage = exception.Message; return false; } finally { _logger.LogMessage("----- End MonoGame content pipeline -----"); } }
protected override MaterialContent ConvertMaterial(MaterialContent material, ContentProcessorContext context) { EffectMaterialContent normalMappingMaterial = new EffectMaterialContent(); string effectDirectory = Path.Combine(directory, "../../Effects/"); normalMappingMaterial.Effect = new ExternalReference<EffectContent> (Path.Combine(effectDirectory, "NormalMapping.fx")); OpaqueDataDictionary processorParameters = new OpaqueDataDictionary(); processorParameters["ColorKeyColor"] = this.ColorKeyColor; processorParameters["ColorKeyEnabled"] = this.ColorKeyEnabled; processorParameters["TextureFormat"] = this.TextureFormat; processorParameters["GenerateMipmaps"] = this.GenerateMipmaps; processorParameters["ResizeTexturesToPowerOfTwo"] = this.ResizeTexturesToPowerOfTwo; // copy the textures in the original material to the new normal mapping // material. this way the diffuse texture is preserved. The // PreprocessSceneHierarchy function has already added the normal map // texture to the Textures collection, so that will be copied as well. foreach (KeyValuePair<String, ExternalReference<TextureContent>> texture in material.Textures) { normalMappingMaterial.Textures.Add(texture.Key, texture.Value); } // and convert the material using the NormalMappingMaterialProcessor, // who has something special in store for the normal map. return context.Convert<MaterialContent, MaterialContent> (normalMappingMaterial, typeof(NormalMappingMaterialProcessor).Name, processorParameters); }