Created
September 7, 2012 20:17
-
-
Save james4k/3669270 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.ComponentModel; | |
using Microsoft.Xna.Framework; | |
using Microsoft.Xna.Framework.Graphics; | |
using Microsoft.Xna.Framework.Graphics.PackedVector; | |
using Microsoft.Xna.Framework.Content.Pipeline; | |
using Microsoft.Xna.Framework.Content.Pipeline.Graphics; | |
using Microsoft.Xna.Framework.Content.Pipeline.Processors; | |
namespace Limpleaf.Phorm.Content.Pipeline | |
{ | |
enum SpriteSheetProcessorSpriteSize | |
{ | |
x32 = 32, | |
x64 = 64, | |
x128 = 128, | |
x256 = 256, | |
x512 = 512, | |
} | |
[ContentProcessor(DisplayName = "Sprite sheet - Phorm")] | |
class SpriteSheetProcessor : TextureProcessor | |
{ | |
[Browsable(false)] | |
public override bool ColorKeyEnabled { get { return false; } set { } } | |
[Browsable(false)] | |
public override Color ColorKeyColor { get; set; } | |
[DisplayName("Sprite Size")] | |
[Description("The size of each sprite in this sprite sheet.")] | |
[DefaultValue(SpriteSheetProcessorSpriteSize.x128)] | |
public SpriteSheetProcessorSpriteSize SpriteSize { get; set; } | |
public SpriteSheetProcessor() | |
{ | |
SpriteSize = SpriteSheetProcessorSpriteSize.x128; | |
} | |
// Summary: | |
// Processes a texture. | |
// | |
// Parameters: | |
// input: | |
// The texture content to process. | |
// | |
// context: | |
// Context for the specified processor. | |
public override TextureContent Process(TextureContent input, ContentProcessorContext context) | |
{ | |
foreach (var face in input.Faces) | |
for (int i = 0; i < face.Count; i += 1) | |
face[i] = ProcessBitmap(face[i]); | |
return base.Process(input, context); | |
} | |
BitmapContent ProcessBitmap(BitmapContent bitmap) | |
{ | |
byte[] data = bitmap.GetPixelData(); | |
// TODO: check the actual format | |
if (data.Length != bitmap.Width * bitmap.Height * 4) | |
{ | |
throw new InvalidContentException("Unexpected bitmap format", bitmap.Identity); | |
} | |
int newWidth, newHeight; | |
byte[] newData = CreateNewBitmap(bitmap, data, out newWidth, out newHeight); | |
var newBitmap = new PixelBitmapContent<Byte4>(newWidth, newHeight); | |
newBitmap.SetPixelData(newData); | |
return newBitmap; | |
} | |
byte[] CreateNewBitmap(BitmapContent bitmap, byte[] oldData, out int width, out int height) | |
{ | |
int spriteSize = (int)SpriteSize; | |
if (spriteSize == 0) | |
throw new Exception(String.Format("{0} is not a valid SpriteSize value.", SpriteSize)); | |
if (bitmap.Width % spriteSize != 0 || bitmap.Height % spriteSize != 0) | |
throw new InvalidContentException(String.Format("Bitmap does not break evenly into x{0} sprites", spriteSize), bitmap.Identity); | |
int xsprites = bitmap.Width / spriteSize; | |
int ysprites = bitmap.Height / spriteSize; | |
width = xsprites * spriteSize + xsprites * 2; | |
height = ysprites * spriteSize + ysprites * 2; | |
byte[] data = new byte[width * height * 4]; | |
for (int y = 0; y < bitmap.Height; y += 1) | |
{ | |
int yoffsetOld = y * 4 * bitmap.Width; | |
int yoffset = y * 4 * width; | |
for (int x = 0; x < bitmap.Width; x += 1) | |
{ | |
int oldOffset = x * 4 + yoffsetOld; | |
int offset = x * 4 + yoffset + (x / spriteSize + (x + spriteSize) / spriteSize) * 4 + | |
(y / spriteSize + (y + spriteSize) / spriteSize) * 4 * width; | |
CopyPixel(data, offset, oldData, oldOffset); | |
} | |
} | |
return data; | |
} | |
void CopyPixel(byte[] destBuf, int destOffset, byte[] srcBuf, int srcOffset) | |
{ | |
destBuf[destOffset] = srcBuf[srcOffset]; | |
destBuf[destOffset + 1] = srcBuf[srcOffset + 1]; | |
destBuf[destOffset + 2] = srcBuf[srcOffset + 2]; | |
destBuf[destOffset + 3] = srcBuf[srcOffset + 3]; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment