diff --git a/OpenRA.Game/Graphics/PaletteReference.cs b/OpenRA.Game/Graphics/PaletteReference.cs index 00e196e404..149687d1d7 100644 --- a/OpenRA.Game/Graphics/PaletteReference.cs +++ b/OpenRA.Game/Graphics/PaletteReference.cs @@ -13,19 +13,17 @@ namespace OpenRA.Graphics { public sealed class PaletteReference { - readonly float index; readonly HardwarePalette hardwarePalette; public readonly string Name; public IPalette Palette { get; internal set; } - public float TextureIndex => index / hardwarePalette.Height; - public float TextureMidIndex => (index + 0.5f) / hardwarePalette.Height; + public int TextureIndex { get; } public PaletteReference(string name, int index, IPalette palette, HardwarePalette hardwarePalette) { Name = name; Palette = palette; - this.index = index; + TextureIndex = index; this.hardwarePalette = hardwarePalette; } diff --git a/OpenRA.Game/Graphics/PlatformInterfaces.cs b/OpenRA.Game/Graphics/PlatformInterfaces.cs index b7fbc59a6d..f11fa66fe6 100644 --- a/OpenRA.Game/Graphics/PlatformInterfaces.cs +++ b/OpenRA.Game/Graphics/PlatformInterfaces.cs @@ -107,7 +107,7 @@ namespace OpenRA { void BeginFrame(); void EndFrame(); - void SetPalette(ITexture palette); + void SetPalette(HardwarePalette palette); } public interface IVertexBuffer : IDisposable where T : struct diff --git a/OpenRA.Game/Graphics/SpriteRenderer.cs b/OpenRA.Game/Graphics/SpriteRenderer.cs index 9ac831ba11..3b07b35639 100644 --- a/OpenRA.Game/Graphics/SpriteRenderer.cs +++ b/OpenRA.Game/Graphics/SpriteRenderer.cs @@ -115,7 +115,7 @@ namespace OpenRA.Graphics return new int2(sheetIndex, secondarySheetIndex); } - static float ResolveTextureIndex(Sprite s, PaletteReference pal) + static int ResolveTextureIndex(Sprite s, PaletteReference pal) { if (pal == null) return 0; @@ -129,7 +129,7 @@ namespace OpenRA.Graphics return pal.TextureIndex; } - internal void DrawSprite(Sprite s, float paletteTextureIndex, in float3 location, in float3 scale, float rotation = 0f) + internal void DrawSprite(Sprite s, int paletteTextureIndex, in float3 location, in float3 scale, float rotation = 0f) { var samplers = SetRenderStateForSprite(s); Util.FastCreateQuad(vertices, location + scale * s.Offset, s, samplers, paletteTextureIndex, vertexCount, scale * s.Size, float3.Ones, @@ -137,7 +137,7 @@ namespace OpenRA.Graphics vertexCount += 4; } - internal void DrawSprite(Sprite s, float paletteTextureIndex, in float3 location, float scale, float rotation = 0f) + internal void DrawSprite(Sprite s, int paletteTextureIndex, in float3 location, float scale, float rotation = 0f) { var samplers = SetRenderStateForSprite(s); Util.FastCreateQuad(vertices, location + scale * s.Offset, s, samplers, paletteTextureIndex, vertexCount, scale * s.Size, float3.Ones, @@ -150,7 +150,7 @@ namespace OpenRA.Graphics DrawSprite(s, ResolveTextureIndex(s, pal), location, scale, rotation); } - internal void DrawSprite(Sprite s, float paletteTextureIndex, in float3 location, float scale, in float3 tint, float alpha, + internal void DrawSprite(Sprite s, int paletteTextureIndex, in float3 location, float scale, in float3 tint, float alpha, float rotation = 0f) { var samplers = SetRenderStateForSprite(s); @@ -165,7 +165,7 @@ namespace OpenRA.Graphics DrawSprite(s, ResolveTextureIndex(s, pal), location, scale, tint, alpha, rotation); } - internal void DrawSprite(Sprite s, float paletteTextureIndex, in float3 a, in float3 b, in float3 c, in float3 d, in float3 tint, float alpha) + internal void DrawSprite(Sprite s, int paletteTextureIndex, in float3 a, in float3 b, in float3 c, in float3 d, in float3 tint, float alpha) { var samplers = SetRenderStateForSprite(s); Util.FastCreateQuad(vertices, a, b, c, d, s, samplers, paletteTextureIndex, tint, alpha, vertexCount); @@ -210,10 +210,11 @@ namespace OpenRA.Graphics vertexCount += 4; } - public void SetPalette(ITexture palette, ITexture colorShifts) + public void SetPalette(HardwarePalette palette) { - shader.SetTexture("Palette", palette); - shader.SetTexture("ColorShifts", colorShifts); + shader.SetTexture("Palette", palette.Texture); + shader.SetTexture("ColorShifts", palette.ColorShifts); + shader.SetVec("PaletteRows", palette.Height); } public void SetViewportParams(Size sheetSize, int downscale, float depthMargin, int2 scroll) diff --git a/OpenRA.Game/Graphics/Util.cs b/OpenRA.Game/Graphics/Util.cs index e72d9e9c37..d08ec8191e 100644 --- a/OpenRA.Game/Graphics/Util.cs +++ b/OpenRA.Game/Graphics/Util.cs @@ -30,7 +30,7 @@ namespace OpenRA.Graphics return indices; } - public static void FastCreateQuad(Vertex[] vertices, in float3 o, Sprite r, int2 samplers, float paletteTextureIndex, int nv, + public static void FastCreateQuad(Vertex[] vertices, in float3 o, Sprite r, int2 samplers, int paletteTextureIndex, int nv, in float3 size, in float3 tint, float alpha, float rotation = 0f) { float3 a, b, c, d; @@ -72,7 +72,7 @@ namespace OpenRA.Graphics public static void FastCreateQuad(Vertex[] vertices, in float3 a, in float3 b, in float3 c, in float3 d, - Sprite r, int2 samplers, float paletteTextureIndex, + Sprite r, int2 samplers, int paletteTextureIndex, in float3 tint, float alpha, int nv) { float sl = 0; diff --git a/OpenRA.Game/Renderer.cs b/OpenRA.Game/Renderer.cs index b317bc1b1f..313cc21ac2 100644 --- a/OpenRA.Game/Renderer.cs +++ b/OpenRA.Game/Renderer.cs @@ -303,11 +303,11 @@ namespace OpenRA Flush(); currentPaletteTexture = palette.Texture; - SpriteRenderer.SetPalette(currentPaletteTexture, palette.ColorShifts); - WorldSpriteRenderer.SetPalette(currentPaletteTexture, palette.ColorShifts); + SpriteRenderer.SetPalette(palette); + WorldSpriteRenderer.SetPalette(palette); foreach (var r in WorldRenderers) - r.SetPalette(currentPaletteTexture); + r.SetPalette(palette); } public void EndFrame(IInputHandler inputHandler) diff --git a/OpenRA.Mods.Cnc/Traits/World/ModelRenderer.cs b/OpenRA.Mods.Cnc/Traits/World/ModelRenderer.cs index 7bd6c98753..57d6a66c4e 100644 --- a/OpenRA.Mods.Cnc/Traits/World/ModelRenderer.cs +++ b/OpenRA.Mods.Cnc/Traits/World/ModelRenderer.cs @@ -65,9 +65,10 @@ namespace OpenRA.Mods.Cnc.Traits SheetBuilder sheetBuilderForFrame; bool isInFrame; - public void SetPalette(ITexture palette) + public void SetPalette(HardwarePalette palette) { - shader.SetTexture("Palette", palette); + shader.SetTexture("Palette", palette.Texture); + shader.SetVec("PaletteRows", palette.Height); } public ModelRenderer(ModelRendererInfo info, Actor self) @@ -226,12 +227,12 @@ namespace OpenRA.Mods.Cnc.Traits var lightDirection = ExtractRotationVector(Util.MatrixMultiply(it, lightTransform)); Render(rd, ModelCache, Util.MatrixMultiply(transform, t), lightDirection, - lightAmbientColor, lightDiffuseColor, color.TextureMidIndex, normals.TextureMidIndex); + lightAmbientColor, lightDiffuseColor, color.TextureIndex, normals.TextureIndex); // Disable shadow normals by forcing zero diffuse and identity ambient light if (m.ShowShadow) Render(rd, ModelCache, Util.MatrixMultiply(shadow, t), lightDirection, - ShadowAmbient, ShadowDiffuse, shadowPalette.TextureMidIndex, normals.TextureMidIndex); + ShadowAmbient, ShadowDiffuse, shadowPalette.TextureIndex, normals.TextureIndex); } } })); @@ -279,10 +280,10 @@ namespace OpenRA.Mods.Cnc.Traits IModelCache cache, float[] t, float[] lightDirection, float[] ambientLight, float[] diffuseLight, - float colorPaletteTextureMidIndex, float normalsPaletteTextureMidIndex) + float colorPaletteTextureIndex, float normalsPaletteTextureIndex) { shader.SetTexture("DiffuseTexture", renderData.Sheet.GetTexture()); - shader.SetVec("PaletteRows", colorPaletteTextureMidIndex, normalsPaletteTextureMidIndex); + shader.SetVec("Palettes", colorPaletteTextureIndex, normalsPaletteTextureIndex); shader.SetMatrix("TransformMatrix", t); shader.SetVec("LightDirection", lightDirection, 4); shader.SetVec("AmbientLight", ambientLight, 3); diff --git a/glsl/combined.frag b/glsl/combined.frag index 4cf1f9731f..bb629b7e5b 100644 --- a/glsl/combined.frag +++ b/glsl/combined.frag @@ -22,7 +22,7 @@ uniform float AntialiasPixelsPerTexel; in vec4 vColor; in vec4 vTexCoord; -in vec2 vTexMetadata; +in float vTexPalette; in vec4 vChannelMask; in vec4 vDepthMask; in vec2 vTexSampler; @@ -129,10 +129,10 @@ vec4 SamplePalettedBilinear(float samplerIndex, vec2 coords, vec2 textureSize) vec4 x3 = Sample(samplerIndex, tl + vec2(0., px.y)); vec4 x4 = Sample(samplerIndex, tl + px); - vec4 c1 = texture(Palette, vec2(dot(x1, vChannelMask), vTexMetadata.s)); - vec4 c2 = texture(Palette, vec2(dot(x2, vChannelMask), vTexMetadata.s)); - vec4 c3 = texture(Palette, vec2(dot(x3, vChannelMask), vTexMetadata.s)); - vec4 c4 = texture(Palette, vec2(dot(x4, vChannelMask), vTexMetadata.s)); + vec4 c1 = texture(Palette, vec2(dot(x1, vChannelMask), vTexPalette)); + vec4 c2 = texture(Palette, vec2(dot(x2, vChannelMask), vTexPalette)); + vec4 c3 = texture(Palette, vec2(dot(x3, vChannelMask), vTexPalette)); + vec4 c4 = texture(Palette, vec2(dot(x4, vChannelMask), vTexPalette)); return mix(mix(c1, c2, interp.x), mix(c3, c4, interp.x), interp.y); } @@ -174,7 +174,7 @@ void main() if (!(AntialiasPixelsPerTexel > 0.0 && vPalettedFraction.x > 0.0)) { vec4 x = Sample(vTexSampler.s, coords); - vec2 p = vec2(dot(x, vChannelMask), vTexMetadata.s); + vec2 p = vec2(dot(x, vChannelMask), vTexPalette); c = vPalettedFraction * texture(Palette, p) + vRGBAFraction * x + vColorFraction * vTexCoord; } @@ -182,8 +182,8 @@ void main() if (c.a == 0.0) discard; - if (vRGBAFraction.r > 0.0 && vTexMetadata.s > 0.0) - c = ColorShift(c, vTexMetadata.s); + if (vRGBAFraction.r > 0.0 && vTexPalette > 0.0) + c = ColorShift(c, vTexPalette); float depth = gl_FragCoord.z; if (length(vDepthMask) > 0.0) diff --git a/glsl/combined.vert b/glsl/combined.vert index 7edb84c3cc..b78058137a 100644 --- a/glsl/combined.vert +++ b/glsl/combined.vert @@ -2,6 +2,7 @@ uniform vec3 Scroll; uniform vec3 p1, p2; +uniform float PaletteRows; in vec3 aVertexPosition; in vec4 aVertexTexCoord; @@ -9,7 +10,7 @@ in vec2 aVertexTexMetadata; in vec4 aVertexTint; out vec4 vTexCoord; -out vec2 vTexMetadata; +out float vTexPalette; out vec4 vChannelMask; out vec4 vDepthMask; out vec2 vTexSampler; @@ -100,7 +101,7 @@ void main() { gl_Position = vec4((aVertexPosition - Scroll) * p1 + p2, 1); vTexCoord = aVertexTexCoord; - vTexMetadata = aVertexTexMetadata; + vTexPalette = aVertexTexMetadata.s / PaletteRows; vec4 attrib = UnpackChannelAttributes(aVertexTexMetadata.t); vChannelMask = SelectChannelMask(attrib.s); diff --git a/glsl/model.frag b/glsl/model.frag index ce3e744c27..b1f016c248 100644 --- a/glsl/model.frag +++ b/glsl/model.frag @@ -4,7 +4,8 @@ precision mediump float; #endif uniform sampler2D Palette, DiffuseTexture; -uniform vec2 PaletteRows; +uniform vec2 Palettes; +uniform float PaletteRows; uniform vec4 LightDirection; uniform vec3 AmbientLight, DiffuseLight; @@ -17,12 +18,12 @@ out vec4 fragColor; void main() { vec4 x = texture(DiffuseTexture, vTexCoord.st); - vec4 color = texture(Palette, vec2(dot(x, vChannelMask), PaletteRows.x)); + vec4 color = texture(Palette, vec2(dot(x, vChannelMask), (Palettes.x + 0.5) / PaletteRows)); if (color.a < 0.01) discard; vec4 y = texture(DiffuseTexture, vTexCoord.pq); - vec4 normal = (2.0 * texture(Palette, vec2(dot(y, vNormalsMask), PaletteRows.y)) - 1.0); + vec4 normal = (2.0 * texture(Palette, vec2(dot(y, vNormalsMask), (Palettes.y + 0.5) / PaletteRows)) - 1.0); vec3 intensity = AmbientLight + DiffuseLight * max(dot(normal, LightDirection), 0.0); fragColor = vec4(intensity * color.rgb, color.a); }