108 lines
2.9 KiB
C#
108 lines
2.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using OpenRa.FileFormats;
|
|
using System.Drawing;
|
|
using BluntDirectX.Direct3D;
|
|
|
|
namespace OpenRa.Game
|
|
{
|
|
static class Util
|
|
{
|
|
public static float Constrain(float x, Range<float> range)
|
|
{
|
|
return x < range.Start ? range.Start : x > range.End ? range.End : x;
|
|
}
|
|
|
|
static PointF EncodeVertexAttributes(TextureChannel channel, int paletteLine)
|
|
{
|
|
Converter<TextureChannel, float> channelEncoder = delegate(TextureChannel c)
|
|
{
|
|
switch (c)
|
|
{
|
|
case TextureChannel.Red: return 0.75f;
|
|
case TextureChannel.Green: return 0.25f;
|
|
case TextureChannel.Blue: return -0.25f;
|
|
case TextureChannel.Alpha: return -0.75f;
|
|
default:
|
|
throw new ArgumentException();
|
|
}
|
|
};
|
|
|
|
return new PointF(paletteLine / 16.0f, channelEncoder(channel));
|
|
}
|
|
|
|
public static Vertex MakeVertex(PointF o, PointF uv, Sprite r, int palette)
|
|
{
|
|
PointF farCorner = new PointF(o.X + r.bounds.Width, o.Y + r.bounds.Height);
|
|
|
|
return new Vertex(
|
|
Lerp( o, farCorner, uv ),
|
|
r.MapTextureCoords(uv),
|
|
EncodeVertexAttributes(r.channel, palette));
|
|
}
|
|
|
|
static float Lerp(float a, float b, float t)
|
|
{
|
|
return (1 - t) * a + t * b;
|
|
}
|
|
|
|
static PointF Lerp(PointF a, PointF b, PointF t)
|
|
{
|
|
return new PointF(
|
|
Lerp(a.X, b.X, t.X),
|
|
Lerp(a.Y, b.Y, t.Y));
|
|
}
|
|
|
|
static PointF[] uv =
|
|
{
|
|
new PointF( 0,0 ),
|
|
new PointF( 1,0 ),
|
|
new PointF( 0,1 ),
|
|
new PointF( 1,1 ),
|
|
};
|
|
|
|
public static void CreateQuad(List<Vertex> vertices, List<ushort> indices, PointF o, Sprite r, int palette)
|
|
{
|
|
ushort offset = (ushort)vertices.Count;
|
|
|
|
foreach( PointF p in uv )
|
|
vertices.Add(Util.MakeVertex(o, p, r, palette));
|
|
|
|
indices.Add(offset);
|
|
indices.Add((ushort)(offset + 1));
|
|
indices.Add((ushort)(offset + 2));
|
|
|
|
indices.Add((ushort)(offset + 1));
|
|
indices.Add((ushort)(offset + 3));
|
|
indices.Add((ushort)(offset + 2));
|
|
}
|
|
|
|
public static void CopyIntoChannel(Sprite dest, byte[] src)
|
|
{
|
|
for (int i = 0; i < dest.bounds.Width; i++)
|
|
for (int j = 0; j < dest.bounds.Height; j++)
|
|
{
|
|
Point p = new Point(dest.bounds.Left + i, dest.bounds.Top + j);
|
|
byte b = src[i + dest.bounds.Width * j];
|
|
Color original = dest.sheet.bitmap.GetPixel(p.X, p.Y);
|
|
dest.sheet.bitmap.SetPixel(p.X, p.Y, ReplaceChannel(original, dest.channel, b));
|
|
}
|
|
}
|
|
|
|
static Color ReplaceChannel(Color o, TextureChannel channel, byte p)
|
|
{
|
|
switch (channel)
|
|
{
|
|
case TextureChannel.Red: return Color.FromArgb(o.A, p, o.G, o.B);
|
|
case TextureChannel.Green: return Color.FromArgb(o.A, o.R, p, o.B);
|
|
case TextureChannel.Blue: return Color.FromArgb(o.A, o.R, o.G, p);
|
|
case TextureChannel.Alpha: return Color.FromArgb(p, o.R, o.G, o.B);
|
|
|
|
default:
|
|
throw new ArgumentException();
|
|
}
|
|
}
|
|
}
|
|
}
|