162 lines
7.0 KiB
C#
Raw Permalink Normal View History

#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<MaterialContent, MaterialContent>
{
[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;
}
/// <summary>
/// Builds the texture and effect content for the material.
/// </summary>
/// <remarks>
/// If the MaterialContent is of type EffectMaterialContent, a build is requested for Effect.
/// Process requests builds for all textures in Textures.
/// </remarks>
/// <param name="input">The material content to build.</param>
/// <param name="context">Context for the specified processor.</param>
/// <returns>The built material.</returns>
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<AlphaTestMaterialContent>(input);
break;
case MaterialProcessorDefaultEffect.DualTextureEffect:
input = ConvertMaterial<DualTextureMaterialContent>(input);
break;
case MaterialProcessorDefaultEffect.EnvironmentMapEffect:
input = ConvertMaterial<EnvironmentMapMaterialContent>(input);
break;
case MaterialProcessorDefaultEffect.SkinnedEffect:
input = ConvertMaterial<SkinnedMaterialContent>(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<T>(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;
}
/// <summary>
/// Builds effect content.
/// </summary>
/// <remarks>
/// 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.
/// </remarks>
/// <param name="effect">An external reference to the effect content. </param>
/// <param name="context">Context for the specified processor.</param>
/// <returns>A compiled binary effect.</returns>
protected virtual ExternalReference<CompiledEffectContent> BuildEffect(ExternalReference<EffectContent> effect, ContentProcessorContext context)
{
return context.BuildAsset<EffectContent, CompiledEffectContent>(effect, typeof(EffectProcessor).Name);
}
protected virtual ExternalReference<TextureContent> BuildTexture(string textureName, ExternalReference<TextureContent> 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<TextureContent, TextureContent>(texture, typeof(TextureProcessor).Name, opaqueDataDictionary, null, null);
}
}
}