Skip to content

Commit

Permalink
Merge pull request #1220 from SickheadGames/FontProcessor
Browse files Browse the repository at this point in the history
First working .xnb texture writtten.
  • Loading branch information
KonajuGames committed Jan 24, 2013
2 parents 58a6ff8 + 422b047 commit 56a442f
Show file tree
Hide file tree
Showing 6 changed files with 203 additions and 186 deletions.
100 changes: 59 additions & 41 deletions MonoGame.Framework.Content.Pipeline/Graphics/GraphicsUtil.cs
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -7,76 +7,94 @@
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Graphics;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;


namespace Microsoft.Xna.Framework.Content.Pipeline.Graphics namespace Microsoft.Xna.Framework.Content.Pipeline.Graphics
{ {

public static class GraphicsUtil
public static class ByteColorConverter
{ {
/*public static void GetPixel<T>(this byte[] data, int startIndex, SurfaceFormat format, out T result) where T : struct public static byte[] ConvertBitmap(Bitmap bmp)
{ {
result = new Color(); var bitmapData = bmp.LockBits(new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height),
}*/ ImageLockMode.ReadOnly,
bmp.PixelFormat);


public static void GetPixel(this byte[] data, int startIndex, SurfaceFormat format, out Color result) var length = bitmapData.Stride * bitmapData.Height;
{ var output = new byte[length];
result = new Color();
// Copy bitmap to byte[]
Marshal.Copy(bitmapData.Scan0, output, 0, length);
bmp.UnlockBits(bitmapData);

// NOTE: According to http://msdn.microsoft.com/en-us/library/dd183449%28VS.85%29.aspx
// and http://stackoverflow.com/questions/8104461/pixelformat-format32bppargb-seems-to-have-wrong-byte-order
// Image data from any GDI based function are stored in memory as BGRA/BGR, even if the format says RBGA.

switch (bitmapData.PixelFormat)
{
case PixelFormat.Format32bppArgb:
BGRAtoRGBA(output);
break;

case PixelFormat.Format32bppRgb:
BGRtoRGBA(output);
break;

default:
throw new NotSupportedException("Unsupported pixel format.");
}
return output;
} }


public static void SetPixelData<T>(this byte[] data, PixelBitmapContent<T> bmpContent, int startIndex, SurfaceFormat format) where T : struct, IEquatable<T> public static void BGRAtoRGBA(byte[] data)
{ {
for (var x = 0; x < data.Length; x += 4)
{
data[x] ^= data[x + 2];
data[x + 2] ^= data[x];
data[x] ^= data[x + 2];
}
} }


public static void SetPixelData(this byte[] data, PixelBitmapContent<Color> bmpContent, SurfaceFormat format) public static void BGRtoRGBA(byte[] data)
{ {
var formatSize = format.Size(); var output = new byte[(int)(data.LongLength * 4.0f / 3.0f)];

var counter = 0;
for (int y = 0; y < bmpContent.Height; y++) for (var x = 0; x < data.Length;)
{ {
for (int x = 0; x < bmpContent.Width; x++) output[counter++] = data[x + 2];
{ output[counter++] = data[x + 1];
switch(format) output[counter++] = data[x];
{ output[counter++] = (byte)255;
case SurfaceFormat.Vector4:

var startIdx = (y * formatSize) + (x * formatSize);
var vec4 = new Vector4( BitConverter.ToSingle(data, startIdx),
BitConverter.ToSingle(data, startIdx + 4),
BitConverter.ToSingle(data, startIdx + 8),
BitConverter.ToSingle(data, startIdx + 12) );


bmpContent._pixelData[y][x] = new Color(vec4); x += 3;
break;

default:
break;
}
}
} }
} }
}


public static class GraphicsUtil
{


public static void PremultiplyAlpha(TextureContent content) public static void PremultiplyAlpha(TextureContent content)
{ {
var colorTex = content.Faces[0][0] as PixelBitmapContent<Color>; var colorTex = content.Faces[0][0] as PixelBitmapContent<Color>;
if (colorTex != null) if (colorTex != null)
{ {
for (int x = 0; x < colorTex.Height; x++) for (var y = 0; y < colorTex.Height; y++)
{ {
var row = colorTex.GetRow(x); for (var x = 0; x < colorTex.Width; x++)
for (int y = 0; y < row.Length; y++)
{ {
if (row[y].A < 0xff) colorTex._pixelData[y][x] = Color.FromNonPremultiplied(colorTex._pixelData[y][x].R,
row[y] = Color.FromNonPremultiplied(row[y].R, row[y].G, row[y].B, row[y].A); colorTex._pixelData[y][x].G,
colorTex._pixelData[y][x].B,
colorTex._pixelData[y][x].A);
} }

} }
} }
else else
{ {
var vec4Tex = content.Faces[0][0] as PixelBitmapContent<Vector4>; /*var vec4Tex = content.Faces[0][0] as PixelBitmapContent<Vector4>;
if (vec4Tex == null) if (vec4Tex == null)
throw new NotSupportedException(); throw new NotSupportedException();
Expand All @@ -92,7 +110,7 @@ public static void PremultiplyAlpha(TextureContent content)
row[y].Z *= row[y].W; row[y].Z *= row[y].W;
} }
} }
} }*/
} }
} }
} }
Expand Down
131 changes: 54 additions & 77 deletions MonoGame.Framework.Content.Pipeline/Graphics/PixelBitmapContent.cs
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -4,141 +4,118 @@


using System; using System;
using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Graphics;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;


namespace Microsoft.Xna.Framework.Content.Pipeline.Graphics namespace Microsoft.Xna.Framework.Content.Pipeline.Graphics
{ {
public class PixelBitmapContent<T> : BitmapContent where T : struct, IEquatable<T> public class PixelBitmapContent<T> : BitmapContent where T : struct, IEquatable<T>
{ {
internal T[][] _pixelData; internal T[][] _pixelData;
protected SurfaceFormat _format = SurfaceFormat.Color;


protected PixelBitmapContent() public PixelBitmapContent(int width, int height)
{ {
} Height = height;
Width = width;


public PixelBitmapContent(int width, int height) : base(width, height)
{
_pixelData = new T[height][]; _pixelData = new T[height][];


for (int y = 0; y < height; y++) for (int y = 0; y < height; y++)
_pixelData[y] = new T[width]; _pixelData[y] = new T[width];
} }


public T GetPixel(int x, int y)
{
checkPixelRange(y, x);

return _pixelData[y][x];
}

public override byte[] GetPixelData() public override byte[] GetPixelData()
{ {
SurfaceFormat format; if (_format != SurfaceFormat.Color)
if (!TryGetFormat(out format)) throw new NotImplementedException();
throw new Exception(string.Format("Tried to get pixel Data for PixedBitmapContent<{0}> with an invalid surfaceformat",
typeof(T)));


if (typeof(T) != typeof(Color)) var formatSize = _format.Size();
throw new NotImplementedException("GetPixelData is not supported for Non-Color formats."); var dataSize = Width * Height * formatSize;
var outputData = new byte[dataSize];


var pixelSize = format.Size(); for (var x = 0; x < Height; x++)
var outputData = new byte[Width * Height * pixelSize];

for (int i = 0; i < Width; i++)
{ {
var row = GetRow(i); var dataHandle = GCHandle.Alloc(_pixelData[x], GCHandleType.Pinned);
for (int j = 0; j < row.Length; j++) var dataPtr = (IntPtr)(dataHandle.AddrOfPinnedObject().ToInt64());
{
var col = (row[j] as Color?).Value;


outputData[(i * row.Length) + j] = col.R; Marshal.Copy(dataPtr, outputData, (formatSize * x * Height), (Width * formatSize));
outputData[(i * row.Length) + j + 1] = col.G;
outputData[(i * row.Length) + j + 2] = col.B; dataHandle.Free();
outputData[(i * row.Length) + j + 3] = col.A;
}
} }


return outputData; return outputData;
} }


public T[] GetRow(int y) public override void SetPixelData(byte[] sourceData)
{ {
if ((y < 0) || (y >= Height)) var size = _format.Size();
throw new ArgumentOutOfRangeException("y");


return _pixelData[y]; for(var x = 0; x < Height; x++)
} {
var dataHandle = GCHandle.Alloc(_pixelData[x], GCHandleType.Pinned);
var dataPtr = (IntPtr)dataHandle.AddrOfPinnedObject().ToInt64();


protected override bool TryCopyFrom(BitmapContent sourceBitmap, Rectangle sourceRegion, Rectangle destRegion) Marshal.Copy(sourceData, (x * Height * size), dataPtr, Width * size);
{
throw new NotImplementedException();
}


protected override bool TryCopyTo(BitmapContent destBitmap, Rectangle sourceRegion, Rectangle destRegion) dataHandle.Free();
{ }
throw new NotImplementedException();
} }


public override bool TryGetFormat(out SurfaceFormat format) public T[] GetRow(int y)
{ {
throw new NotImplementedException(); if (y >= Height)
} throw new ArgumentOutOfRangeException("y");


public override string ToString() return _pixelData[y];
{
return base.ToString();
} }


public override void SetPixelData(byte[] sourceData) /// <summary>
/// Gets the corresponding GPU texture format for the specified bitmap type.
/// </summary>
/// <param name="format">Format being retrieved.</param>
/// <returns>The GPU texture format of the bitmap type.</returns>
public override bool TryGetFormat(out SurfaceFormat format)
{ {
if (typeof(T) != typeof(Color)) format = SurfaceFormat.Color;
throw new NotImplementedException("SetPixelData is not supported for Non-Color formats."); return true;

SurfaceFormat format;
if (!TryGetFormat(out format))
throw new Exception(string.Format("Tried to get pixel Data for PixedBitmapContent<{0}> with an invalid surfaceformat",
typeof(T)));

sourceData.SetPixelData(this, 0, format);
/*var formatSize = format.Size();
for (int y = 0; y < Height; y++)
{
for (int x = 0; x < Width; x++)
{
sourceData.GetPixel((y * formatSize) + (x * formatSize), format, out _pixelData[y][x]);
}
}*/
} }


private void SetPixelData() public T GetPixel(int x, int y)
{ {

return _pixelData[y][x];
} }


public void SetPixel(int x, int y, T value) public void SetPixel(int x, int y, T value)
{ {
checkPixelRange(y, x);

_pixelData[y][x] = value; _pixelData[y][x] = value;
} }


public void ReplaceColor(T originalColor, T newColor) public void ReplaceColor(T originalColor, T newColor)
{ {
for (int y = 0; y < Height; y++) for (var y = 0; y < Height; y++ )
{ {
for (int x = 0; x < Width; x++) for (var x = 0; x < Width; x++)
{ {
if (_pixelData[y][x].Equals(originalColor)) if (_pixelData[y][x].Equals(originalColor))
{
_pixelData[y][x] = newColor; _pixelData[y][x] = newColor;
}
} }
} }
} }


private void checkPixelRange(int y, int x) protected override bool TryCopyFrom(BitmapContent sourceBitmap, Rectangle sourceRegion, Rectangle destRegion)
{
throw new NotImplementedException();
}

protected override bool TryCopyTo(BitmapContent destBitmap, Rectangle sourceRegion, Rectangle destRegion)
{ {
if (x * y == 0 || x >= Height || y >= Width) throw new NotImplementedException();
throw new ArgumentOutOfRangeException("x or y"); }

public override string ToString()
{
return base.ToString();
} }
} }
} }
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@
<Compile Include="Serialization\Compiler\ContentTypeWriterGeneric.cs" /> <Compile Include="Serialization\Compiler\ContentTypeWriterGeneric.cs" />
<Compile Include="Serialization\Compiler\ContentWriter.cs" /> <Compile Include="Serialization\Compiler\ContentWriter.cs" />
<Compile Include="Serialization\Compiler\SongContentWriter.cs" /> <Compile Include="Serialization\Compiler\SongContentWriter.cs" />
<Compile Include="Serialization\Compiler\TextureContentWriter.cs" /> <Compile Include="Serialization\Compiler\Texture2DContentWriter.cs" />
<Compile Include="TargetPlatform.cs" /> <Compile Include="TargetPlatform.cs" />
<Compile Include="TextureImporter.cs" /> <Compile Include="TextureImporter.cs" />
<Compile Include="VideoContent.cs" /> <Compile Include="VideoContent.cs" />
Expand Down
Loading

0 comments on commit 56a442f

Please sign in to comment.