Merge pull request #5406 from RoosterDragon/palette-efficiency
Changed HardwarePalette.ApplyModifiers to be more efficient.
This commit is contained in:
@@ -153,11 +153,11 @@ namespace OpenRA.Editor
|
||||
tileset = Program.Rules.TileSets[map.Tileset];
|
||||
tilesetRenderer = new TileSetRenderer(tileset, modData.Manifest.TileSize);
|
||||
var shadowIndex = new int[] { 3, 4 };
|
||||
var palette = new Palette(GlobalFileSystem.Open(tileset.Palette), shadowIndex);
|
||||
var palette = new ImmutablePalette(GlobalFileSystem.Open(tileset.Palette), shadowIndex);
|
||||
|
||||
// required for desert terrain in RA
|
||||
var playerPalette = tileset.PlayerPalette ?? tileset.Palette;
|
||||
var shadowedPalette = new Palette(GlobalFileSystem.Open(playerPalette), shadowIndex);
|
||||
var shadowedPalette = new ImmutablePalette(GlobalFileSystem.Open(playerPalette), shadowIndex);
|
||||
|
||||
surface1.Bind(map, tileset, tilesetRenderer, palette, shadowedPalette);
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace OpenRA.Editor
|
||||
{
|
||||
static class RenderUtils
|
||||
{
|
||||
static Bitmap RenderShp(ISpriteSource shp, Palette p)
|
||||
static Bitmap RenderShp(ISpriteSource shp, IPalette p)
|
||||
{
|
||||
var frame = shp.Frames.First();
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace OpenRA.Editor
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
public static ActorTemplate RenderActor(ActorInfo info, TileSet tileset, Palette p)
|
||||
public static ActorTemplate RenderActor(ActorInfo info, TileSet tileset, IPalette p)
|
||||
{
|
||||
var image = RenderSprites.GetImage(info);
|
||||
|
||||
@@ -76,7 +76,7 @@ namespace OpenRA.Editor
|
||||
}
|
||||
}
|
||||
|
||||
public static ResourceTemplate RenderResourceType(ResourceTypeInfo info, string[] exts, Palette p)
|
||||
public static ResourceTemplate RenderResourceType(ResourceTypeInfo info, string[] exts, IPalette p)
|
||||
{
|
||||
var image = info.EditorSprite;
|
||||
using (var s = GlobalFileSystem.OpenWithExts(image, exts))
|
||||
|
||||
@@ -45,8 +45,8 @@ namespace OpenRA.Editor
|
||||
public Map Map { get; private set; }
|
||||
public TileSet TileSet { get; private set; }
|
||||
public TileSetRenderer TileSetRenderer { get; private set; }
|
||||
public Palette Palette { get; private set; }
|
||||
public Palette PlayerPalette { get; private set; }
|
||||
public IPalette Palette { get; private set; }
|
||||
public IPalette PlayerPalette { get; private set; }
|
||||
public int2 Offset;
|
||||
|
||||
public int2 GetOffset() { return Offset; }
|
||||
@@ -81,7 +81,7 @@ namespace OpenRA.Editor
|
||||
|
||||
public Keys GetModifiers() { return ModifierKeys; }
|
||||
|
||||
public void Bind(Map m, TileSet ts, TileSetRenderer tsr, Palette p, Palette pp)
|
||||
public void Bind(Map m, TileSet ts, TileSetRenderer tsr, IPalette p, IPalette pp)
|
||||
{
|
||||
Map = m;
|
||||
TileSet = ts;
|
||||
@@ -381,7 +381,7 @@ namespace OpenRA.Editor
|
||||
var pr = Map.Players[name];
|
||||
var pcpi = Program.Rules.Actors["player"].Traits.Get<PlayerColorPaletteInfo>();
|
||||
var remap = new PlayerColorRemap(pcpi.RemapIndex, pr.Color, pcpi.Ramp);
|
||||
return new Palette(PlayerPalette, remap).AsSystemPalette();
|
||||
return new ImmutablePalette(PlayerPalette, remap).AsSystemPalette();
|
||||
}
|
||||
|
||||
Cache<string, ColorPalette> playerPalettes;
|
||||
|
||||
@@ -82,7 +82,7 @@ namespace OpenRA.Editor
|
||||
templates.Add(t.Key, LoadTemplate(t.Value.Image, tileset.Extensions, sourceCache, t.Value.Frames));
|
||||
}
|
||||
|
||||
public Bitmap RenderTemplate(ushort id, Palette p)
|
||||
public Bitmap RenderTemplate(ushort id, IPalette p)
|
||||
{
|
||||
var template = TileSet.Templates[id];
|
||||
var templateData = templates[id];
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace OpenRA.Graphics
|
||||
|
||||
palette = new HardwarePalette();
|
||||
foreach (var p in nodesDict["Palettes"].Nodes)
|
||||
palette.AddPalette(p.Key, new Palette(GlobalFileSystem.Open(p.Value.Value), shadowIndex), false);
|
||||
palette.AddPalette(p.Key, new ImmutablePalette(GlobalFileSystem.Open(p.Value.Value), shadowIndex), false);
|
||||
|
||||
var spriteLoader = new SpriteLoader(new string[0], new SheetBuilder(SheetType.Indexed));
|
||||
foreach (var s in nodesDict["Cursors"].Nodes)
|
||||
@@ -53,9 +53,6 @@ namespace OpenRA.Graphics
|
||||
PaletteReference CreatePaletteReference(string name)
|
||||
{
|
||||
var pal = palette.GetPalette(name);
|
||||
if (pal == null)
|
||||
throw new InvalidOperationException("Palette `{0}` does not exist".F(name));
|
||||
|
||||
return new PaletteReference(name, palette.GetPaletteIndex(name), pal);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2014 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
@@ -10,7 +10,6 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Graphics
|
||||
@@ -18,70 +17,101 @@ namespace OpenRA.Graphics
|
||||
public class HardwarePalette
|
||||
{
|
||||
public const int MaxPalettes = 256;
|
||||
int allocated = 0;
|
||||
|
||||
public ITexture Texture { get; private set; }
|
||||
Dictionary<string, Palette> palettes;
|
||||
Dictionary<string, int> indices;
|
||||
Dictionary<string, bool> allowsMods;
|
||||
readonly Dictionary<string, ImmutablePalette> palettes = new Dictionary<string, ImmutablePalette>();
|
||||
readonly Dictionary<string, MutablePalette> modifiablePalettes = new Dictionary<string, MutablePalette>();
|
||||
readonly IReadOnlyDictionary<string, MutablePalette> readOnlyModifiablePalettes;
|
||||
readonly Dictionary<string, int> indices = new Dictionary<string, int>();
|
||||
readonly uint[,] buffer = new uint[Palette.Size, MaxPalettes];
|
||||
|
||||
public HardwarePalette()
|
||||
{
|
||||
palettes = new Dictionary<string, Palette>();
|
||||
indices = new Dictionary<string, int>();
|
||||
allowsMods = new Dictionary<string, bool>();
|
||||
Texture = Game.Renderer.Device.CreateTexture();
|
||||
readOnlyModifiablePalettes = modifiablePalettes.AsReadOnly();
|
||||
}
|
||||
|
||||
public Palette GetPalette(string name)
|
||||
public IPalette GetPalette(string name)
|
||||
{
|
||||
Palette ret;
|
||||
if (!palettes.TryGetValue(name,out ret))
|
||||
throw new InvalidOperationException("Palette `{0}` does not exist".F(name));
|
||||
return ret;
|
||||
MutablePalette mutable;
|
||||
if (modifiablePalettes.TryGetValue(name, out mutable))
|
||||
return mutable.AsReadOnly();
|
||||
ImmutablePalette immutable;
|
||||
if (palettes.TryGetValue(name, out immutable))
|
||||
return immutable;
|
||||
throw new InvalidOperationException("Palette `{0}` does not exist".F(name));
|
||||
}
|
||||
|
||||
public int GetPaletteIndex(string name)
|
||||
{
|
||||
int ret;
|
||||
if (!indices.TryGetValue(name,out ret))
|
||||
if (!indices.TryGetValue(name, out ret))
|
||||
throw new InvalidOperationException("Palette `{0}` does not exist".F(name));
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void AddPalette(string name, Palette p, bool allowModifiers)
|
||||
public void AddPalette(string name, ImmutablePalette p, bool allowModifiers)
|
||||
{
|
||||
if (palettes.Count >= MaxPalettes)
|
||||
throw new InvalidOperationException("Limit of {0} palettes reached. Cannot add {1}.".F(MaxPalettes, name));
|
||||
if (palettes.ContainsKey(name))
|
||||
throw new InvalidOperationException("Palette {0} has already been defined".F(name));
|
||||
|
||||
int index = palettes.Count;
|
||||
indices.Add(name, index);
|
||||
palettes.Add(name, p);
|
||||
indices.Add(name, allocated++);
|
||||
allowsMods.Add(name, allowModifiers);
|
||||
if (allowModifiers)
|
||||
modifiablePalettes.Add(name, new MutablePalette(p));
|
||||
else
|
||||
CopyPaletteToBuffer(index, p);
|
||||
}
|
||||
|
||||
uint[,] data = new uint[MaxPalettes, 256];
|
||||
public void ApplyModifiers(IEnumerable<IPaletteModifier> paletteMods)
|
||||
public void ReplacePalette(string name, IPalette p)
|
||||
{
|
||||
var copy = palettes.ToDictionary(p => p.Key, p => new Palette(p.Value));
|
||||
var modifiable = copy.Where(p => allowsMods[p.Key]).ToDictionary(p => p.Key, p => p.Value);
|
||||
|
||||
foreach (var mod in paletteMods)
|
||||
mod.AdjustPalette(modifiable);
|
||||
|
||||
foreach (var pal in copy)
|
||||
{
|
||||
var j = indices[pal.Key];
|
||||
var c = pal.Value.Values;
|
||||
for (var i = 0; i < 256; i++)
|
||||
data[j,i] = c[i];
|
||||
}
|
||||
|
||||
Texture.SetData(data);
|
||||
if (modifiablePalettes.ContainsKey(name))
|
||||
CopyPaletteToBuffer(indices[name], modifiablePalettes[name] = new MutablePalette(p));
|
||||
else if (palettes.ContainsKey(name))
|
||||
CopyPaletteToBuffer(indices[name], palettes[name] = new ImmutablePalette(p));
|
||||
else
|
||||
throw new InvalidOperationException("Palette `{0}` does not exist".F(name));
|
||||
Texture.SetData(buffer);
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
ApplyModifiers(new IPaletteModifier[] {});
|
||||
CopyModifiablePalettesToBuffer();
|
||||
Texture.SetData(buffer);
|
||||
}
|
||||
|
||||
void CopyPaletteToBuffer(int index, IPalette p)
|
||||
{
|
||||
for (var i = 0; i < Palette.Size; i++)
|
||||
buffer[i, index] = p[i];
|
||||
}
|
||||
|
||||
void CopyModifiablePalettesToBuffer()
|
||||
{
|
||||
foreach (var kvp in modifiablePalettes)
|
||||
CopyPaletteToBuffer(indices[kvp.Key], kvp.Value);
|
||||
}
|
||||
|
||||
public void ApplyModifiers(IEnumerable<IPaletteModifier> paletteMods)
|
||||
{
|
||||
foreach (var mod in paletteMods)
|
||||
mod.AdjustPalette(readOnlyModifiablePalettes);
|
||||
|
||||
// Update our texture with the changes.
|
||||
CopyModifiablePalettesToBuffer();
|
||||
Texture.SetData(buffer);
|
||||
|
||||
// Reset modified palettes back to their original colors, ready for next time.
|
||||
foreach (var kvp in modifiablePalettes)
|
||||
{
|
||||
var originalPalette = palettes[kvp.Key];
|
||||
var modifiedPalette = kvp.Value;
|
||||
for (var i = 0; i < Palette.Size; i++)
|
||||
modifiedPalette[i] = originalPalette[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2012 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2014 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
@@ -8,94 +8,35 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace OpenRA.Graphics
|
||||
{
|
||||
public class Palette
|
||||
public interface IPalette { uint this[int index] { get; } }
|
||||
public interface IPaletteRemap { Color GetRemappedColor(Color original, int index); }
|
||||
|
||||
public static class Palette
|
||||
{
|
||||
public static Palette Load(string filename, int[] remap)
|
||||
public const int Size = 256;
|
||||
|
||||
public static Color GetColor(this IPalette palette, int index)
|
||||
{
|
||||
using (var s = File.OpenRead(filename))
|
||||
return new Palette(s, remap);
|
||||
return Color.FromArgb((int)palette[index]);
|
||||
}
|
||||
|
||||
uint[] colors;
|
||||
public Color GetColor(int index)
|
||||
{
|
||||
return Color.FromArgb((int)colors[index]);
|
||||
}
|
||||
|
||||
public void SetColor(int index, Color color)
|
||||
{
|
||||
colors[index] = (uint)color.ToArgb();
|
||||
}
|
||||
|
||||
public void SetColor(int index, uint color)
|
||||
{
|
||||
colors[index] = (uint)color;
|
||||
}
|
||||
|
||||
public uint[] Values
|
||||
{
|
||||
get { return colors; }
|
||||
}
|
||||
|
||||
public void ApplyRemap(IPaletteRemap r)
|
||||
{
|
||||
for (var i = 0; i < 256; i++)
|
||||
colors[i] = (uint)r.GetRemappedColor(Color.FromArgb((int)colors[i]), i).ToArgb();
|
||||
}
|
||||
|
||||
public Palette(Stream s, int[] remapShadow)
|
||||
{
|
||||
colors = new uint[256];
|
||||
|
||||
using (var reader = new BinaryReader(s))
|
||||
{
|
||||
for (var i = 0; i < 256; i++)
|
||||
{
|
||||
var r = (byte)(reader.ReadByte() << 2);
|
||||
var g = (byte)(reader.ReadByte() << 2);
|
||||
var b = (byte)(reader.ReadByte() << 2);
|
||||
colors[i] = (uint)((255 << 24) | (r << 16) | (g << 8) | b);
|
||||
}
|
||||
}
|
||||
|
||||
colors[0] = 0; // convert black background to transparency
|
||||
foreach (var i in remapShadow)
|
||||
colors[i] = 140u << 24;
|
||||
}
|
||||
|
||||
public Palette(Palette p, IPaletteRemap r)
|
||||
{
|
||||
colors = (uint[])p.colors.Clone();
|
||||
ApplyRemap(r);
|
||||
}
|
||||
|
||||
public Palette(Palette p)
|
||||
{
|
||||
colors = (uint[])p.colors.Clone();
|
||||
}
|
||||
|
||||
public Palette(uint[] data)
|
||||
{
|
||||
if (data.Length != 256)
|
||||
throw new InvalidDataException("Attempting to create palette with incorrect array size");
|
||||
colors = (uint[])data.Clone();
|
||||
}
|
||||
|
||||
public ColorPalette AsSystemPalette()
|
||||
public static ColorPalette AsSystemPalette(this IPalette palette)
|
||||
{
|
||||
ColorPalette pal;
|
||||
using (var b = new Bitmap(1, 1, PixelFormat.Format8bppIndexed))
|
||||
pal = b.Palette;
|
||||
|
||||
for (var i = 0; i < 256; i++)
|
||||
pal.Entries[i] = GetColor(i);
|
||||
for (var i = 0; i < Size; i++)
|
||||
pal.Entries[i] = palette.GetColor(i);
|
||||
|
||||
// hack around a mono bug -- the palette flags get set wrong.
|
||||
if (Platform.CurrentPlatform != PlatformType.Windows)
|
||||
@@ -105,22 +46,116 @@ namespace OpenRA.Graphics
|
||||
return pal;
|
||||
}
|
||||
|
||||
public Bitmap AsBitmap()
|
||||
public static Bitmap AsBitmap(this IPalette palette)
|
||||
{
|
||||
var b = new Bitmap(256, 1, PixelFormat.Format32bppArgb);
|
||||
var b = new Bitmap(Size, 1, PixelFormat.Format32bppArgb);
|
||||
var data = b.LockBits(new Rectangle(0, 0, b.Width, b.Height),
|
||||
ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
|
||||
unsafe
|
||||
{
|
||||
var c = (uint*)data.Scan0;
|
||||
for (var x = 0; x < 256; x++)
|
||||
*(c + x) = colors[x];
|
||||
}
|
||||
|
||||
var temp = new uint[Palette.Size];
|
||||
for (int i = 0; i < temp.Length; i++)
|
||||
temp[i] = palette[i];
|
||||
Marshal.Copy((int[])(object)temp, 0, data.Scan0, Size);
|
||||
b.UnlockBits(data);
|
||||
return b;
|
||||
}
|
||||
|
||||
public static IPalette AsReadOnly(this IPalette palette)
|
||||
{
|
||||
if (palette is ImmutablePalette)
|
||||
return palette;
|
||||
return new ReadOnlyPalette(palette);
|
||||
}
|
||||
|
||||
class ReadOnlyPalette : IPalette
|
||||
{
|
||||
IPalette palette;
|
||||
public ReadOnlyPalette(IPalette palette) { this.palette = palette; }
|
||||
public uint this[int index] { get { return palette[index]; } }
|
||||
}
|
||||
}
|
||||
|
||||
public interface IPaletteRemap { Color GetRemappedColor(Color original, int index); }
|
||||
public class ImmutablePalette : IPalette
|
||||
{
|
||||
readonly uint[] colors = new uint[Palette.Size];
|
||||
|
||||
public uint this[int index]
|
||||
{
|
||||
get { return colors[index]; }
|
||||
}
|
||||
|
||||
public ImmutablePalette(string filename, int[] remap)
|
||||
{
|
||||
using (var s = File.OpenRead(filename))
|
||||
LoadFromStream(s, remap);
|
||||
}
|
||||
|
||||
public ImmutablePalette(Stream s, int[] remapShadow)
|
||||
{
|
||||
LoadFromStream(s, remapShadow);
|
||||
}
|
||||
|
||||
void LoadFromStream(Stream s, int[] remapShadow)
|
||||
{
|
||||
using (var reader = new BinaryReader(s))
|
||||
for (var i = 0; i < Palette.Size; i++)
|
||||
{
|
||||
var r = (byte)(reader.ReadByte() << 2);
|
||||
var g = (byte)(reader.ReadByte() << 2);
|
||||
var b = (byte)(reader.ReadByte() << 2);
|
||||
colors[i] = (uint)((255 << 24) | (r << 16) | (g << 8) | b);
|
||||
}
|
||||
|
||||
colors[0] = 0; // Convert black background to transparency.
|
||||
foreach (var i in remapShadow)
|
||||
colors[i] = 140u << 24;
|
||||
}
|
||||
|
||||
public ImmutablePalette(IPalette p, IPaletteRemap r)
|
||||
: this(p)
|
||||
{
|
||||
for (var i = 0; i < Palette.Size; i++)
|
||||
colors[i] = (uint)r.GetRemappedColor(this.GetColor(i), i).ToArgb();
|
||||
}
|
||||
|
||||
public ImmutablePalette(IPalette p)
|
||||
{
|
||||
for (int i = 0; i < Palette.Size; i++)
|
||||
colors[i] = p[i];
|
||||
}
|
||||
|
||||
public ImmutablePalette(IEnumerable<uint> sourceColors)
|
||||
{
|
||||
var i = 0;
|
||||
foreach (var sourceColor in sourceColors)
|
||||
colors[i++] = sourceColor;
|
||||
}
|
||||
}
|
||||
|
||||
public class MutablePalette : IPalette
|
||||
{
|
||||
readonly uint[] colors = new uint[Palette.Size];
|
||||
|
||||
public uint this[int index]
|
||||
{
|
||||
get { return colors[index]; }
|
||||
set { colors[index] = value; }
|
||||
}
|
||||
|
||||
public MutablePalette(IPalette p)
|
||||
{
|
||||
for (int i = 0; i < Palette.Size; i++)
|
||||
this[i] = p[i];
|
||||
}
|
||||
|
||||
public void SetColor(int index, Color color)
|
||||
{
|
||||
colors[index] = (uint)color.ToArgb();
|
||||
}
|
||||
|
||||
public void ApplyRemap(IPaletteRemap r)
|
||||
{
|
||||
for (var i = 0; i < Palette.Size; i++)
|
||||
colors[i] = (uint)r.GetRemappedColor(this.GetColor(i), i).ToArgb();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ namespace OpenRA.Graphics
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
public Bitmap AsBitmap(TextureChannel channel, Palette pal)
|
||||
public Bitmap AsBitmap(TextureChannel channel, IPalette pal)
|
||||
{
|
||||
var d = Data;
|
||||
var dataStride = 4 * Size.Width;
|
||||
@@ -115,7 +115,7 @@ namespace OpenRA.Graphics
|
||||
for (var x = 0; x < Size.Width; x++)
|
||||
{
|
||||
var paletteIndex = d[dataRowIndex + 4 * x];
|
||||
colors[bdRowIndex + x] = pal.Values[paletteIndex];
|
||||
colors[bdRowIndex + x] = pal[paletteIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2014 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
@@ -12,7 +12,6 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using OpenRA.Primitives;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Graphics
|
||||
@@ -21,8 +20,8 @@ namespace OpenRA.Graphics
|
||||
{
|
||||
public readonly string Name;
|
||||
public readonly int Index;
|
||||
public readonly Palette Palette;
|
||||
public PaletteReference(string name, int index, Palette palette)
|
||||
public IPalette Palette { get; internal set; }
|
||||
public PaletteReference(string name, int index, IPalette palette)
|
||||
{
|
||||
Name = name;
|
||||
Index = index;
|
||||
@@ -36,10 +35,10 @@ namespace OpenRA.Graphics
|
||||
public readonly Theater Theater;
|
||||
public Viewport Viewport { get; private set; }
|
||||
|
||||
internal readonly TerrainRenderer terrainRenderer;
|
||||
internal readonly HardwarePalette palette;
|
||||
internal Cache<string, PaletteReference> palettes;
|
||||
Lazy<DeveloperMode> devTrait;
|
||||
readonly TerrainRenderer terrainRenderer;
|
||||
readonly HardwarePalette palette;
|
||||
readonly Dictionary<string, PaletteReference> palettes;
|
||||
readonly Lazy<DeveloperMode> devTrait;
|
||||
|
||||
internal WorldRenderer(World world)
|
||||
{
|
||||
@@ -47,9 +46,9 @@ namespace OpenRA.Graphics
|
||||
Viewport = new Viewport(this, world.Map);
|
||||
palette = new HardwarePalette();
|
||||
|
||||
palettes = new Cache<string, PaletteReference>(CreatePaletteReference);
|
||||
foreach (var pal in world.traitDict.ActorsWithTrait<IPalette>())
|
||||
pal.Trait.InitPalette(this);
|
||||
palettes = new Dictionary<string, PaletteReference>();
|
||||
foreach (var pal in world.traitDict.ActorsWithTrait<ILoadsPalettes>())
|
||||
pal.Trait.LoadPalettes(this);
|
||||
|
||||
palette.Initialize();
|
||||
|
||||
@@ -62,14 +61,13 @@ namespace OpenRA.Graphics
|
||||
PaletteReference CreatePaletteReference(string name)
|
||||
{
|
||||
var pal = palette.GetPalette(name);
|
||||
if (pal == null)
|
||||
throw new InvalidOperationException("Palette `{0}` does not exist".F(name));
|
||||
|
||||
return new PaletteReference(name, palette.GetPaletteIndex(name), pal);
|
||||
}
|
||||
|
||||
public PaletteReference Palette(string name) { return palettes[name]; }
|
||||
public void AddPalette(string name, Palette pal, bool allowModifiers) { palette.AddPalette(name, pal, allowModifiers); }
|
||||
public PaletteReference Palette(string name) { return palettes.GetOrAdd(name, CreatePaletteReference); }
|
||||
public void AddPalette(string name, ImmutablePalette pal) { palette.AddPalette(name, pal, false); }
|
||||
public void AddPalette(string name, ImmutablePalette pal, bool allowModifiers) { palette.AddPalette(name, pal, allowModifiers); }
|
||||
public void ReplacePalette(string name, IPalette pal) { palette.ReplacePalette(name, pal); palettes[name].Palette = pal; }
|
||||
|
||||
List<IRenderable> GenerateRenderables()
|
||||
{
|
||||
|
||||
@@ -32,6 +32,14 @@ namespace OpenRA
|
||||
bool TryGetValue(TKey key, out TValue value);
|
||||
}
|
||||
|
||||
public static class ReadOnlyDictionary
|
||||
{
|
||||
public static IReadOnlyDictionary<TKey, TValue> AsReadOnly<TKey, TValue>(this IDictionary<TKey, TValue> dict)
|
||||
{
|
||||
return dict as IReadOnlyDictionary<TKey, TValue> ?? new ReadOnlyDictionary<TKey, TValue>(dict);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A minimal read only dictionary for .NET 4 implemented as a wrapper
|
||||
/// around an IDictionary.
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace OpenRA.Traits
|
||||
public object Create(ActorInitializer init) { return new FixedColorPalette(this); }
|
||||
}
|
||||
|
||||
public class FixedColorPalette : IPalette
|
||||
public class FixedColorPalette : ILoadsPalettes
|
||||
{
|
||||
readonly FixedColorPaletteInfo info;
|
||||
|
||||
@@ -40,10 +40,10 @@ namespace OpenRA.Traits
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
public void InitPalette(WorldRenderer wr)
|
||||
public void LoadPalettes(WorldRenderer wr)
|
||||
{
|
||||
var remap = new PlayerColorRemap(info.RemapIndex, info.Color, info.Ramp);
|
||||
wr.AddPalette(info.Name, new Palette(wr.Palette(info.Base).Palette, remap), info.AllowModifiers);
|
||||
wr.AddPalette(info.Name, new ImmutablePalette(wr.Palette(info.Base).Palette, remap), info.AllowModifiers);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace OpenRA.Traits
|
||||
public object Create(ActorInitializer init) { return new PlayerColorPalette(init.self.Owner, this); }
|
||||
}
|
||||
|
||||
public class PlayerColorPalette : IPalette
|
||||
public class PlayerColorPalette : ILoadsPalettes
|
||||
{
|
||||
readonly Player owner;
|
||||
readonly PlayerColorPaletteInfo info;
|
||||
@@ -40,10 +40,10 @@ namespace OpenRA.Traits
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
public void InitPalette(WorldRenderer wr)
|
||||
public void LoadPalettes(WorldRenderer wr)
|
||||
{
|
||||
var remap = new PlayerColorRemap(info.RemapIndex, owner.Color, info.Ramp);
|
||||
wr.AddPalette(info.BaseName + owner.InternalName, new Palette(wr.Palette(info.BasePalette).Palette, remap), info.AllowModifiers);
|
||||
wr.AddPalette(info.BaseName + owner.InternalName, new ImmutablePalette(wr.Palette(info.BasePalette).Palette, remap), info.AllowModifiers);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#endregion
|
||||
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
|
||||
namespace OpenRA.Traits
|
||||
@@ -22,7 +23,7 @@ namespace OpenRA.Traits
|
||||
public object Create(ActorInitializer init) { return new PlayerHighlightPalette(init.self.Owner, this); }
|
||||
}
|
||||
|
||||
public class PlayerHighlightPalette : IPalette
|
||||
public class PlayerHighlightPalette : ILoadsPalettes
|
||||
{
|
||||
readonly Player owner;
|
||||
readonly PlayerHighlightPaletteInfo info;
|
||||
@@ -33,10 +34,10 @@ namespace OpenRA.Traits
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
public void InitPalette(WorldRenderer wr)
|
||||
public void LoadPalettes(WorldRenderer wr)
|
||||
{
|
||||
var argb = (uint)Color.FromArgb(128, owner.Color.RGB).ToArgb();
|
||||
wr.AddPalette(info.BaseName + owner.InternalName, new Palette(Exts.MakeArray(256, i => i == 0 ? 0 : argb)), false);
|
||||
wr.AddPalette(info.BaseName + owner.InternalName, new ImmutablePalette(Enumerable.Range(0, Palette.Size).Select(i => i == 0 ? 0 : argb)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,8 +150,8 @@ namespace OpenRA.Traits
|
||||
public interface IDamageModifier { float GetDamageModifier(Actor attacker, WarheadInfo warhead); }
|
||||
public interface ISpeedModifier { decimal GetSpeedModifier(); }
|
||||
public interface IFirepowerModifier { float GetFirepowerModifier(); }
|
||||
public interface IPalette { void InitPalette(WorldRenderer wr); }
|
||||
public interface IPaletteModifier { void AdjustPalette(Dictionary<string, Palette> b); }
|
||||
public interface ILoadsPalettes { void LoadPalettes(WorldRenderer wr); }
|
||||
public interface IPaletteModifier { void AdjustPalette(IReadOnlyDictionary<string, MutablePalette> b); }
|
||||
public interface IPips { IEnumerable<PipType> GetPips(Actor self); }
|
||||
public interface ITags { IEnumerable<TagType> GetTags(); }
|
||||
public interface ISelectionBar { float GetValue(); Color GetColor(); }
|
||||
|
||||
@@ -29,19 +29,19 @@ namespace OpenRA.Mods.RA
|
||||
public object Create(ActorInitializer init) { return new FogPaletteFromR8(this); }
|
||||
}
|
||||
|
||||
class FogPaletteFromR8 : IPalette
|
||||
class FogPaletteFromR8 : ILoadsPalettes
|
||||
{
|
||||
readonly FogPaletteFromR8Info info;
|
||||
public FogPaletteFromR8(FogPaletteFromR8Info info) { this.info = info; }
|
||||
|
||||
public void InitPalette(WorldRenderer wr)
|
||||
public void LoadPalettes(WorldRenderer wr)
|
||||
{
|
||||
var colors = new uint[256];
|
||||
var colors = new uint[Palette.Size];
|
||||
using (var s = GlobalFileSystem.Open(info.Filename))
|
||||
{
|
||||
s.Seek(info.Offset, SeekOrigin.Begin);
|
||||
|
||||
for (var i = 0; i < 256; i++)
|
||||
for (var i = 0; i < Palette.Size; i++)
|
||||
{
|
||||
var packed = s.ReadUInt16();
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace OpenRA.Mods.RA
|
||||
}
|
||||
}
|
||||
|
||||
wr.AddPalette(info.Name, new Palette(colors), info.AllowModifiers);
|
||||
wr.AddPalette(info.Name, new ImmutablePalette(colors), info.AllowModifiers);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,19 +29,19 @@ namespace OpenRA.Mods.RA
|
||||
public object Create(ActorInitializer init) { return new PaletteFromR8(this); }
|
||||
}
|
||||
|
||||
class PaletteFromR8 : IPalette
|
||||
class PaletteFromR8 : ILoadsPalettes
|
||||
{
|
||||
readonly PaletteFromR8Info info;
|
||||
public PaletteFromR8(PaletteFromR8Info info) { this.info = info; }
|
||||
|
||||
public void InitPalette(WorldRenderer wr)
|
||||
public void LoadPalettes(WorldRenderer wr)
|
||||
{
|
||||
var colors = new uint[256];
|
||||
var colors = new uint[Palette.Size];
|
||||
using (var s = GlobalFileSystem.Open(info.Filename))
|
||||
{
|
||||
s.Seek(info.Offset, SeekOrigin.Begin);
|
||||
|
||||
for (var i = 0; i < 256; i++)
|
||||
for (var i = 0; i < Palette.Size; i++)
|
||||
{
|
||||
var packed = s.ReadUInt16();
|
||||
colors[i] = (uint)((255 << 24) | ((packed & 0xF800) << 8) | ((packed & 0x7E0) << 5) | ((packed & 0x1f) << 3));
|
||||
@@ -51,7 +51,7 @@ namespace OpenRA.Mods.RA
|
||||
}
|
||||
}
|
||||
|
||||
wr.AddPalette(info.Name, new Palette(colors), info.AllowModifiers);
|
||||
wr.AddPalette(info.Name, new ImmutablePalette(colors), info.AllowModifiers);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,15 +35,15 @@ namespace OpenRA.Mods.D2k
|
||||
public object Create(ActorInitializer init) { return new PaletteFromScaledPalette(this); }
|
||||
}
|
||||
|
||||
class PaletteFromScaledPalette : IPalette
|
||||
class PaletteFromScaledPalette : ILoadsPalettes
|
||||
{
|
||||
readonly PaletteFromScaledPaletteInfo info;
|
||||
public PaletteFromScaledPalette(PaletteFromScaledPaletteInfo info) { this.info = info; }
|
||||
|
||||
public void InitPalette(WorldRenderer wr)
|
||||
public void LoadPalettes(WorldRenderer wr)
|
||||
{
|
||||
var remap = new ScaledPaletteRemap(info.Scale, info.Offset);
|
||||
wr.AddPalette(info.Name, new Palette(wr.Palette(info.BasePalette).Palette, remap), info.AllowModifiers);
|
||||
wr.AddPalette(info.Name, new ImmutablePalette(wr.Palette(info.BasePalette).Palette, remap), info.AllowModifiers);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,16 +33,16 @@ namespace OpenRA.Mods.RA
|
||||
remainingFrames--;
|
||||
}
|
||||
|
||||
public void AdjustPalette(Dictionary<string,Palette> palettes)
|
||||
public void AdjustPalette(IReadOnlyDictionary<string, MutablePalette> palettes)
|
||||
{
|
||||
if (remainingFrames == 0)
|
||||
return;
|
||||
|
||||
var frac = (float)remainingFrames / chronoEffectLength;
|
||||
|
||||
|
||||
foreach (var pal in palettes)
|
||||
{
|
||||
for (var x = 0; x < 256; x++)
|
||||
for (var x = 0; x < Palette.Size; x++)
|
||||
{
|
||||
var orig = pal.Value.GetColor(x);
|
||||
var lum = (int)(255 * orig.GetBrightness());
|
||||
|
||||
@@ -15,7 +15,7 @@ using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
public class CloakPaletteEffectInfo : TraitInfo<CloakPaletteEffect> {}
|
||||
public class CloakPaletteEffectInfo : TraitInfo<CloakPaletteEffect> { }
|
||||
|
||||
public class CloakPaletteEffect : IPaletteModifier, ITick
|
||||
{
|
||||
@@ -29,23 +29,22 @@ namespace OpenRA.Mods.RA
|
||||
Color.FromArgb(178, 205, 250, 220),
|
||||
};
|
||||
|
||||
public void AdjustPalette(Dictionary<string, Palette> b)
|
||||
public void AdjustPalette(IReadOnlyDictionary<string, MutablePalette> b)
|
||||
{
|
||||
var i = (int)t;
|
||||
var p = b[paletteName];
|
||||
|
||||
for (var j = 0; j < colors.Length; j++ )
|
||||
for (var j = 0; j < colors.Length; j++)
|
||||
{
|
||||
var k = (i+j) % 16 + 0xb0;
|
||||
p.SetColor(k, colors[j]);
|
||||
var k = (i + j) % 16 + 0xb0;
|
||||
p.SetColor(k, colors[j]);
|
||||
}
|
||||
}
|
||||
|
||||
public void Tick (Actor self)
|
||||
public void Tick(Actor self)
|
||||
{
|
||||
t += 0.25f;
|
||||
if (t >= 256) t = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace OpenRA.Mods.RA
|
||||
[Desc("Palette effect used for blinking \"animations\" on actors.")]
|
||||
class LightPaletteRotatorInfo : ITraitInfo
|
||||
{
|
||||
public readonly string[] ExcludePalettes = {};
|
||||
public readonly string[] ExcludePalettes = { };
|
||||
|
||||
public object Create(ActorInitializer init) { return new LightPaletteRotator(this); }
|
||||
}
|
||||
@@ -38,7 +38,7 @@ namespace OpenRA.Mods.RA
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
public void AdjustPalette(Dictionary<string,Palette> palettes)
|
||||
public void AdjustPalette(IReadOnlyDictionary<string, MutablePalette> palettes)
|
||||
{
|
||||
foreach (var pal in palettes)
|
||||
{
|
||||
@@ -49,7 +49,7 @@ namespace OpenRA.Mods.RA
|
||||
if (rotate > 9)
|
||||
rotate = 18 - rotate;
|
||||
|
||||
pal.Value.SetColor(0x67, pal.Value.GetColor(230+rotate));
|
||||
pal.Value.SetColor(0x67, pal.Value.GetColor(230 + rotate));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,24 +66,24 @@ namespace OpenRA.Mods.RA
|
||||
}
|
||||
}
|
||||
|
||||
public void AdjustPalette(Dictionary<string, Palette> palettes)
|
||||
public void AdjustPalette(IReadOnlyDictionary<string, MutablePalette> palettes)
|
||||
{
|
||||
if (to == EffectType.None && remainingFrames == 0)
|
||||
return;
|
||||
|
||||
foreach (var pal in palettes)
|
||||
foreach (var pal in palettes.Values)
|
||||
{
|
||||
for (var x = 0; x < 256; x++)
|
||||
for (var x = 0; x < Palette.Size; x++)
|
||||
{
|
||||
var orig = pal.Value.GetColor(x);
|
||||
var orig = pal.GetColor(x);
|
||||
var t = ColorForEffect(to, orig);
|
||||
|
||||
if (remainingFrames == 0)
|
||||
pal.Value.SetColor(x, t);
|
||||
pal.SetColor(x, t);
|
||||
else
|
||||
{
|
||||
var f = ColorForEffect(from, orig);
|
||||
pal.Value.SetColor(x, Exts.ColorLerp((float)remainingFrames / Info.FadeLength, t, f));
|
||||
pal.SetColor(x, Exts.ColorLerp((float)remainingFrames / Info.FadeLength, t, f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace OpenRA.Mods.RA
|
||||
remainingFrames--;
|
||||
}
|
||||
|
||||
public void AdjustPalette(Dictionary<string,Palette> palettes)
|
||||
public void AdjustPalette(IReadOnlyDictionary<string, MutablePalette> palettes)
|
||||
{
|
||||
if (remainingFrames == 0)
|
||||
return;
|
||||
@@ -42,11 +42,11 @@ namespace OpenRA.Mods.RA
|
||||
|
||||
foreach (var pal in palettes)
|
||||
{
|
||||
for (var x = 0; x < 256; x++)
|
||||
for (var x = 0; x < Palette.Size; x++)
|
||||
{
|
||||
var orig = pal.Value.GetColor(x);
|
||||
var white = Color.FromArgb(orig.A, 255, 255, 255);
|
||||
pal.Value.SetColor(x, Exts.ColorLerp(frac,orig,white));
|
||||
pal.Value.SetColor(x, Exts.ColorLerp(frac, orig, white));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace OpenRA.Mods.RA
|
||||
public object Create(ActorInitializer init) { return new PaletteFromCurrentTileset(init.world, this); }
|
||||
}
|
||||
|
||||
class PaletteFromCurrentTileset : IPalette
|
||||
class PaletteFromCurrentTileset : ILoadsPalettes
|
||||
{
|
||||
readonly World world;
|
||||
readonly PaletteFromCurrentTilesetInfo info;
|
||||
@@ -37,9 +37,9 @@ namespace OpenRA.Mods.RA
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
public void InitPalette(WorldRenderer wr)
|
||||
public void LoadPalettes(WorldRenderer wr)
|
||||
{
|
||||
wr.AddPalette(info.Name, new Palette(GlobalFileSystem.Open(world.TileSet.Palette), info.ShadowIndex), info.AllowModifiers);
|
||||
wr.AddPalette(info.Name, new ImmutablePalette(GlobalFileSystem.Open(world.TileSet.Palette), info.ShadowIndex), info.AllowModifiers);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace OpenRA.Mods.RA
|
||||
public object Create(ActorInitializer init) { return new PaletteFromFile(init.world, this); }
|
||||
}
|
||||
|
||||
class PaletteFromFile : IPalette
|
||||
class PaletteFromFile : ILoadsPalettes
|
||||
{
|
||||
readonly World world;
|
||||
readonly PaletteFromFileInfo info;
|
||||
@@ -39,10 +39,10 @@ namespace OpenRA.Mods.RA
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
public void InitPalette(WorldRenderer wr)
|
||||
public void LoadPalettes(WorldRenderer wr)
|
||||
{
|
||||
if (info.Tileset == null || info.Tileset.ToLowerInvariant() == world.Map.Tileset.ToLowerInvariant())
|
||||
wr.AddPalette(info.Name, new Palette(GlobalFileSystem.Open(info.Filename), info.ShadowIndex), info.AllowModifiers);
|
||||
wr.AddPalette(info.Name, new ImmutablePalette(GlobalFileSystem.Open(info.Filename), info.ShadowIndex), info.AllowModifiers);
|
||||
}
|
||||
|
||||
public string Filename
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Traits;
|
||||
|
||||
@@ -33,7 +34,7 @@ namespace OpenRA.Mods.RA
|
||||
public object Create(ActorInitializer init) { return new PaletteFromRGBA(init.world, this); }
|
||||
}
|
||||
|
||||
class PaletteFromRGBA : IPalette
|
||||
class PaletteFromRGBA : ILoadsPalettes
|
||||
{
|
||||
readonly World world;
|
||||
readonly PaletteFromRGBAInfo info;
|
||||
@@ -43,14 +44,14 @@ namespace OpenRA.Mods.RA
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
public void InitPalette(WorldRenderer wr)
|
||||
public void LoadPalettes(WorldRenderer wr)
|
||||
{
|
||||
// Enable palette only for a specific tileset
|
||||
if (info.Tileset != null && info.Tileset.ToLowerInvariant() != world.Map.Tileset.ToLowerInvariant())
|
||||
return;
|
||||
|
||||
var c = (uint)((info.A << 24) | (info.R << 16) | (info.G << 8) | info.B);
|
||||
wr.AddPalette(info.Name, new Palette(Exts.MakeArray(256, i => (i == 0) ? 0 : c)), info.AllowModifiers);
|
||||
wr.AddPalette(info.Name, new ImmutablePalette(Enumerable.Range(0, Palette.Size).Select(i => (i == 0) ? 0 : c)), info.AllowModifiers);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace OpenRA.Mods.RA
|
||||
public object Create(ActorInitializer init) { return new PlayerPaletteFromCurrentTileset(init.world, this); }
|
||||
}
|
||||
|
||||
class PlayerPaletteFromCurrentTileset : IPalette
|
||||
class PlayerPaletteFromCurrentTileset : ILoadsPalettes
|
||||
{
|
||||
readonly World world;
|
||||
readonly PlayerPaletteFromCurrentTilesetInfo info;
|
||||
@@ -37,10 +37,10 @@ namespace OpenRA.Mods.RA
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
public void InitPalette(WorldRenderer wr)
|
||||
public void LoadPalettes(WorldRenderer wr)
|
||||
{
|
||||
var filename = world.TileSet.PlayerPalette ?? world.TileSet.Palette;
|
||||
wr.AddPalette(info.Name, new Palette(GlobalFileSystem.Open(filename), info.ShadowIndex), info.AllowModifiers);
|
||||
wr.AddPalette(info.Name, new ImmutablePalette(GlobalFileSystem.Open(filename), info.ShadowIndex), info.AllowModifiers);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#endregion
|
||||
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Traits;
|
||||
|
||||
@@ -26,16 +27,16 @@ namespace OpenRA.Mods.RA
|
||||
public object Create(ActorInitializer init) { return new ShroudPalette(this); }
|
||||
}
|
||||
|
||||
class ShroudPalette : IPalette
|
||||
class ShroudPalette : ILoadsPalettes
|
||||
{
|
||||
readonly ShroudPaletteInfo info;
|
||||
|
||||
public ShroudPalette(ShroudPaletteInfo info) { this.info = info; }
|
||||
|
||||
public void InitPalette(WorldRenderer wr)
|
||||
public void LoadPalettes(WorldRenderer wr)
|
||||
{
|
||||
var c = info.Fog ? Fog : Shroud;
|
||||
wr.AddPalette(info.Name, new Palette(Exts.MakeArray(256, i => (uint)c[i % 8].ToArgb())), false);
|
||||
wr.AddPalette(info.Name, new ImmutablePalette(Enumerable.Range(0, Palette.Size).Select(i => (uint)c[i % 8].ToArgb())));
|
||||
}
|
||||
|
||||
static Color[] Fog = new[] {
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace OpenRA.Mods.RA
|
||||
public object Create(ActorInitializer init) { return new VoxelNormalsPalette(this); }
|
||||
}
|
||||
|
||||
public class VoxelNormalsPalette : IPalette
|
||||
public class VoxelNormalsPalette : ILoadsPalettes
|
||||
{
|
||||
readonly VoxelNormalsPaletteInfo info;
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace OpenRA.Mods.RA
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
public void InitPalette(WorldRenderer wr)
|
||||
public void LoadPalettes(WorldRenderer wr)
|
||||
{
|
||||
// Rotate vectors to expected orientation
|
||||
// Voxel coordinates are x=forward, y=right, z=up
|
||||
@@ -40,7 +40,7 @@ namespace OpenRA.Mods.RA
|
||||
|
||||
// Map normals into color range
|
||||
// Introduces a maximum error of ~0.5%
|
||||
var data = new uint[256];
|
||||
var data = new uint[Palette.Size];
|
||||
for (var i = 0; i < n.Length / 3; i++)
|
||||
{
|
||||
data[i] = 0xFF000000;
|
||||
@@ -51,7 +51,7 @@ namespace OpenRA.Mods.RA
|
||||
}
|
||||
}
|
||||
|
||||
wr.AddPalette(info.Name, new Palette(data), false);
|
||||
wr.AddPalette(info.Name, new ImmutablePalette(data));
|
||||
}
|
||||
|
||||
// Normal vector tables from http://www.sleipnirstuff.com/forum/viewtopic.php?t=8048
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace OpenRA.Mods.RA
|
||||
[Desc("Palette effect used for sprinkle \"animations\" on terrain tiles.")]
|
||||
class WaterPaletteRotationInfo : ITraitInfo
|
||||
{
|
||||
public readonly string[] ExcludePalettes = {};
|
||||
public readonly string[] ExcludePalettes = { };
|
||||
|
||||
public object Create(ActorInitializer init) { return new WaterPaletteRotation(init.world, this); }
|
||||
}
|
||||
@@ -38,23 +38,26 @@ namespace OpenRA.Mods.RA
|
||||
|
||||
public void Tick(Actor self) { t += .25f; }
|
||||
|
||||
static uint[] temp = new uint[7]; /* allocating this on the fly actually hurts our profile */
|
||||
uint[] temp = new uint[7]; /* allocating this on the fly actually hurts our profile */
|
||||
|
||||
public void AdjustPalette(Dictionary<string,Palette> palettes)
|
||||
public void AdjustPalette(IReadOnlyDictionary<string, MutablePalette> palettes)
|
||||
{
|
||||
foreach (var pal in palettes)
|
||||
var rotate = (int)t % 7;
|
||||
if (rotate == 0)
|
||||
return;
|
||||
|
||||
foreach (var kvp in palettes)
|
||||
{
|
||||
if (info.ExcludePalettes.Contains(pal.Key))
|
||||
if (info.ExcludePalettes.Contains(kvp.Key))
|
||||
continue;
|
||||
|
||||
var colors = pal.Value.Values;
|
||||
var rotate = (int)t % 7;
|
||||
var palette = kvp.Value;
|
||||
|
||||
for (var i = 0; i < 7; i++)
|
||||
temp[(rotate + i) % 7] = colors[world.TileSet.WaterPaletteRotationBase + i];
|
||||
temp[(rotate + i) % 7] = palette[world.TileSet.WaterPaletteRotationBase + i];
|
||||
|
||||
for (var i = 0; i < 7; i++)
|
||||
pal.Value.SetColor(world.TileSet.WaterPaletteRotationBase + i, temp[i]);
|
||||
palette[world.TileSet.WaterPaletteRotationBase + i] = temp[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,14 +16,14 @@ namespace OpenRA.Mods.RA.Widgets
|
||||
{
|
||||
public class ColorPreviewManagerWidget : Widget
|
||||
{
|
||||
public readonly string Palette = "colorpicker";
|
||||
public readonly string PaletteName = "colorpicker";
|
||||
public readonly int[] RemapIndices = ChromeMetrics.Get<int[]>("ColorPickerRemapIndices");
|
||||
public readonly float Ramp = 0.05f;
|
||||
public HSLColor Color;
|
||||
|
||||
HSLColor cachedColor;
|
||||
WorldRenderer worldRenderer;
|
||||
Palette preview;
|
||||
IPalette preview;
|
||||
|
||||
[ObjectCreator.UseCtor]
|
||||
public ColorPreviewManagerWidget(WorldRenderer worldRenderer)
|
||||
@@ -34,17 +34,18 @@ namespace OpenRA.Mods.RA.Widgets
|
||||
public override void Initialize(WidgetArgs args)
|
||||
{
|
||||
base.Initialize(args);
|
||||
preview = worldRenderer.Palette(Palette).Palette;
|
||||
preview = worldRenderer.Palette(PaletteName).Palette;
|
||||
}
|
||||
|
||||
public override void Tick()
|
||||
{
|
||||
if (cachedColor == Color)
|
||||
return;
|
||||
|
||||
preview.ApplyRemap(new PlayerColorRemap(RemapIndices, Color, Ramp));
|
||||
cachedColor = Color;
|
||||
|
||||
var newPalette = new MutablePalette(preview);
|
||||
newPalette.ApplyRemap(new PlayerColorRemap(RemapIndices, Color, Ramp));
|
||||
worldRenderer.ReplacePalette(PaletteName, newPalette);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
||||
var colorDropdown = panel.GetOrNull<DropDownButtonWidget>("COLOR");
|
||||
if (colorDropdown != null)
|
||||
{
|
||||
colorDropdown.IsDisabled = () => currentPalette != colorPreview.Palette;
|
||||
colorDropdown.IsDisabled = () => currentPalette != colorPreview.PaletteName;
|
||||
colorDropdown.OnMouseDown = _ => ShowColorDropDown(colorDropdown, colorPreview, world);
|
||||
panel.Get<ColorBlockWidget>("COLORBLOCK").GetColor = () => Game.Settings.Player.Color.RGB;
|
||||
}
|
||||
|
||||
@@ -9,8 +9,7 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using OpenRA.FileFormats;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Traits;
|
||||
|
||||
@@ -25,13 +24,13 @@ namespace OpenRA.Mods.TS
|
||||
public object Create(ActorInitializer init) { return new TSShroudPalette(this); }
|
||||
}
|
||||
|
||||
class TSShroudPalette : IPalette
|
||||
class TSShroudPalette : ILoadsPalettes
|
||||
{
|
||||
readonly TSShroudPaletteInfo info;
|
||||
|
||||
public TSShroudPalette(TSShroudPaletteInfo info) { this.info = info; }
|
||||
|
||||
public void InitPalette(WorldRenderer wr)
|
||||
public void LoadPalettes(WorldRenderer wr)
|
||||
{
|
||||
Func<int, uint> makeColor = i =>
|
||||
{
|
||||
@@ -40,7 +39,7 @@ namespace OpenRA.Mods.TS
|
||||
return 0;
|
||||
};
|
||||
|
||||
wr.AddPalette(info.Name, new Palette(Exts.MakeArray(256, i => makeColor(i))), false);
|
||||
wr.AddPalette(info.Name, new ImmutablePalette(Enumerable.Range(0, Palette.Size).Select(i => makeColor(i))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace OpenRA.TilesetBuilder
|
||||
string srcfile;
|
||||
int size;
|
||||
public TerrainTypeInfo[] TerrainType;
|
||||
public Palette TerrainPalette;
|
||||
public ImmutablePalette TerrainPalette;
|
||||
public bool PaletteFromImage = true;
|
||||
public string PaletteFile = "";
|
||||
public string ImageFile = "";
|
||||
@@ -60,7 +60,7 @@ namespace OpenRA.TilesetBuilder
|
||||
|
||||
if (!PaletteFromImage)
|
||||
{
|
||||
TerrainPalette = Palette.Load(PaletteFile, shadowIndex);
|
||||
TerrainPalette = new ImmutablePalette(PaletteFile, shadowIndex);
|
||||
rbitmap.Palette = TerrainPalette.AsSystemPalette();
|
||||
}
|
||||
|
||||
@@ -247,8 +247,8 @@ namespace OpenRA.TilesetBuilder
|
||||
|
||||
static string ExportPalette(List<Color> p, string file)
|
||||
{
|
||||
while (p.Count < 256) p.Add(Color.Black); // pad the palette out with extra blacks
|
||||
var paletteData = p.Take(256).SelectMany(
|
||||
while (p.Count < Palette.Size) p.Add(Color.Black); // pad the palette out with extra blacks
|
||||
var paletteData = p.Take(Palette.Size).SelectMany(
|
||||
c => new byte[] { (byte)(c.R >> 2), (byte)(c.G >> 2), (byte)(c.B >> 2) }).ToArray();
|
||||
File.WriteAllBytes(file, paletteData);
|
||||
return file;
|
||||
|
||||
@@ -96,7 +96,7 @@ namespace OpenRA.Utility
|
||||
shadowIndex[shadowIndex.Length - 3] = 4;
|
||||
}
|
||||
|
||||
var palette = Palette.Load(args[2], shadowIndex);
|
||||
var palette = new ImmutablePalette(args[2], shadowIndex);
|
||||
|
||||
ISpriteSource source;
|
||||
using (var stream = File.OpenRead(src))
|
||||
@@ -209,16 +209,14 @@ namespace OpenRA.Utility
|
||||
= PlayerColorRemap.GetRemapIndex(destRemapIndex, i);
|
||||
|
||||
// map everything else to the best match based on channel-wise distance
|
||||
var srcPalette = Palette.Load(args[1].Split(':')[1], shadowIndex);
|
||||
var destPalette = Palette.Load(args[2].Split(':')[1], shadowIndex);
|
||||
var srcPalette = new ImmutablePalette(args[1].Split(':')[1], shadowIndex);
|
||||
var destPalette = new ImmutablePalette(args[2].Split(':')[1], shadowIndex);
|
||||
|
||||
var fullIndexRange = Exts.MakeArray<int>(256, x => x);
|
||||
|
||||
for (var i = 0; i < 256; i++)
|
||||
for (var i = 0; i < Palette.Size; i++)
|
||||
if (!remap.ContainsKey(i))
|
||||
remap[i] = fullIndexRange
|
||||
remap[i] = Enumerable.Range(0, Palette.Size)
|
||||
.Where(a => !remap.ContainsValue(a))
|
||||
.MinBy(a => ColorDistance(destPalette.Values[a], srcPalette.Values[i]));
|
||||
.MinBy(a => ColorDistance(destPalette[a], srcPalette[i]));
|
||||
|
||||
var srcImage = ShpReader.Load(args[3]);
|
||||
|
||||
|
||||
@@ -3,6 +3,6 @@ uniform sampler2D DiffuseTexture, Palette;
|
||||
void main()
|
||||
{
|
||||
vec4 x = texture2D(DiffuseTexture, gl_TexCoord[0].st);
|
||||
vec2 p = vec2( dot(x, gl_TexCoord[1]), gl_TexCoord[0].p );
|
||||
gl_FragColor = texture2D(Palette,p);
|
||||
}
|
||||
vec2 p = vec2(gl_TexCoord[0].p, dot(x, gl_TexCoord[1]));
|
||||
gl_FragColor = texture2D(Palette, p);
|
||||
}
|
||||
|
||||
@@ -7,11 +7,11 @@ uniform vec3 AmbientLight, DiffuseLight;
|
||||
void main()
|
||||
{
|
||||
vec4 x = texture2D(DiffuseTexture, gl_TexCoord[0].st);
|
||||
vec4 color = texture2D(Palette, vec2(dot(x, gl_TexCoord[1]), PaletteRows.x));
|
||||
vec4 color = texture2D(Palette, vec2(PaletteRows.x, dot(x, gl_TexCoord[1])));
|
||||
if (color.a < 0.01)
|
||||
discard;
|
||||
|
||||
vec4 normal = (2.0*texture2D(Palette, vec2(dot(x, gl_TexCoord[2]), PaletteRows.y)) - 1.0);
|
||||
vec3 intensity = AmbientLight + DiffuseLight*max(dot(normal, LightDirection), 0.0);
|
||||
gl_FragColor = vec4(intensity*color.rgb, color.a);
|
||||
vec4 normal = (2.0 * texture2D(Palette, vec2(PaletteRows.y, dot(x, gl_TexCoord[2]))) - 1.0);
|
||||
vec3 intensity = AmbientLight + DiffuseLight * max(dot(normal, LightDirection), 0.0);
|
||||
gl_FragColor = vec4(intensity * color.rgb, color.a);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user