Konstantin Koch 8287c54432 Included the Visual Studio extension and made the necessary changes to make it run.
Replaced the old VS templates with ones that offer more flexiblity.
Started replacing the Content Project for the samples with our custom project type.
Inlcuded a basic not yet working AssimpImporter.
2015-04-08 14:50:03 +02:00

165 lines
6.1 KiB
C#

#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 TextureProcessor : ContentProcessor<TextureContent, TextureContent>
{
[DefaultValue(typeof(Color), "255; 0; 255; 255")]
public virtual Color ColorKeyColor { get; set; }
[DefaultValue(true)]
public virtual bool ColorKeyEnabled { get; set; }
[DefaultValue(false)]
public virtual bool GenerateMipmaps { get; set; }
[DefaultValue(true)]
public virtual bool PremultiplyAlpha { get; set; }
[DefaultValue(false)]
public virtual bool ResizeToPowerOfTwo { get; set; }
[DefaultValue(TextureProcessorOutputFormat.Color)]
public virtual TextureProcessorOutputFormat TextureFormat { get; set; }
public TextureProcessor()
{
ColorKeyColor = Color.FromNonPremultiplied(255, 0, 255, 255);
ColorKeyEnabled = true;
GenerateMipmaps = false;
PremultiplyAlpha = true;
ResizeToPowerOfTwo = false;
TextureFormat = TextureProcessorOutputFormat.Color;
}
public override TextureContent Process(TextureContent input, ContentProcessorContext context)
{
if (ColorKeyEnabled)
{
foreach (MipmapChain face in input.Faces)
{
foreach (BitmapContent bitmap in face)
{
PixelBitmapContent<Color> pixelBitmapContent = bitmap as PixelBitmapContent<Color>;
if (pixelBitmapContent != null)
{
pixelBitmapContent.ReplaceColor(ColorKeyColor, Color.Transparent);
}
}
}
}
if (PremultiplyAlpha)
{
foreach (MipmapChain face in input.Faces)
{
foreach (BitmapContent bitmap in face)
{
PixelBitmapContent<Color> pixelBitmapContent = bitmap as PixelBitmapContent<Color>;
if (pixelBitmapContent != null)
{
for (int x = 0, width = bitmap.Width; x < width; x++)
for (int y = 0, height = bitmap.Height; y < height; y++)
{
Color color = pixelBitmapContent.GetPixel(x, y);
if (color.A < 255)
{
//premultiplies the colors.
pixelBitmapContent.SetPixel(x, y, Color.FromNonPremultiplied((int)color.R, (int)color.G, (int)color.B, (int)color.A));
}
}
}
}
}
}
if (ResizeToPowerOfTwo)
{
foreach (MipmapChain face in input.Faces)
{
for (int i = 0; i < face.Count; i++)
{
BitmapContent bitmapContent = face[i];
int width = RoundUpToPowerOfTwo(bitmapContent.Width);
int height = RoundUpToPowerOfTwo(bitmapContent.Height);
if (width != bitmapContent.Width || height != bitmapContent.Height)
{
face[i] = BitmapContent.Convert(bitmapContent, bitmapContent.GetType(), width, height);
}
}
}
}
if (GenerateMipmaps)
{
input.GenerateMipmaps(false);
}
switch (TextureFormat)
{
case TextureProcessorOutputFormat.Color:
input.ConvertBitmapType(typeof(PixelBitmapContent<Color>));
break;
case TextureProcessorOutputFormat.DxtCompressed:
if (this.HasFractionalAlpha(input))
{
input.ConvertBitmapType(typeof(Dxt5BitmapContent));
}
else
{
input.ConvertBitmapType(typeof(Dxt1BitmapContent));
}
break;
}
//TODO: test
return input;
}
/// <summary>
/// Tests if the given <see cref="TextureContent"/> has alpha values that are neither 0 nor 255.
/// </summary>
/// <param name="content"></param>
/// <returns></returns>
private bool HasFractionalAlpha(TextureContent content)
{
foreach (var face in content.Faces)
{
foreach (var bitmap in face)
{
PixelBitmapContent<Color> pixelBitmapContent = BitmapContent.Convert<PixelBitmapContent<Color>>(bitmap);
for (int x = 0; x < pixelBitmapContent.Width; x++)
for (int y = 0; y < pixelBitmapContent.Height; y++)
{
var alpha = pixelBitmapContent.GetPixel(x, y).A;
if (alpha > 0 && alpha < 255)
return true;
}
}
}
return false;
}
private static int RoundUpToPowerOfTwo(int value)
{
return (int) Math.Pow(2, Math.Ceiling(Math.Log(value, 2)));
}
}
}