Merge pull request #3773 from Mailaender/palette-clean
Cleaned up the palette code
This commit is contained in:
@@ -19,29 +19,11 @@ namespace OpenRA.FileFormats
|
|||||||
public readonly byte L;
|
public readonly byte L;
|
||||||
public readonly Color RGB;
|
public readonly Color RGB;
|
||||||
|
|
||||||
public HSLColor(byte h, byte s, byte l)
|
|
||||||
{
|
|
||||||
H = h;
|
|
||||||
S = s;
|
|
||||||
L = l;
|
|
||||||
RGB = RGBFromHSL(H / 255f, S / 255f, L / 255f);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ToHSV(out float h, out float s, out float v)
|
|
||||||
{
|
|
||||||
var ll = 2*L / 255f;
|
|
||||||
var ss = S / 255f * ((ll <= 1) ? ll : 2 - ll);
|
|
||||||
|
|
||||||
h = H / 255f;
|
|
||||||
s = (2 * ss) / (ll + ss);
|
|
||||||
v = (ll + ss) / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static HSLColor FromHSV(float h, float s, float v)
|
public static HSLColor FromHSV(float h, float s, float v)
|
||||||
{
|
{
|
||||||
var ll = 0.5f*(2 - s)*v;
|
var ll = 0.5f * (2 - s) * v;
|
||||||
var ss = (ll >= 1 || v <= 0) ? 0 : 0.5f*s*v / (ll <= 0.5f ? ll : 1 - ll);
|
var ss = (ll >= 1 || v <= 0) ? 0 : 0.5f * s * v / (ll <= 0.5f ? ll : 1 - ll);
|
||||||
return new HSLColor((byte)(255*h), (byte)(255*ss), (byte)(255*ll));
|
return new HSLColor((byte)(255 * h), (byte)(255 * ss), (byte)(255 * ll));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static HSLColor FromRGB(int r, int g, int b)
|
public static HSLColor FromRGB(int r, int g, int b)
|
||||||
@@ -59,7 +41,7 @@ namespace OpenRA.FileFormats
|
|||||||
var q = (l < 0.5f) ? l * (1 + s) : l + s - (l * s);
|
var q = (l < 0.5f) ? l * (1 + s) : l + s - (l * s);
|
||||||
var p = 2 * l - q;
|
var p = 2 * l - q;
|
||||||
|
|
||||||
float[] trgb = { h + 1 / 3.0f, h, h - 1/3.0f };
|
float[] trgb = { h + 1 / 3.0f, h, h - 1 / 3.0f };
|
||||||
float[] rgb = { 0, 0, 0 };
|
float[] rgb = { 0, 0, 0 };
|
||||||
|
|
||||||
for (int k = 0; k < 3; k++)
|
for (int k = 0; k < 3; k++)
|
||||||
@@ -70,27 +52,45 @@ namespace OpenRA.FileFormats
|
|||||||
|
|
||||||
for (int k = 0; k < 3; k++)
|
for (int k = 0; k < 3; k++)
|
||||||
{
|
{
|
||||||
if (trgb[k] < 1 / 6.0f) { rgb[k] = (p + ((q - p) * 6 * trgb[k])); }
|
if (trgb[k] < 1 / 6.0f) { rgb[k] = p + ((q - p) * 6 * trgb[k]); }
|
||||||
else if (trgb[k] >= 1 / 6.0f && trgb[k] < 0.5) { rgb[k] = q; }
|
else if (trgb[k] >= 1 / 6.0f && trgb[k] < 0.5) { rgb[k] = q; }
|
||||||
else if (trgb[k] >= 0.5f && trgb[k] < 2.0f / 3) { rgb[k] = (p + ((q - p) * 6 * (2.0f / 3 - trgb[k]))); }
|
else if (trgb[k] >= 0.5f && trgb[k] < 2.0f / 3) { rgb[k] = p + ((q - p) * 6 * (2.0f / 3 - trgb[k])); }
|
||||||
else { rgb[k] = p; }
|
else { rgb[k] = p; }
|
||||||
}
|
}
|
||||||
|
|
||||||
return Color.FromArgb((int)(rgb[0] * 255), (int)(rgb[1] * 255), (int)(rgb[2] * 255));
|
return Color.FromArgb((int)(rgb[0] * 255), (int)(rgb[1] * 255), (int)(rgb[2] * 255));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool operator ==(HSLColor me, HSLColor other)
|
||||||
|
{
|
||||||
|
return me.H == other.H && me.S == other.S && me.L == other.L;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator !=(HSLColor me, HSLColor other) { return !(me == other); }
|
||||||
|
|
||||||
|
public HSLColor(byte h, byte s, byte l)
|
||||||
|
{
|
||||||
|
H = h;
|
||||||
|
S = s;
|
||||||
|
L = l;
|
||||||
|
RGB = RGBFromHSL(H / 255f, S / 255f, L / 255f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ToHSV(out float h, out float s, out float v)
|
||||||
|
{
|
||||||
|
var ll = 2 * L / 255f;
|
||||||
|
var ss = S / 255f * ((ll <= 1) ? ll : 2 - ll);
|
||||||
|
|
||||||
|
h = H / 255f;
|
||||||
|
s = (2 * ss) / (ll + ss);
|
||||||
|
v = (ll + ss) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return "{0},{1},{2}".F(H, S, L);
|
return "{0},{1},{2}".F(H, S, L);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool operator ==(HSLColor me, HSLColor other)
|
|
||||||
{
|
|
||||||
return (me.H == other.H && me.S == other.S && me.L == other.L);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator !=(HSLColor me, HSLColor other) { return !(me == other); }
|
|
||||||
|
|
||||||
public override int GetHashCode() { return H.GetHashCode() ^ S.GetHashCode() ^ L.GetHashCode(); }
|
public override int GetHashCode() { return H.GetHashCode() ^ S.GetHashCode() ^ L.GetHashCode(); }
|
||||||
|
|
||||||
public override bool Equals(object obj)
|
public override bool Equals(object obj)
|
||||||
|
|||||||
@@ -8,16 +8,22 @@
|
|||||||
*/
|
*/
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Drawing.Imaging;
|
using System.Drawing.Imaging;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System;
|
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
namespace OpenRA.FileFormats
|
namespace OpenRA.FileFormats
|
||||||
{
|
{
|
||||||
public class Palette
|
public class Palette
|
||||||
{
|
{
|
||||||
|
public static Palette Load(string filename, int[] remap)
|
||||||
|
{
|
||||||
|
using (var s = File.OpenRead(filename))
|
||||||
|
return new Palette(s, remap);
|
||||||
|
}
|
||||||
|
|
||||||
uint[] colors;
|
uint[] colors;
|
||||||
public Color GetColor(int index)
|
public Color GetColor(int index)
|
||||||
{
|
{
|
||||||
@@ -41,8 +47,8 @@ namespace OpenRA.FileFormats
|
|||||||
|
|
||||||
public void ApplyRemap(IPaletteRemap r)
|
public void ApplyRemap(IPaletteRemap r)
|
||||||
{
|
{
|
||||||
for(int i = 0; i < 256; i++)
|
for (int i = 0; i < 256; i++)
|
||||||
colors[i] = (uint)r.GetRemappedColor(Color.FromArgb((int)colors[i]),i).ToArgb();
|
colors[i] = (uint)r.GetRemappedColor(Color.FromArgb((int)colors[i]), i).ToArgb();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Palette(Stream s, int[] remapShadow)
|
public Palette(Stream s, int[] remapShadow)
|
||||||
@@ -60,7 +66,7 @@ namespace OpenRA.FileFormats
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
colors[0] = 0; //convert black background to transparency
|
colors[0] = 0; // convert black background to transparency
|
||||||
foreach (int i in remapShadow)
|
foreach (int i in remapShadow)
|
||||||
colors[i] = 140u << 24;
|
colors[i] = 140u << 24;
|
||||||
}
|
}
|
||||||
@@ -101,24 +107,19 @@ namespace OpenRA.FileFormats
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Bitmap AsBitmap()
|
public Bitmap AsBitmap()
|
||||||
{
|
|
||||||
var b = new Bitmap(256, 1, PixelFormat.Format32bppArgb);
|
|
||||||
var data = b.LockBits(new Rectangle(0, 0, b.Width, b.Height),
|
|
||||||
ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
|
|
||||||
unsafe
|
|
||||||
{
|
|
||||||
uint* c = (uint*)data.Scan0;
|
|
||||||
for (var x = 0; x < 256; x++)
|
|
||||||
*(c + x) = colors[x];
|
|
||||||
}
|
|
||||||
b.UnlockBits(data);
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Palette Load(string filename, int[] remap)
|
|
||||||
{
|
{
|
||||||
using(var s = File.OpenRead(filename))
|
var b = new Bitmap(256, 1, PixelFormat.Format32bppArgb);
|
||||||
return new Palette(s, remap);
|
var data = b.LockBits(new Rectangle(0, 0, b.Width, b.Height),
|
||||||
|
ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
uint* c = (uint*)data.Scan0;
|
||||||
|
for (var x = 0; x < 256; x++)
|
||||||
|
*(c + x) = colors[x];
|
||||||
|
}
|
||||||
|
|
||||||
|
b.UnlockBits(data);
|
||||||
|
return b;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,33 +15,33 @@ using System.Linq;
|
|||||||
|
|
||||||
namespace OpenRA.FileFormats
|
namespace OpenRA.FileFormats
|
||||||
{
|
{
|
||||||
|
|
||||||
public class PlayerColorRemap : IPaletteRemap
|
public class PlayerColorRemap : IPaletteRemap
|
||||||
{
|
{
|
||||||
Dictionary<int, Color> remapColors;
|
Dictionary<int, Color> remapColors;
|
||||||
|
|
||||||
public static int GetRemapIndex(int[] Ramp, int i)
|
public static int GetRemapIndex(int[] ramp, int i)
|
||||||
{
|
{
|
||||||
return Ramp[i];
|
return ramp[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
public PlayerColorRemap(int[] Ramp, HSLColor c, float rampFraction)
|
public PlayerColorRemap(int[] ramp, HSLColor c, float rampFraction)
|
||||||
{
|
{
|
||||||
// Increase luminosity if required to represent the full ramp
|
// Increase luminosity if required to represent the full ramp
|
||||||
var rampRange = (byte)((1 - rampFraction)*c.L);
|
var rampRange = (byte)((1 - rampFraction) * c.L);
|
||||||
var c1 = new HSLColor(c.H, c.S, (byte)Math.Max(rampRange, c.L)).RGB;
|
var c1 = new HSLColor(c.H, c.S, (byte)Math.Max(rampRange, c.L)).RGB;
|
||||||
var c2 = new HSLColor(c.H, c.S, (byte)Math.Max(0, c.L - rampRange)).RGB;
|
var c2 = new HSLColor(c.H, c.S, (byte)Math.Max(0, c.L - rampRange)).RGB;
|
||||||
var baseIndex = Ramp[0];
|
var baseIndex = ramp[0];
|
||||||
var RemapRamp = Ramp.Select(r => r - Ramp[0]).ToArray();
|
var remapRamp = ramp.Select(r => r - ramp[0]).ToArray();
|
||||||
|
|
||||||
if (Ramp[0] > Ramp[15]) // reversed remapping
|
// reversed remapping
|
||||||
{
|
if (ramp[0] > ramp[15])
|
||||||
baseIndex = Ramp[15];
|
{
|
||||||
|
baseIndex = ramp[15];
|
||||||
for (var i = 15; i > 0; i--)
|
for (var i = 15; i > 0; i--)
|
||||||
RemapRamp = Ramp.Select(r => r - Ramp[15]).ToArray();
|
remapRamp = ramp.Select(r => r - ramp[15]).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
remapColors = RemapRamp.Select((x, i) => Pair.New(baseIndex + i, Exts.ColorLerp(x / 16f, c1, c2)))
|
remapColors = remapRamp.Select((x, i) => Pair.New(baseIndex + i, Exts.ColorLerp(x / 16f, c1, c2)))
|
||||||
.ToDictionary(u => u.First, u => u.Second);
|
.ToDictionary(u => u.First, u => u.Second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user