diff --git a/OpenRA.Game/Graphics/RgbaColorRenderer.cs b/OpenRA.Game/Graphics/RgbaColorRenderer.cs index 17650f6ee2..422b4f7a8e 100644 --- a/OpenRA.Game/Graphics/RgbaColorRenderer.cs +++ b/OpenRA.Game/Graphics/RgbaColorRenderer.cs @@ -16,44 +16,20 @@ using System.Linq; namespace OpenRA.Graphics { - public class RgbaColorRenderer : Renderer.IBatchRenderer + public class RgbaColorRenderer { static readonly float2 Offset = new float2(0.5f, 0.5f); - readonly Renderer renderer; - readonly IShader shader; - readonly Action renderAction; + readonly SpriteRenderer parent; + readonly Vertex[] vertices = new Vertex[6]; - readonly Vertex[] vertices; - int nv = 0; - - public RgbaColorRenderer(Renderer renderer, IShader shader) + public RgbaColorRenderer(SpriteRenderer parent) { - this.renderer = renderer; - this.shader = shader; - vertices = new Vertex[renderer.TempBufferSize]; - renderAction = () => renderer.DrawBatch(vertices, nv, PrimitiveType.TriangleList); - } - - public void Flush() - { - if (nv > 0) - { - renderer.Device.SetBlendMode(BlendMode.Alpha); - shader.Render(renderAction); - renderer.Device.SetBlendMode(BlendMode.None); - - nv = 0; - } + this.parent = parent; } public void DrawLine(float3 start, float3 end, float width, Color startColor, Color endColor) { - renderer.CurrentBatchRenderer = this; - - if (nv + 6 > renderer.TempBufferSize) - Flush(); - var delta = (end - start) / (end - start).XY.Length; var corner = width / 2 * new float3(-delta.Y, delta.X, delta.Z); @@ -69,21 +45,18 @@ namespace OpenRA.Graphics var eb = endColor.B / 255.0f; var ea = endColor.A / 255.0f; - vertices[nv++] = new Vertex(start - corner + Offset, sr, sg, sb, sa, 0, 0); - vertices[nv++] = new Vertex(start + corner + Offset, sr, sg, sb, sa, 0, 0); - vertices[nv++] = new Vertex(end + corner + Offset, er, eg, eb, ea, 0, 0); - vertices[nv++] = new Vertex(end + corner + Offset, er, eg, eb, ea, 0, 0); - vertices[nv++] = new Vertex(end - corner + Offset, er, eg, eb, ea, 0, 0); - vertices[nv++] = new Vertex(start - corner + Offset, sr, sg, sb, sa, 0, 0); + vertices[0] = new Vertex(start - corner + Offset, sr, sg, sb, sa, 0, 0); + vertices[1] = new Vertex(start + corner + Offset, sr, sg, sb, sa, 0, 0); + vertices[2] = new Vertex(end + corner + Offset, er, eg, eb, ea, 0, 0); + vertices[3] = new Vertex(end + corner + Offset, er, eg, eb, ea, 0, 0); + vertices[4] = new Vertex(end - corner + Offset, er, eg, eb, ea, 0, 0); + vertices[5] = new Vertex(start - corner + Offset, sr, sg, sb, sa, 0, 0); + + parent.DrawRGBAVertices(vertices); } public void DrawLine(float3 start, float3 end, float width, Color color) { - renderer.CurrentBatchRenderer = this; - - if (nv + 6 > renderer.TempBufferSize) - Flush(); - var delta = (end - start) / (end - start).XY.Length; var corner = width / 2 * new float2(-delta.Y, delta.X); @@ -93,12 +66,13 @@ namespace OpenRA.Graphics var b = color.B / 255.0f; var a = color.A / 255.0f; - vertices[nv++] = new Vertex(start - corner + Offset, r, g, b, a, 0, 0); - vertices[nv++] = new Vertex(start + corner + Offset, r, g, b, a, 0, 0); - vertices[nv++] = new Vertex(end + corner + Offset, r, g, b, a, 0, 0); - vertices[nv++] = new Vertex(end + corner + Offset, r, g, b, a, 0, 0); - vertices[nv++] = new Vertex(end - corner + Offset, r, g, b, a, 0, 0); - vertices[nv++] = new Vertex(start - corner + Offset, r, g, b, a, 0, 0); + vertices[0] = new Vertex(start - corner + Offset, r, g, b, a, 0, 0); + vertices[1] = new Vertex(start + corner + Offset, r, g, b, a, 0, 0); + vertices[2] = new Vertex(end + corner + Offset, r, g, b, a, 0, 0); + vertices[3] = new Vertex(end + corner + Offset, r, g, b, a, 0, 0); + vertices[4] = new Vertex(end - corner + Offset, r, g, b, a, 0, 0); + vertices[5] = new Vertex(start - corner + Offset, r, g, b, a, 0, 0); + parent.DrawRGBAVertices(vertices); } /// @@ -146,7 +120,6 @@ namespace OpenRA.Graphics return; } - renderer.CurrentBatchRenderer = this; color = Util.PremultiplyAlpha(color); var r = color.R / 255.0f; var g = color.G / 255.0f; @@ -184,15 +157,13 @@ namespace OpenRA.Graphics var cd = closed || i < limit ? IntersectionOf(end - corner, dir, end - nextCorner, nextDir) : end - corner; // Fill segment - if (nv + 6 > renderer.TempBufferSize) - Flush(); - - vertices[nv++] = new Vertex(ca + Offset, r, g, b, a, 0, 0); - vertices[nv++] = new Vertex(cb + Offset, r, g, b, a, 0, 0); - vertices[nv++] = new Vertex(cc + Offset, r, g, b, a, 0, 0); - vertices[nv++] = new Vertex(cc + Offset, r, g, b, a, 0, 0); - vertices[nv++] = new Vertex(cd + Offset, r, g, b, a, 0, 0); - vertices[nv++] = new Vertex(ca + Offset, r, g, b, a, 0, 0); + vertices[0] = new Vertex(ca + Offset, r, g, b, a, 0, 0); + vertices[1] = new Vertex(cb + Offset, r, g, b, a, 0, 0); + vertices[2] = new Vertex(cc + Offset, r, g, b, a, 0, 0); + vertices[3] = new Vertex(cc + Offset, r, g, b, a, 0, 0); + vertices[4] = new Vertex(cd + Offset, r, g, b, a, 0, 0); + vertices[5] = new Vertex(ca + Offset, r, g, b, a, 0, 0); + parent.DrawRGBAVertices(vertices); // Advance line segment end = next; @@ -238,23 +209,19 @@ namespace OpenRA.Graphics public void FillRect(float3 a, float3 b, float3 c, float3 d, Color color) { - renderer.CurrentBatchRenderer = this; - - if (nv + 6 > renderer.TempBufferSize) - Flush(); - color = Util.PremultiplyAlpha(color); var cr = color.R / 255.0f; var cg = color.G / 255.0f; var cb = color.B / 255.0f; var ca = color.A / 255.0f; - vertices[nv++] = new Vertex(a + Offset, cr, cg, cb, ca, 0, 0); - vertices[nv++] = new Vertex(b + Offset, cr, cg, cb, ca, 0, 0); - vertices[nv++] = new Vertex(c + Offset, cr, cg, cb, ca, 0, 0); - vertices[nv++] = new Vertex(c + Offset, cr, cg, cb, ca, 0, 0); - vertices[nv++] = new Vertex(d + Offset, cr, cg, cb, ca, 0, 0); - vertices[nv++] = new Vertex(a + Offset, cr, cg, cb, ca, 0, 0); + vertices[0] = new Vertex(a + Offset, cr, cg, cb, ca, 0, 0); + vertices[1] = new Vertex(b + Offset, cr, cg, cb, ca, 0, 0); + vertices[2] = new Vertex(c + Offset, cr, cg, cb, ca, 0, 0); + vertices[3] = new Vertex(c + Offset, cr, cg, cb, ca, 0, 0); + vertices[4] = new Vertex(d + Offset, cr, cg, cb, ca, 0, 0); + vertices[5] = new Vertex(a + Offset, cr, cg, cb, ca, 0, 0); + parent.DrawRGBAVertices(vertices); } public void FillEllipse(float3 tl, float3 br, Color color, int vertices = 32) @@ -271,20 +238,5 @@ namespace OpenRA.Graphics DrawLine(new float3(xc - dx, y, z), new float3(xc + dx, y, z), 1, color); } } - - public void SetViewportParams(Size screen, float depthScale, float depthOffset, float zoom, int2 scroll) - { - shader.SetVec("Scroll", scroll.X, scroll.Y, scroll.Y); - shader.SetVec("r1", - zoom * 2f / screen.Width, - -zoom * 2f / screen.Height, - -depthScale * zoom / screen.Height); - shader.SetVec("r2", -1, 1, 1 - depthOffset); - } - - public void SetDepthPreviewEnabled(bool enabled) - { - shader.SetBool("EnableDepthPreview", enabled); - } } } diff --git a/OpenRA.Game/Graphics/SpriteRenderer.cs b/OpenRA.Game/Graphics/SpriteRenderer.cs index 76b4413b46..4b29b19967 100644 --- a/OpenRA.Game/Graphics/SpriteRenderer.cs +++ b/OpenRA.Game/Graphics/SpriteRenderer.cs @@ -37,7 +37,8 @@ namespace OpenRA.Graphics { if (nv > 0) { - shader.SetTexture("DiffuseTexture", currentSheet.GetTexture()); + if (currentSheet != null) + shader.SetTexture("DiffuseTexture", currentSheet.GetTexture()); renderer.Device.SetBlendMode(currentBlend); shader.Render(renderAction); @@ -109,6 +110,19 @@ namespace OpenRA.Graphics renderer.Device.SetBlendMode(BlendMode.None); } + // For RGBAColorRenderer + internal void DrawRGBAVertices(Vertex[] v) + { + renderer.CurrentBatchRenderer = this; + + if (currentBlend != BlendMode.Alpha || nv + v.Length > renderer.TempBufferSize) + Flush(); + + currentBlend = BlendMode.Alpha; + Array.Copy(v, 0, vertices, nv, v.Length); + nv += v.Length; + } + public void SetPalette(ITexture palette) { shader.SetTexture("Palette", palette); diff --git a/OpenRA.Game/Graphics/WorldRenderer.cs b/OpenRA.Game/Graphics/WorldRenderer.cs index 508738266f..148110c460 100644 --- a/OpenRA.Game/Graphics/WorldRenderer.cs +++ b/OpenRA.Game/Graphics/WorldRenderer.cs @@ -167,7 +167,6 @@ namespace OpenRA.Graphics { Game.Renderer.WorldSpriteRenderer.SetDepthPreviewEnabled(debugVis.Value.DepthBuffer); Game.Renderer.WorldRgbaSpriteRenderer.SetDepthPreviewEnabled(debugVis.Value.DepthBuffer); - Game.Renderer.WorldRgbaColorRenderer.SetDepthPreviewEnabled(debugVis.Value.DepthBuffer); } RefreshPalette(); diff --git a/OpenRA.Game/Renderer.cs b/OpenRA.Game/Renderer.cs index 30b0891a64..330603a8b5 100644 --- a/OpenRA.Game/Renderer.cs +++ b/OpenRA.Game/Renderer.cs @@ -58,11 +58,11 @@ namespace OpenRA WorldSpriteRenderer = new SpriteRenderer(this, Device.CreateShader("shp")); WorldRgbaSpriteRenderer = new SpriteRenderer(this, Device.CreateShader("rgba")); - WorldRgbaColorRenderer = new RgbaColorRenderer(this, Device.CreateShader("color")); + WorldRgbaColorRenderer = new RgbaColorRenderer(WorldSpriteRenderer); WorldModelRenderer = new ModelRenderer(this, Device.CreateShader("model")); - RgbaColorRenderer = new RgbaColorRenderer(this, Device.CreateShader("color")); - RgbaSpriteRenderer = new SpriteRenderer(this, Device.CreateShader("rgba")); SpriteRenderer = new SpriteRenderer(this, Device.CreateShader("shp")); + RgbaSpriteRenderer = new SpriteRenderer(this, Device.CreateShader("rgba")); + RgbaColorRenderer = new RgbaColorRenderer(SpriteRenderer); tempBuffer = Device.CreateVertexBuffer(TempBufferSize); } @@ -126,7 +126,6 @@ namespace OpenRA lastResolution = Resolution; RgbaSpriteRenderer.SetViewportParams(Resolution, 0f, 0f, 1f, int2.Zero); SpriteRenderer.SetViewportParams(Resolution, 0f, 0f, 1f, int2.Zero); - RgbaColorRenderer.SetViewportParams(Resolution, 0f, 0f, 1f, int2.Zero); } // If zoom evaluates as different due to floating point weirdness that's OK, setting the parameters again is harmless. @@ -137,7 +136,6 @@ namespace OpenRA WorldRgbaSpriteRenderer.SetViewportParams(Resolution, depthScale, depthOffset, zoom, scroll); WorldSpriteRenderer.SetViewportParams(Resolution, depthScale, depthOffset, zoom, scroll); WorldModelRenderer.SetViewportParams(Resolution, zoom, scroll); - WorldRgbaColorRenderer.SetViewportParams(Resolution, depthScale, depthOffset, zoom, scroll); } } diff --git a/glsl/color.frag b/glsl/color.frag deleted file mode 100644 index c84c7e1aba..0000000000 --- a/glsl/color.frag +++ /dev/null @@ -1,36 +0,0 @@ -varying vec4 vColor; -uniform bool EnableDepthPreview; - -float jet_r(float x) -{ - return x < 0.7 ? 4.0 * x - 1.5 : -4.0 * x + 4.5; -} - -float jet_g(float x) -{ - return x < 0.5 ? 4.0 * x - 0.5 : -4.0 * x + 3.5; -} - -float jet_b(float x) -{ - return x < 0.3 ? 4.0 * x + 0.5 : -4.0 * x + 2.5; -} - -void main() -{ - float depth = gl_FragCoord.z; - - // Convert to window coords - gl_FragDepth = 0.5 * depth + 0.5; - - if (EnableDepthPreview) - { - float x = 1.0 - gl_FragDepth; - float r = clamp(jet_r(x), 0.0, 1.0); - float g = clamp(jet_g(x), 0.0, 1.0); - float b = clamp(jet_b(x), 0.0, 1.0); - gl_FragColor = vec4(r, g, b, 1.0); - } - else - gl_FragColor = vColor; -} \ No newline at end of file diff --git a/glsl/color.vert b/glsl/color.vert deleted file mode 100644 index 724cc38c0e..0000000000 --- a/glsl/color.vert +++ /dev/null @@ -1,12 +0,0 @@ -uniform vec3 Scroll; -uniform vec3 r1, r2; - -attribute vec4 aVertexPosition; -attribute vec4 aVertexTexCoord; -varying vec4 vColor; - -void main() -{ - gl_Position = vec4((aVertexPosition.xyz - Scroll.xyz) * r1 + r2, 1); - vColor = aVertexTexCoord; -} diff --git a/glsl/shp.frag b/glsl/shp.frag index aa16bc3196..c40e312057 100644 --- a/glsl/shp.frag +++ b/glsl/shp.frag @@ -7,6 +7,7 @@ varying vec4 vTexCoord; varying vec2 vTexMetadata; varying vec4 vChannelMask; varying vec4 vDepthMask; +varying vec4 vColorFraction; float jet_r(float x) { @@ -27,7 +28,7 @@ void main() { vec4 x = texture2D(DiffuseTexture, vTexCoord.st); vec2 p = vec2(dot(x, vChannelMask), vTexMetadata.s); - vec4 c = texture2D(Palette, p); + vec4 c = (vec4(1, 1, 1, 1) - vColorFraction) * texture2D(Palette, p) + vColorFraction * vTexCoord; // Discard any transparent fragments (both color and depth) if (c.a == 0.0) diff --git a/glsl/shp.vert b/glsl/shp.vert index 87c0ca1b62..b245dbbdb9 100644 --- a/glsl/shp.vert +++ b/glsl/shp.vert @@ -8,6 +8,7 @@ varying vec4 vTexCoord; varying vec2 vTexMetadata; varying vec4 vChannelMask; varying vec4 vDepthMask; +varying vec4 vColorFraction; vec4 DecodeChannelMask(float x) { @@ -17,8 +18,18 @@ vec4 DecodeChannelMask(float x) return vec4(0,0,1,0); if (x > 0.3) return vec4(0,1,0,0); - else + if (x > 0.0) return vec4(1,0,0,0); + + return vec4(0, 0, 0, 0); +} + +vec4 DecodeColorFraction(float x) +{ + if (x > 0.0) + return vec4(0, 0, 0, 0); + else + return vec4(1, 1, 1, 1); } void main() @@ -27,6 +38,7 @@ void main() vTexCoord = aVertexTexCoord; vTexMetadata = aVertexTexMetadata; vChannelMask = DecodeChannelMask(abs(aVertexTexMetadata.t)); + vColorFraction = DecodeColorFraction(abs(aVertexTexMetadata.t)); if (aVertexTexMetadata.t < 0.0) { float x = -aVertexTexMetadata.t * 10.0;