#region Using Statements using System; using System.Collections.Generic; using System.Linq; using System.Text; using ANX.Framework.Content.Pipeline.Graphics; using System.ComponentModel; #endregion // This file is part of the ANX.Framework created by the // "ANX.Framework developer group" and released under the Ms-PL license. // For details see: http://anxframework.codeplex.com/license namespace ANX.Framework.Content.Pipeline.Processors { [ContentProcessor] public class MaterialProcessor : ContentProcessor { [DefaultValue(typeof(Color), "255; 0; 255; 255")] public virtual Color ColorKeyColor { get; set; } [DefaultValue(true)] public virtual bool ColorKeyEnabled { get; set; } [DefaultValue(MaterialProcessorDefaultEffect.BasicEffect)] public virtual MaterialProcessorDefaultEffect DefaultEffect { get; set; } [DefaultValue(true)] public virtual bool GenerateMipmaps { get; set; } [DefaultValue(true)] public virtual bool PremultiplyTextureAlpha { get; set; } [DefaultValue(false)] public virtual bool ResizeTexturesToPowerOfTwo { get; set; } [DefaultValue(TextureProcessorOutputFormat.DxtCompressed)] public virtual TextureProcessorOutputFormat TextureFormat { get; set; } public MaterialProcessor() { ColorKeyColor = Color.FromNonPremultiplied(255, 0, 255, 255); ColorKeyEnabled = true; DefaultEffect = MaterialProcessorDefaultEffect.BasicEffect; GenerateMipmaps = true; PremultiplyTextureAlpha = true; ResizeTexturesToPowerOfTwo = false; TextureFormat = TextureProcessorOutputFormat.DxtCompressed; } /// /// Builds the texture and effect content for the material. /// /// /// If the MaterialContent is of type EffectMaterialContent, a build is requested for Effect. /// Process requests builds for all textures in Textures. /// /// The material content to build. /// Context for the specified processor. /// The built material. public override MaterialContent Process(MaterialContent input, ContentProcessorContext context) { if (input == null) throw new ArgumentNullException("input"); if (context == null) throw new ArgumentNullException("context"); //If no specific material seems to be specified, try to convert it to the default effect. if (input is BasicMaterialContent) { switch (this.DefaultEffect) { case MaterialProcessorDefaultEffect.AlphaTestEffect: input = ConvertMaterial(input); break; case MaterialProcessorDefaultEffect.DualTextureEffect: input = ConvertMaterial(input); break; case MaterialProcessorDefaultEffect.EnvironmentMapEffect: input = ConvertMaterial(input); break; case MaterialProcessorDefaultEffect.SkinnedEffect: input = ConvertMaterial(input); break; } } foreach (var pair in input.Textures) { this.BuildTexture(pair.Key, pair.Value, context); } if (input is EffectMaterialContent) { var effectMaterialContent = (EffectMaterialContent)input; if (effectMaterialContent.Effect == null) throw new InvalidContentException(string.Format("EffectMaterialContent doesn't contain an effect."), effectMaterialContent.Identity); effectMaterialContent.CompiledEffect = this.BuildEffect(effectMaterialContent.Effect, context); } return input; } protected virtual T ConvertMaterial(MaterialContent material) where T : MaterialContent, new() { if (material == null) throw new ArgumentNullException("material"); T instance = new T() { Name = material.Name, Identity = material.Identity, }; foreach (var pair in material.OpaqueData) { instance.OpaqueData.Add(pair.Key, pair.Value); } foreach (var pair in material.Textures) { instance.Textures.Add(pair.Key, pair.Value); } return instance; } /// /// Builds effect content. /// /// /// If the input to process is of type EffectMaterialContent, this function will be called to request that the EffectContent be built. /// The EffectProcessor is used to process the EffectContent. /// Subclasses of MaterialProcessor can override this function to modify the parameters used to build EffectContent. /// For example, a different version of this function could request a different processor for the EffectContent. /// /// An external reference to the effect content. /// Context for the specified processor. /// A compiled binary effect. protected virtual ExternalReference BuildEffect(ExternalReference effect, ContentProcessorContext context) { return context.BuildAsset(effect, typeof(EffectProcessor).Name); } protected virtual ExternalReference BuildTexture(string textureName, ExternalReference texture, ContentProcessorContext context) { OpaqueDataDictionary opaqueDataDictionary = new OpaqueDataDictionary(); opaqueDataDictionary.Add("ColorKeyColor", this.ColorKeyColor); opaqueDataDictionary.Add("ColorKeyEnabled", this.ColorKeyEnabled); opaqueDataDictionary.Add("TextureFormat", this.TextureFormat); opaqueDataDictionary.Add("GenerateMipmaps", this.GenerateMipmaps); opaqueDataDictionary.Add("PremultiplyAlpha", this.PremultiplyTextureAlpha); opaqueDataDictionary.Add("ResizeToPowerOfTwo", this.ResizeTexturesToPowerOfTwo); return context.BuildAsset(texture, typeof(TextureProcessor).Name, opaqueDataDictionary, null, null); } } }