diff --git a/OpenRA.Game/Graphics/LineRenderer.cs b/OpenRA.Game/Graphics/LineRenderer.cs index 2c55a8dfd3..6ed142fdcc 100644 --- a/OpenRA.Game/Graphics/LineRenderer.cs +++ b/OpenRA.Game/Graphics/LineRenderer.cs @@ -9,6 +9,7 @@ #endregion using System; +using System.Collections.Generic; using System.Drawing; namespace OpenRA.Graphics @@ -69,10 +70,25 @@ namespace OpenRA.Graphics { var tr = new float2(br.X, tl.Y); var bl = new float2(tl.X, br.Y); - DrawLine(tl, tr, c, c); - DrawLine(tl, bl, c, c); - DrawLine(tr, br, c, c); - DrawLine(bl, br, c, c); + DrawLine(tl, tr, c); + DrawLine(tl, bl, c); + DrawLine(tr, br, c); + DrawLine(bl, br, c); + } + + public void DrawLine(float2 start, float2 end, Color color) + { + renderer.CurrentBatchRenderer = this; + + if (nv + 2 > renderer.TempBufferSize) + Flush(); + + var r = color.R / 255.0f; + var g = color.G / 255.0f; + var b = color.B / 255.0f; + var a = color.A / 255.0f; + vertices[nv++] = new Vertex(start + Offset, r, g, b, a); + vertices[nv++] = new Vertex(end + Offset, r, g, b, a); } public void DrawLine(float2 start, float2 end, Color startColor, Color endColor) @@ -82,19 +98,52 @@ namespace OpenRA.Graphics if (nv + 2 > renderer.TempBufferSize) Flush(); - vertices[nv++] = new Vertex(start + Offset, - startColor.R / 255.0f, startColor.G / 255.0f, - startColor.B / 255.0f, startColor.A / 255.0f); + var r = startColor.R / 255.0f; + var g = startColor.G / 255.0f; + var b = startColor.B / 255.0f; + var a = startColor.A / 255.0f; + vertices[nv++] = new Vertex(start + Offset, r, g, b, a); - vertices[nv++] = new Vertex(end + Offset, - endColor.R / 255.0f, endColor.G / 255.0f, - endColor.B / 255.0f, endColor.A / 255.0f); + r = endColor.R / 255.0f; + g = endColor.G / 255.0f; + b = endColor.B / 255.0f; + a = endColor.A / 255.0f; + vertices[nv++] = new Vertex(end + Offset, r, g, b, a); + } + + public void DrawLineStrip(IEnumerable points, Color color) + { + renderer.CurrentBatchRenderer = this; + + var r = color.R / 255.0f; + var g = color.G / 255.0f; + var b = color.B / 255.0f; + var a = color.A / 255.0f; + + var first = true; + var prev = new Vertex(); + foreach (var point in points) + { + if (first) + { + first = false; + prev = new Vertex(point + Offset, r, g, b, a); + continue; + } + + if (nv + 2 > renderer.TempBufferSize) + Flush(); + + vertices[nv++] = prev; + prev = new Vertex(point + Offset, r, g, b, a); + vertices[nv++] = prev; + } } public void FillRect(RectangleF r, Color color) { for (var y = r.Top; y < r.Bottom; y++) - DrawLine(new float2(r.Left, y), new float2(r.Right, y), color, color); + DrawLine(new float2(r.Left, y), new float2(r.Right, y), color); } public void FillEllipse(RectangleF r, Color color) @@ -106,7 +155,7 @@ namespace OpenRA.Graphics for (var y = r.Top; y <= r.Bottom; y++) { var dx = a * (float)Math.Sqrt(1 - (y - yc) * (y - yc) / b / b); - DrawLine(new float2(xc - dx, y), new float2(xc + dx, y), color, color); + DrawLine(new float2(xc - dx, y), new float2(xc + dx, y), color); } } diff --git a/OpenRA.Game/Graphics/SelectionBarsRenderable.cs b/OpenRA.Game/Graphics/SelectionBarsRenderable.cs index 4d86850a25..a297a14e35 100644 --- a/OpenRA.Game/Graphics/SelectionBarsRenderable.cs +++ b/OpenRA.Game/Graphics/SelectionBarsRenderable.cs @@ -65,13 +65,13 @@ namespace OpenRA.Graphics var z = float2.Lerp(start, end, value); var wlr = Game.Renderer.WorldLineRenderer; - wlr.DrawLine(start + p, end + p, c, c); - wlr.DrawLine(start + q, end + q, c2, c2); - wlr.DrawLine(start + r, end + r, c, c); + wlr.DrawLine(start + p, end + p, c); + wlr.DrawLine(start + q, end + q, c2); + wlr.DrawLine(start + r, end + r, c); - wlr.DrawLine(start + p, z + p, barColor2, barColor2); - wlr.DrawLine(start + q, z + q, barColor, barColor); - wlr.DrawLine(start + r, z + r, barColor2, barColor2); + wlr.DrawLine(start + p, z + p, barColor2); + wlr.DrawLine(start + q, z + q, barColor); + wlr.DrawLine(start + r, z + r, barColor2); } Color GetHealthColor(Health health) @@ -125,13 +125,13 @@ namespace OpenRA.Graphics var z = float2.Lerp(start, end, (float)health.HP / health.MaxHP); var wlr = Game.Renderer.WorldLineRenderer; - wlr.DrawLine(start + p, end + p, c, c); - wlr.DrawLine(start + q, end + q, c2, c2); - wlr.DrawLine(start + r, end + r, c, c); + wlr.DrawLine(start + p, end + p, c); + wlr.DrawLine(start + q, end + q, c2); + wlr.DrawLine(start + r, end + r, c); - wlr.DrawLine(start + p, z + p, healthColor2, healthColor2); - wlr.DrawLine(start + q, z + q, healthColor, healthColor); - wlr.DrawLine(start + r, z + r, healthColor2, healthColor2); + wlr.DrawLine(start + p, z + p, healthColor2); + wlr.DrawLine(start + q, z + q, healthColor); + wlr.DrawLine(start + r, z + r, healthColor2); if (health.DisplayHp != health.HP) { @@ -143,9 +143,9 @@ namespace OpenRA.Graphics deltaColor.B / 2); var zz = float2.Lerp(start, end, (float)health.DisplayHp / health.MaxHP); - wlr.DrawLine(z + p, zz + p, deltaColor2, deltaColor2); - wlr.DrawLine(z + q, zz + q, deltaColor, deltaColor); - wlr.DrawLine(z + r, zz + r, deltaColor2, deltaColor2); + wlr.DrawLine(z + p, zz + p, deltaColor2); + wlr.DrawLine(z + q, zz + q, deltaColor); + wlr.DrawLine(z + r, zz + r, deltaColor2); } } diff --git a/OpenRA.Game/Graphics/SelectionBoxRenderable.cs b/OpenRA.Game/Graphics/SelectionBoxRenderable.cs index 1b677553f8..825314c0a5 100644 --- a/OpenRA.Game/Graphics/SelectionBoxRenderable.cs +++ b/OpenRA.Game/Graphics/SelectionBoxRenderable.cs @@ -55,15 +55,15 @@ namespace OpenRA.Graphics var v = new float2(0, 4f / wr.Viewport.Zoom); var wlr = Game.Renderer.WorldLineRenderer; - wlr.DrawLine(tl + u, tl, color, color); - wlr.DrawLine(tl, tl + v, color, color); - wlr.DrawLine(tr, tr - u, color, color); - wlr.DrawLine(tr, tr + v, color, color); + wlr.DrawLine(tl + u, tl, color); + wlr.DrawLine(tl, tl + v, color); + wlr.DrawLine(tr, tr - u, color); + wlr.DrawLine(tr, tr + v, color); - wlr.DrawLine(bl, bl + u, color, color); - wlr.DrawLine(bl, bl - v, color, color); - wlr.DrawLine(br, br - u, color, color); - wlr.DrawLine(br, br - v, color, color); + wlr.DrawLine(bl, bl + u, color); + wlr.DrawLine(bl, bl - v, color); + wlr.DrawLine(br, br - u, color); + wlr.DrawLine(br, br - v, color); } public void RenderDebugGeometry(WorldRenderer wr) { } diff --git a/OpenRA.Game/Graphics/TargetLineRenderable.cs b/OpenRA.Game/Graphics/TargetLineRenderable.cs index ad8adba6b6..a177d9cfae 100644 --- a/OpenRA.Game/Graphics/TargetLineRenderable.cs +++ b/OpenRA.Game/Graphics/TargetLineRenderable.cs @@ -47,7 +47,7 @@ namespace OpenRA.Graphics var a = first; foreach (var b in waypoints.Skip(1).Select(pos => wr.ScreenPxPosition(pos))) { - Game.Renderer.WorldLineRenderer.DrawLine(a, b, color, color); + Game.Renderer.WorldLineRenderer.DrawLine(a, b, color); wr.DrawTargetMarker(color, b); a = b; } diff --git a/OpenRA.Game/Graphics/WorldRenderer.cs b/OpenRA.Game/Graphics/WorldRenderer.cs index 50de97c956..9f81ade452 100644 --- a/OpenRA.Game/Graphics/WorldRenderer.cs +++ b/OpenRA.Game/Graphics/WorldRenderer.cs @@ -202,7 +202,7 @@ namespace OpenRA.Graphics { var pa = pos + offset.Rotate(WRot.FromFacing(8 * i)); var pb = pos + offset.Rotate(WRot.FromFacing(8 * i + 6)); - Game.Renderer.WorldLineRenderer.DrawLine(ScreenPosition(pa), ScreenPosition(pb), c, c); + Game.Renderer.WorldLineRenderer.DrawLine(ScreenPosition(pa), ScreenPosition(pb), c); } } @@ -214,10 +214,10 @@ namespace OpenRA.Graphics var tr = new float2(br.X, tl.Y); var wlr = Game.Renderer.WorldLineRenderer; - wlr.DrawLine(location + tl, location + tr, c, c); - wlr.DrawLine(location + tr, location + br, c, c); - wlr.DrawLine(location + br, location + bl, c, c); - wlr.DrawLine(location + bl, location + tl, c, c); + wlr.DrawLine(location + tl, location + tr, c); + wlr.DrawLine(location + tr, location + br, c); + wlr.DrawLine(location + br, location + bl, c); + wlr.DrawLine(location + bl, location + tl, c); } public void RefreshPalette() diff --git a/OpenRA.Mods.Common/Graphics/BeamRenderable.cs b/OpenRA.Mods.Common/Graphics/BeamRenderable.cs index ac024c4187..faeb2a24d3 100644 --- a/OpenRA.Mods.Common/Graphics/BeamRenderable.cs +++ b/OpenRA.Mods.Common/Graphics/BeamRenderable.cs @@ -49,7 +49,7 @@ namespace OpenRA.Mods.Common.Graphics var oldWidth = wlr.LineWidth; wlr.LineWidth = wr.Viewport.Zoom * width; - wlr.DrawLine(src, dest, color, color); + wlr.DrawLine(src, dest, color); wlr.LineWidth = oldWidth; } diff --git a/OpenRA.Mods.Common/Graphics/VoxelRenderable.cs b/OpenRA.Mods.Common/Graphics/VoxelRenderable.cs index 9898862bf2..8c5810c1af 100644 --- a/OpenRA.Mods.Common/Graphics/VoxelRenderable.cs +++ b/OpenRA.Mods.Common/Graphics/VoxelRenderable.cs @@ -135,10 +135,10 @@ namespace OpenRA.Mods.Common.Graphics // Draw transformed shadow sprite rect var c = Color.Purple; var psb = renderProxy.ProjectedShadowBounds; - Game.Renderer.WorldLineRenderer.DrawLine(shadowOrigin + psb[1], shadowOrigin + psb[3], c, c); - Game.Renderer.WorldLineRenderer.DrawLine(shadowOrigin + psb[3], shadowOrigin + psb[0], c, c); - Game.Renderer.WorldLineRenderer.DrawLine(shadowOrigin + psb[0], shadowOrigin + psb[2], c, c); - Game.Renderer.WorldLineRenderer.DrawLine(shadowOrigin + psb[2], shadowOrigin + psb[1], c, c); + Game.Renderer.WorldLineRenderer.DrawLine(shadowOrigin + psb[1], shadowOrigin + psb[3], c); + Game.Renderer.WorldLineRenderer.DrawLine(shadowOrigin + psb[3], shadowOrigin + psb[0], c); + Game.Renderer.WorldLineRenderer.DrawLine(shadowOrigin + psb[0], shadowOrigin + psb[2], c); + Game.Renderer.WorldLineRenderer.DrawLine(shadowOrigin + psb[2], shadowOrigin + psb[1], c); // Draw voxel bounding box var draw = voxel.voxels.Where(v => v.DisableFunc == null || !v.DisableFunc()); @@ -171,20 +171,20 @@ namespace OpenRA.Mods.Common.Graphics corners[i] = pxPos + new float2(screen[0], screen[1]); } - Game.Renderer.WorldLineRenderer.DrawLine(corners[0], corners[1], c, c); - Game.Renderer.WorldLineRenderer.DrawLine(corners[1], corners[3], c, c); - Game.Renderer.WorldLineRenderer.DrawLine(corners[3], corners[2], c, c); - Game.Renderer.WorldLineRenderer.DrawLine(corners[2], corners[0], c, c); + Game.Renderer.WorldLineRenderer.DrawLine(corners[0], corners[1], c); + Game.Renderer.WorldLineRenderer.DrawLine(corners[1], corners[3], c); + Game.Renderer.WorldLineRenderer.DrawLine(corners[3], corners[2], c); + Game.Renderer.WorldLineRenderer.DrawLine(corners[2], corners[0], c); - Game.Renderer.WorldLineRenderer.DrawLine(corners[4], corners[5], c, c); - Game.Renderer.WorldLineRenderer.DrawLine(corners[5], corners[7], c, c); - Game.Renderer.WorldLineRenderer.DrawLine(corners[7], corners[6], c, c); - Game.Renderer.WorldLineRenderer.DrawLine(corners[6], corners[4], c, c); + Game.Renderer.WorldLineRenderer.DrawLine(corners[4], corners[5], c); + Game.Renderer.WorldLineRenderer.DrawLine(corners[5], corners[7], c); + Game.Renderer.WorldLineRenderer.DrawLine(corners[7], corners[6], c); + Game.Renderer.WorldLineRenderer.DrawLine(corners[6], corners[4], c); - Game.Renderer.WorldLineRenderer.DrawLine(corners[0], corners[4], c, c); - Game.Renderer.WorldLineRenderer.DrawLine(corners[1], corners[5], c, c); - Game.Renderer.WorldLineRenderer.DrawLine(corners[2], corners[6], c, c); - Game.Renderer.WorldLineRenderer.DrawLine(corners[3], corners[7], c, c); + Game.Renderer.WorldLineRenderer.DrawLine(corners[0], corners[4], c); + Game.Renderer.WorldLineRenderer.DrawLine(corners[1], corners[5], c); + Game.Renderer.WorldLineRenderer.DrawLine(corners[2], corners[6], c); + Game.Renderer.WorldLineRenderer.DrawLine(corners[3], corners[7], c); } public Rectangle ScreenBounds(WorldRenderer wr) diff --git a/OpenRA.Mods.Common/Traits/CombatDebugOverlay.cs b/OpenRA.Mods.Common/Traits/CombatDebugOverlay.cs index 4a0886cb49..755813525e 100644 --- a/OpenRA.Mods.Common/Traits/CombatDebugOverlay.cs +++ b/OpenRA.Mods.Common/Traits/CombatDebugOverlay.cs @@ -69,8 +69,8 @@ namespace OpenRA.Mods.Common.Traits var o = wr.ScreenPosition(pos); var a = wr.ScreenPosition(pos + da * 224 / da.Length); var b = wr.ScreenPosition(pos + db * 224 / db.Length); - wlr.DrawLine(o, a, c, c); - wlr.DrawLine(o, b, c, c); + wlr.DrawLine(o, a, c); + wlr.DrawLine(o, b, c); } return; @@ -85,7 +85,7 @@ namespace OpenRA.Mods.Common.Traits var sm = wr.ScreenPosition(muzzle); var sd = wr.ScreenPosition(muzzle + dirOffset); - wlr.DrawLine(sm, sd, c, c); + wlr.DrawLine(sm, sd, c); wr.DrawTargetMarker(c, sm); } } diff --git a/OpenRA.Mods.Common/Widgets/LineGraphWidget.cs b/OpenRA.Mods.Common/Widgets/LineGraphWidget.cs index b412dc9f9a..14329fcb9f 100644 --- a/OpenRA.Mods.Common/Widgets/LineGraphWidget.cs +++ b/OpenRA.Mods.Common/Widgets/LineGraphWidget.cs @@ -118,21 +118,18 @@ namespace OpenRA.Mods.Common.Widgets if (points.Any()) { points = points.Reverse().Take(xAxisSize).Reverse(); - var scaledData = points.Select(d => d * scale); - var x = 0; - scaledData.Aggregate((a, b) => - { - Game.Renderer.LineRenderer.DrawLine( - origin + new float2(x, -a), - origin + new float2(x + xStep, -b), - color, color); - x += xStep; - return b; - }); + var lastX = 0; + var lastPoint = 0f; + Game.Renderer.LineRenderer.DrawLineStrip( + points.Select((point, x) => + { + lastX = x; + lastPoint = point; + return origin + new float2(x * xStep, -point * scale); + }), color); - var value = points.Last(); - if (value != 0) - tiny.DrawText(GetValueFormat().F(value), origin + new float2(x, -value * scale - 2), color); + if (lastPoint != 0f) + tiny.DrawText(GetValueFormat().F(lastPoint), origin + new float2(lastX * xStep, -lastPoint * scale - 2), color); } tiny.DrawText(key, new float2(rect.Left, rect.Top) + new float2(5, 10 * keyOffset + 3), color); @@ -142,7 +139,7 @@ namespace OpenRA.Mods.Common.Widgets // TODO: make this stuff not draw outside of the RenderBounds for (int n = pointStart, x = 0; n <= pointEnd; n++, x += xStep) { - Game.Renderer.LineRenderer.DrawLine(origin + new float2(x, 0), origin + new float2(x, -5), Color.White, Color.White); + Game.Renderer.LineRenderer.DrawLine(origin + new float2(x, 0), origin + new float2(x, -5), Color.White); tiny.DrawText(GetXAxisValueFormat().F(n), origin + new float2(x, 2), Color.White); } @@ -151,16 +148,16 @@ namespace OpenRA.Mods.Common.Widgets for (var y = GetDisplayFirstYAxisValue() ? 0 : yStep; y <= height; y += yStep) { var yValue = y / scale; - Game.Renderer.LineRenderer.DrawLine(origin + new float2(width - 5, -y), origin + new float2(width, -y), Color.White, Color.White); + Game.Renderer.LineRenderer.DrawLine(origin + new float2(width - 5, -y), origin + new float2(width, -y), Color.White); tiny.DrawText(GetYAxisValueFormat().F(yValue), origin + new float2(width + 2, -y), Color.White); } bold.DrawText(GetYAxisLabel(), origin + new float2(width + 40, -(height / 2)), Color.White); - Game.Renderer.LineRenderer.DrawLine(origin, origin + new float2(width, 0), Color.White, Color.White); - Game.Renderer.LineRenderer.DrawLine(origin, origin + new float2(0, -height), Color.White, Color.White); - Game.Renderer.LineRenderer.DrawLine(origin + new float2(width, 0), origin + new float2(width, -height), Color.White, Color.White); - Game.Renderer.LineRenderer.DrawLine(origin + new float2(0, -height), origin + new float2(width, -height), Color.White, Color.White); + Game.Renderer.LineRenderer.DrawLine(origin, origin + new float2(width, 0), Color.White); + Game.Renderer.LineRenderer.DrawLine(origin, origin + new float2(0, -height), Color.White); + Game.Renderer.LineRenderer.DrawLine(origin + new float2(width, 0), origin + new float2(width, -height), Color.White); + Game.Renderer.LineRenderer.DrawLine(origin + new float2(0, -height), origin + new float2(width, -height), Color.White); } public override Widget Clone() diff --git a/OpenRA.Mods.Common/Widgets/PerfGraphWidget.cs b/OpenRA.Mods.Common/Widgets/PerfGraphWidget.cs index e06c17a71b..ce0b9d4130 100644 --- a/OpenRA.Mods.Common/Widgets/PerfGraphWidget.cs +++ b/OpenRA.Mods.Common/Widgets/PerfGraphWidget.cs @@ -23,34 +23,26 @@ namespace OpenRA.Mods.Common.Widgets var origin = new float2(rect.Right, rect.Bottom); var basis = new float2(-rect.Width / 100, -rect.Height / 100); - Game.Renderer.LineRenderer.DrawLine(origin, origin + new float2(100, 0) * basis, Color.White, Color.White); - Game.Renderer.LineRenderer.DrawLine(origin + new float2(100, 0) * basis, origin + new float2(100, 100) * basis, Color.White, Color.White); + Game.Renderer.LineRenderer.DrawLine(origin, origin + new float2(100, 0) * basis, Color.White); + Game.Renderer.LineRenderer.DrawLine(origin + new float2(100, 0) * basis, origin + new float2(100, 100) * basis, Color.White); var k = 0; foreach (var item in PerfHistory.Items.Values) { - var n = 0; - item.Samples().Aggregate((a, b) => - { - Game.Renderer.LineRenderer.DrawLine( - origin + new float2(n, (float)a) * basis, - origin + new float2(n + 1, (float)b) * basis, - item.C, item.C); - ++n; - return b; - }); + Game.Renderer.LineRenderer.DrawLineStrip( + item.Samples().Select((sample, i) => origin + new float2(i, (float)sample) * basis), item.C); var u = new float2(rect.Left, rect.Top); Game.Renderer.LineRenderer.DrawLine( u + new float2(10, 10 * k + 5), u + new float2(12, 10 * k + 5), - item.C, item.C); + item.C); Game.Renderer.LineRenderer.DrawLine( u + new float2(10, 10 * k + 4), u + new float2(12, 10 * k + 4), - item.C, item.C); + item.C); ++k; } diff --git a/OpenRA.Mods.Common/Widgets/RadarWidget.cs b/OpenRA.Mods.Common/Widgets/RadarWidget.cs index 9801580c02..99f9ff6f71 100644 --- a/OpenRA.Mods.Common/Widgets/RadarWidget.cs +++ b/OpenRA.Mods.Common/Widgets/RadarWidget.cs @@ -256,9 +256,9 @@ namespace OpenRA.Mods.Common.Widgets var pingCell = world.Map.CellContaining(radarPing.Position); var points = radarPing.Points(CellToMinimapPixel(pingCell)).ToArray(); - lr.DrawLine(points[0], points[1], c, c); - lr.DrawLine(points[1], points[2], c, c); - lr.DrawLine(points[2], points[0], c, c); + lr.DrawLine(points[0], points[1], c); + lr.DrawLine(points[1], points[2], c); + lr.DrawLine(points[2], points[0], c); } lr.LineWidth = oldWidth; diff --git a/OpenRA.Mods.Common/Widgets/ResourceBarWidget.cs b/OpenRA.Mods.Common/Widgets/ResourceBarWidget.cs index 19756c4b3e..4963d9e24f 100644 --- a/OpenRA.Mods.Common/Widgets/ResourceBarWidget.cs +++ b/OpenRA.Mods.Common/Widgets/ResourceBarWidget.cs @@ -92,7 +92,7 @@ namespace OpenRA.Mods.Common.Widgets top.Y -= 1; } - Game.Renderer.LineRenderer.DrawLine(bottom, top, color, color); + Game.Renderer.LineRenderer.DrawLine(bottom, top, color); } } else @@ -122,7 +122,7 @@ namespace OpenRA.Mods.Common.Widgets right.X -= 1; } - Game.Renderer.LineRenderer.DrawLine(left, right, color, color); + Game.Renderer.LineRenderer.DrawLine(left, right, color); } } else