diff --git a/OpenRA.Game/Graphics/HardwarePalette.cs b/OpenRA.Game/Graphics/HardwarePalette.cs index c2e8e29870..ed60251027 100644 --- a/OpenRA.Game/Graphics/HardwarePalette.cs +++ b/OpenRA.Game/Graphics/HardwarePalette.cs @@ -16,14 +16,13 @@ namespace OpenRA.Graphics { public sealed class HardwarePalette : IDisposable { - public const int MaxPalettes = 256; - public ITexture Texture { get; private set; } + public int Height { get; private set; } readonly Dictionary palettes = new Dictionary(); readonly Dictionary modifiablePalettes = new Dictionary(); readonly IReadOnlyDictionary readOnlyModifiablePalettes; readonly Dictionary indices = new Dictionary(); - readonly uint[,] buffer = new uint[MaxPalettes, Palette.Size]; + byte[] buffer = new byte[0]; public HardwarePalette() { @@ -52,14 +51,19 @@ namespace OpenRA.Graphics 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); + + if (palettes.Count > Height) + { + Height = Exts.NextPowerOf2(palettes.Count); + Array.Resize(ref buffer, Height * Palette.Size * 4); + } + if (allowModifiers) modifiablePalettes.Add(name, new MutablePalette(p)); else @@ -74,13 +78,13 @@ namespace OpenRA.Graphics CopyPaletteToBuffer(indices[name], palettes[name] = new ImmutablePalette(p)); else throw new InvalidOperationException("Palette `{0}` does not exist".F(name)); - Texture.SetData(buffer); + CopyBufferToTexture(); } public void Initialize() { CopyModifiablePalettesToBuffer(); - Texture.SetData(buffer); + CopyBufferToTexture(); } void CopyPaletteToBuffer(int index, IPalette p) @@ -94,6 +98,11 @@ namespace OpenRA.Graphics CopyPaletteToBuffer(indices[kvp.Key], kvp.Value); } + void CopyBufferToTexture() + { + Texture.SetData(buffer, Palette.Size, Height); + } + public void ApplyModifiers(IEnumerable paletteMods) { foreach (var mod in paletteMods) @@ -101,7 +110,7 @@ namespace OpenRA.Graphics // Update our texture with the changes. CopyModifiablePalettesToBuffer(); - Texture.SetData(buffer); + CopyBufferToTexture(); // Reset modified palettes back to their original colors, ready for next time. foreach (var kvp in modifiablePalettes) diff --git a/OpenRA.Game/Graphics/SoftwareCursor.cs b/OpenRA.Game/Graphics/SoftwareCursor.cs index 047ca9ca8b..09725f1957 100644 --- a/OpenRA.Game/Graphics/SoftwareCursor.cs +++ b/OpenRA.Game/Graphics/SoftwareCursor.cs @@ -57,7 +57,7 @@ namespace OpenRA.Graphics PaletteReference CreatePaletteReference(string name) { var pal = palette.GetPalette(name); - return new PaletteReference(name, palette.GetPaletteIndex(name), pal); + return new PaletteReference(name, palette.GetPaletteIndex(name), pal, palette); } string cursorName; diff --git a/OpenRA.Game/Graphics/SpriteRenderer.cs b/OpenRA.Game/Graphics/SpriteRenderer.cs index 0d6d6dc133..b5ec0c2e60 100644 --- a/OpenRA.Game/Graphics/SpriteRenderer.cs +++ b/OpenRA.Game/Graphics/SpriteRenderer.cs @@ -51,15 +51,15 @@ namespace OpenRA.Graphics public void DrawSprite(Sprite s, float2 location, PaletteReference pal) { - DrawSprite(s, location, pal.Index, s.Size); + DrawSprite(s, location, pal.TextureIndex, s.Size); } public void DrawSprite(Sprite s, float2 location, PaletteReference pal, float2 size) { - DrawSprite(s, location, pal.Index, size); + DrawSprite(s, location, pal.TextureIndex, size); } - void DrawSprite(Sprite s, float2 location, int paletteIndex, float2 size) + void DrawSprite(Sprite s, float2 location, float paletteTextureIndex, float2 size) { renderer.CurrentBatchRenderer = this; @@ -74,7 +74,7 @@ namespace OpenRA.Graphics currentBlend = s.BlendMode; currentSheet = s.Sheet; - Util.FastCreateQuad(vertices, location + s.FractionalOffset * size, s, paletteIndex, nv, size); + Util.FastCreateQuad(vertices, location + s.FractionalOffset * size, s, paletteTextureIndex, nv, size); nv += 4; } diff --git a/OpenRA.Game/Graphics/TerrainRenderer.cs b/OpenRA.Game/Graphics/TerrainRenderer.cs index bbb01eee2f..18e95fd747 100644 --- a/OpenRA.Game/Graphics/TerrainRenderer.cs +++ b/OpenRA.Game/Graphics/TerrainRenderer.cs @@ -24,7 +24,7 @@ namespace OpenRA.Graphics this.world = world; this.map = world.Map; - var terrainPalette = wr.Palette("terrain").Index; + var terrainPalette = wr.Palette("terrain").TextureIndex; var vertices = new Vertex[4 * map.Bounds.Height * map.Bounds.Width]; var nv = 0; diff --git a/OpenRA.Game/Graphics/Util.cs b/OpenRA.Game/Graphics/Util.cs index 9ca3130d1f..d0b05396f0 100644 --- a/OpenRA.Game/Graphics/Util.cs +++ b/OpenRA.Game/Graphics/Util.cs @@ -21,23 +21,22 @@ namespace OpenRA.Graphics static readonly int[] ChannelMasks = { 2, 1, 0, 3 }; static readonly float[] ChannelSelect = { 0.75f, 0.25f, -0.25f, -0.75f }; - public static void FastCreateQuad(Vertex[] vertices, float2 o, Sprite r, int palette, int nv, float2 size) + public static void FastCreateQuad(Vertex[] vertices, float2 o, Sprite r, float paletteTextureIndex, int nv, float2 size) { var b = new float2(o.X + size.X, o.Y); var c = new float2(o.X + size.X, o.Y + size.Y); var d = new float2(o.X, o.Y + size.Y); - FastCreateQuad(vertices, o, b, c, d, r, palette, nv); + FastCreateQuad(vertices, o, b, c, d, r, paletteTextureIndex, nv); } - public static void FastCreateQuad(Vertex[] vertices, float2 a, float2 b, float2 c, float2 d, Sprite r, int palette, int nv) + public static void FastCreateQuad(Vertex[] vertices, float2 a, float2 b, float2 c, float2 d, Sprite r, float paletteTextureIndex, int nv) { - var attribP = palette / (float)HardwarePalette.MaxPalettes; var attribC = ChannelSelect[(int)r.Channel]; - vertices[nv] = new Vertex(a, r.Left, r.Top, attribP, attribC); - vertices[nv + 1] = new Vertex(b, r.Right, r.Top, attribP, attribC); - vertices[nv + 2] = new Vertex(c, r.Right, r.Bottom, attribP, attribC); - vertices[nv + 3] = new Vertex(d, r.Left, r.Bottom, attribP, attribC); + vertices[nv] = new Vertex(a, r.Left, r.Top, paletteTextureIndex, attribC); + vertices[nv + 1] = new Vertex(b, r.Right, r.Top, paletteTextureIndex, attribC); + vertices[nv + 2] = new Vertex(c, r.Right, r.Bottom, paletteTextureIndex, attribC); + vertices[nv + 3] = new Vertex(d, r.Left, r.Bottom, paletteTextureIndex, attribC); } public static void FastCopyIntoChannel(Sprite dest, byte[] src) { FastCopyIntoChannel(dest, 0, src); } diff --git a/OpenRA.Game/Graphics/VoxelRenderer.cs b/OpenRA.Game/Graphics/VoxelRenderer.cs index a070b0953e..8280effec9 100644 --- a/OpenRA.Game/Graphics/VoxelRenderer.cs +++ b/OpenRA.Game/Graphics/VoxelRenderer.cs @@ -203,11 +203,11 @@ namespace OpenRA.Graphics var lightDirection = ExtractRotationVector(Util.MatrixMultiply(Util.MatrixInverse(t), lightTransform)); Render(rd, Util.MatrixMultiply(transform, t), lightDirection, - lightAmbientColor, lightDiffuseColor, color.Index, normals.Index); + lightAmbientColor, lightDiffuseColor, color.TextureMidIndex, normals.TextureMidIndex); // Disable shadow normals by forcing zero diffuse and identity ambient light Render(rd, Util.MatrixMultiply(shadow, t), lightDirection, - ShadowAmbient, ShadowDiffuse, shadowPalette.Index, normals.Index); + ShadowAmbient, ShadowDiffuse, shadowPalette.TextureMidIndex, normals.TextureMidIndex); } } })); @@ -254,12 +254,10 @@ namespace OpenRA.Graphics VoxelRenderData renderData, float[] t, float[] lightDirection, float[] ambientLight, float[] diffuseLight, - int colorPalette, int normalsPalette) + float colorPaletteTextureMidIndex, float normalsPaletteTextureMidIndex) { shader.SetTexture("DiffuseTexture", renderData.Sheet.GetTexture()); - shader.SetVec("PaletteRows", - (colorPalette + 0.5f) / HardwarePalette.MaxPalettes, - (normalsPalette + 0.5f) / HardwarePalette.MaxPalettes); + shader.SetVec("PaletteRows", colorPaletteTextureMidIndex, normalsPaletteTextureMidIndex); shader.SetMatrix("TransformMatrix", t); shader.SetVec("LightDirection", lightDirection, 4); shader.SetVec("AmbientLight", ambientLight, 3); diff --git a/OpenRA.Game/Graphics/WorldRenderer.cs b/OpenRA.Game/Graphics/WorldRenderer.cs index f6058b3d62..3242c5c117 100644 --- a/OpenRA.Game/Graphics/WorldRenderer.cs +++ b/OpenRA.Game/Graphics/WorldRenderer.cs @@ -19,13 +19,17 @@ namespace OpenRA.Graphics public class PaletteReference { public readonly string Name; - public readonly int Index; public IPalette Palette { get; internal set; } - public PaletteReference(string name, int index, IPalette palette) + readonly float index; + readonly HardwarePalette hardwarePalette; + public float TextureIndex { get { return index / hardwarePalette.Height; } } + public float TextureMidIndex { get { return (index + 0.5f) / hardwarePalette.Height; } } + public PaletteReference(string name, int index, IPalette palette, HardwarePalette hardwarePalette) { Name = name; - Index = index; Palette = palette; + this.index = index; + this.hardwarePalette = hardwarePalette; } } @@ -62,7 +66,7 @@ namespace OpenRA.Graphics PaletteReference CreatePaletteReference(string name) { var pal = palette.GetPalette(name); - return new PaletteReference(name, palette.GetPaletteIndex(name), pal); + return new PaletteReference(name, palette.GetPaletteIndex(name), pal, palette); } public PaletteReference Palette(string name) { return palettes.GetOrAdd(name, CreatePaletteReference); }