Add CopyToArray method for IPalette.
By allowing a palette to be copied to an array, a speedup can be gained in HardwarePalette since palettes can be block copied using native magic rather than having to copy them item by item. We transpose the buffer in HardwarePalette in order to allow a contiguous block copy into this buffer, transposing again in the shader to keep everything correct.
This commit is contained in:
@@ -23,7 +23,7 @@ namespace OpenRA.Graphics
|
|||||||
readonly Dictionary<string, MutablePalette> modifiablePalettes = new Dictionary<string, MutablePalette>();
|
readonly Dictionary<string, MutablePalette> modifiablePalettes = new Dictionary<string, MutablePalette>();
|
||||||
readonly IReadOnlyDictionary<string, MutablePalette> readOnlyModifiablePalettes;
|
readonly IReadOnlyDictionary<string, MutablePalette> readOnlyModifiablePalettes;
|
||||||
readonly Dictionary<string, int> indices = new Dictionary<string, int>();
|
readonly Dictionary<string, int> indices = new Dictionary<string, int>();
|
||||||
readonly uint[,] buffer = new uint[Palette.Size, MaxPalettes];
|
readonly uint[,] buffer = new uint[MaxPalettes, Palette.Size];
|
||||||
|
|
||||||
public HardwarePalette()
|
public HardwarePalette()
|
||||||
{
|
{
|
||||||
@@ -85,8 +85,7 @@ namespace OpenRA.Graphics
|
|||||||
|
|
||||||
void CopyPaletteToBuffer(int index, IPalette p)
|
void CopyPaletteToBuffer(int index, IPalette p)
|
||||||
{
|
{
|
||||||
for (var i = 0; i < Palette.Size; i++)
|
p.CopyToArray(buffer, index * Palette.Size);
|
||||||
buffer[i, index] = p[i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CopyModifiablePalettesToBuffer()
|
void CopyModifiablePalettesToBuffer()
|
||||||
@@ -109,8 +108,7 @@ namespace OpenRA.Graphics
|
|||||||
{
|
{
|
||||||
var originalPalette = palettes[kvp.Key];
|
var originalPalette = palettes[kvp.Key];
|
||||||
var modifiedPalette = kvp.Value;
|
var modifiedPalette = kvp.Value;
|
||||||
for (var i = 0; i < Palette.Size; i++)
|
modifiedPalette.SetFromPalette(originalPalette);
|
||||||
modifiedPalette[i] = originalPalette[i];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Drawing.Imaging;
|
using System.Drawing.Imaging;
|
||||||
@@ -17,7 +18,11 @@ using System.Runtime.InteropServices;
|
|||||||
|
|
||||||
namespace OpenRA.Graphics
|
namespace OpenRA.Graphics
|
||||||
{
|
{
|
||||||
public interface IPalette { uint this[int index] { get; } }
|
public interface IPalette
|
||||||
|
{
|
||||||
|
uint this[int index] { get; }
|
||||||
|
void CopyToArray(Array destination, int destinationOffset);
|
||||||
|
}
|
||||||
public interface IPaletteRemap { Color GetRemappedColor(Color original, int index); }
|
public interface IPaletteRemap { Color GetRemappedColor(Color original, int index); }
|
||||||
|
|
||||||
public static class Palette
|
public static class Palette
|
||||||
@@ -52,8 +57,7 @@ namespace OpenRA.Graphics
|
|||||||
var data = b.LockBits(new Rectangle(0, 0, b.Width, b.Height),
|
var data = b.LockBits(new Rectangle(0, 0, b.Width, b.Height),
|
||||||
ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
|
ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
|
||||||
var temp = new uint[Palette.Size];
|
var temp = new uint[Palette.Size];
|
||||||
for (int i = 0; i < temp.Length; i++)
|
palette.CopyToArray(temp, 0);
|
||||||
temp[i] = palette[i];
|
|
||||||
Marshal.Copy((int[])(object)temp, 0, data.Scan0, Size);
|
Marshal.Copy((int[])(object)temp, 0, data.Scan0, Size);
|
||||||
b.UnlockBits(data);
|
b.UnlockBits(data);
|
||||||
return b;
|
return b;
|
||||||
@@ -71,6 +75,10 @@ namespace OpenRA.Graphics
|
|||||||
IPalette palette;
|
IPalette palette;
|
||||||
public ReadOnlyPalette(IPalette palette) { this.palette = palette; }
|
public ReadOnlyPalette(IPalette palette) { this.palette = palette; }
|
||||||
public uint this[int index] { get { return palette[index]; } }
|
public uint this[int index] { get { return palette[index]; } }
|
||||||
|
public void CopyToArray(Array destination, int destinationOffset)
|
||||||
|
{
|
||||||
|
palette.CopyToArray(destination, destinationOffset);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,6 +91,11 @@ namespace OpenRA.Graphics
|
|||||||
get { return colors[index]; }
|
get { return colors[index]; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void CopyToArray(Array destination, int destinationOffset)
|
||||||
|
{
|
||||||
|
Buffer.BlockCopy(colors, 0, destination, destinationOffset * 4, Palette.Size * 4);
|
||||||
|
}
|
||||||
|
|
||||||
public ImmutablePalette(string filename, int[] remap)
|
public ImmutablePalette(string filename, int[] remap)
|
||||||
{
|
{
|
||||||
using (var s = File.OpenRead(filename))
|
using (var s = File.OpenRead(filename))
|
||||||
@@ -141,10 +154,14 @@ namespace OpenRA.Graphics
|
|||||||
set { colors[index] = value; }
|
set { colors[index] = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void CopyToArray(Array destination, int destinationOffset)
|
||||||
|
{
|
||||||
|
Buffer.BlockCopy(colors, 0, destination, destinationOffset * 4, Palette.Size * 4);
|
||||||
|
}
|
||||||
|
|
||||||
public MutablePalette(IPalette p)
|
public MutablePalette(IPalette p)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < Palette.Size; i++)
|
SetFromPalette(p);
|
||||||
this[i] = p[i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetColor(int index, Color color)
|
public void SetColor(int index, Color color)
|
||||||
@@ -152,6 +169,11 @@ namespace OpenRA.Graphics
|
|||||||
colors[index] = (uint)color.ToArgb();
|
colors[index] = (uint)color.ToArgb();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetFromPalette(IPalette p)
|
||||||
|
{
|
||||||
|
p.CopyToArray(colors, 0);
|
||||||
|
}
|
||||||
|
|
||||||
public void ApplyRemap(IPaletteRemap r)
|
public void ApplyRemap(IPaletteRemap r)
|
||||||
{
|
{
|
||||||
for (var i = 0; i < Palette.Size; i++)
|
for (var i = 0; i < Palette.Size; i++)
|
||||||
|
|||||||
@@ -3,6 +3,6 @@ uniform sampler2D DiffuseTexture, Palette;
|
|||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
vec4 x = texture2D(DiffuseTexture, gl_TexCoord[0].st);
|
vec4 x = texture2D(DiffuseTexture, gl_TexCoord[0].st);
|
||||||
vec2 p = vec2(gl_TexCoord[0].p, dot(x, gl_TexCoord[1]));
|
vec2 p = vec2(dot(x, gl_TexCoord[1]), gl_TexCoord[0].p);
|
||||||
gl_FragColor = texture2D(Palette, p);
|
gl_FragColor = texture2D(Palette, p);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,11 +7,11 @@ uniform vec3 AmbientLight, DiffuseLight;
|
|||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
vec4 x = texture2D(DiffuseTexture, gl_TexCoord[0].st);
|
vec4 x = texture2D(DiffuseTexture, gl_TexCoord[0].st);
|
||||||
vec4 color = texture2D(Palette, vec2(PaletteRows.x, dot(x, gl_TexCoord[1])));
|
vec4 color = texture2D(Palette, vec2(dot(x, gl_TexCoord[1]), PaletteRows.x));
|
||||||
if (color.a < 0.01)
|
if (color.a < 0.01)
|
||||||
discard;
|
discard;
|
||||||
|
|
||||||
vec4 normal = (2.0 * texture2D(Palette, vec2(PaletteRows.y, dot(x, gl_TexCoord[2]))) - 1.0);
|
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);
|
vec3 intensity = AmbientLight + DiffuseLight * max(dot(normal, LightDirection), 0.0);
|
||||||
gl_FragColor = vec4(intensity * color.rgb, color.a);
|
gl_FragColor = vec4(intensity * color.rgb, color.a);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user