From 803390c68e069596a94583e5a1d73b2e66c95fa4 Mon Sep 17 00:00:00 2001 From: RoosterDragon Date: Wed, 25 Feb 2015 20:17:02 +0000 Subject: [PATCH 1/2] Speed up rendering map border shroud when no shroud is visible. When the map border shroud must be rendered, but no cells at the border are visible, then we know that no shroud will be visible at all. We can bail from rendering early in this case. --- .../Traits/World/ShroudRenderer.cs | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/OpenRA.Mods.Common/Traits/World/ShroudRenderer.cs b/OpenRA.Mods.Common/Traits/World/ShroudRenderer.cs index 787e1f73d3..37521d613c 100644 --- a/OpenRA.Mods.Common/Traits/World/ShroudRenderer.cs +++ b/OpenRA.Mods.Common/Traits/World/ShroudRenderer.cs @@ -201,7 +201,7 @@ namespace OpenRA.Mods.Common.Traits public void RenderShroud(WorldRenderer wr, Shroud shroud) { Update(shroud); - Render(wr.Viewport.VisibleCells); + Render(CellRegion.Expand(wr.Viewport.VisibleCells, 1)); } void Update(Shroud newShroud) @@ -269,22 +269,22 @@ namespace OpenRA.Mods.Common.Traits void Render(CellRegion visibleRegion) { - var renderRegion = CellRegion.Expand(visibleRegion, 1).MapCoords; - if (currentShroud == null) - { - RenderMapBorderShroud(renderRegion); - return; - } - - RenderPlayerShroud(visibleRegion, renderRegion); + RenderMapBorderShroud(visibleRegion); + else + RenderPlayerShroud(visibleRegion); } - void RenderMapBorderShroud(CellRegion.MapCoordsRegion renderRegion) + void RenderMapBorderShroud(CellRegion visibleRegion) { + // The map border shroud only affects the map border. If none of the visible cells are on the border, then + // we don't need to render anything and can bail early for performance. + if (map.Cells.Contains(visibleRegion)) + return; + // Render the shroud that just encroaches at the map border. This shroud is always fully cached, so we can // just render straight from the cache. - foreach (var uv in renderRegion) + foreach (var uv in visibleRegion.MapCoords) { var offset = VertexArrayOffset(uv); RenderCachedTile(shroudSpriteLayer[uv], shroudVertices, offset); @@ -292,7 +292,7 @@ namespace OpenRA.Mods.Common.Traits } } - void RenderPlayerShroud(CellRegion visibleRegion, CellRegion.MapCoordsRegion renderRegion) + void RenderPlayerShroud(CellRegion visibleRegion) { // Render the shroud by drawing the appropriate tile over each cell that is visible on-screen. // For performance we keep a cache tiles we have drawn previously so we don't have to recalculate the @@ -303,7 +303,7 @@ namespace OpenRA.Mods.Common.Traits // cached vertices. var visibleUnderShroud = currentShroud.IsExploredTest(visibleRegion); var visibleUnderFog = currentShroud.IsVisibleTest(visibleRegion); - foreach (var uv in renderRegion) + foreach (var uv in visibleRegion.MapCoords) { var offset = VertexArrayOffset(uv); if (shroudDirty[uv]) From d3b93345b4c7bfd1b53ce2023b783f038acbd3c2 Mon Sep 17 00:00:00 2001 From: RoosterDragon Date: Thu, 26 Feb 2015 21:27:48 +0000 Subject: [PATCH 2/2] Fix Viewport.VisibleCells. Reworked the visible cells calculation to ensure the visible region is actually minimal, which should reduce the amount of rendering to be done by a small amount. Previously, the region would tend to overdraw by 2-3 cells in either direction. For isometric maps, there was also a bug where it would draw far too much vertically above the top of the map. --- OpenRA.Game/Graphics/Viewport.cs | 18 +++++++++++------- .../Traits/World/ShroudRenderer.cs | 8 ++++++-- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/OpenRA.Game/Graphics/Viewport.cs b/OpenRA.Game/Graphics/Viewport.cs index 4538fb1245..c09fc5bb94 100644 --- a/OpenRA.Game/Graphics/Viewport.cs +++ b/OpenRA.Game/Graphics/Viewport.cs @@ -163,16 +163,20 @@ namespace OpenRA.Graphics var wtl = worldRenderer.Position(TopLeft); var wbr = worldRenderer.Position(BottomRight); - // Visible rectangle in map coordinates - var ctl = new MPos(wtl.X / 1024, wtl.Y / 1024); + // Due to diamond tile staggering, we need to adjust the top-left bounds outwards by half a cell. + if (map.TileShape == TileShape.Diamond) + wtl -= new WVec(512, 512, 0); + + // Visible rectangle in map coordinates. var dy = map.TileShape == TileShape.Diamond ? 512 : 1024; - var cbr = new MPos((wbr.X + 1023) / 1024, (wbr.Y + dy - 1) / dy); + var ctl = new MPos(wtl.X / 1024, wtl.Y / dy); + var cbr = new MPos(wbr.X / 1024, wbr.Y / dy); - // Add a 1 cell cordon to prevent holes, then convert back to cell coordinates - var tl = map.Clamp(new MPos(ctl.U - 1, ctl.V - 1).ToCPos(map)); + var tl = map.Clamp(ctl.ToCPos(map)); - // Also need to account for height of cells in rows below the bottom - var br = map.Clamp(new MPos(cbr.U + 1, cbr.V + 2 + maxGroundHeight / 2).ToCPos(map)); + // Also need to account for height of cells in rows below the bottom. + var heightPadding = map.TileShape == TileShape.Diamond ? 2 : 0; + var br = map.Clamp(new MPos(cbr.U, cbr.V + heightPadding + maxGroundHeight / 2).ToCPos(map)); cells = new CellRegion(map.TileShape, tl, br); cellsDirty = false; diff --git a/OpenRA.Mods.Common/Traits/World/ShroudRenderer.cs b/OpenRA.Mods.Common/Traits/World/ShroudRenderer.cs index 37521d613c..7f31a923b8 100644 --- a/OpenRA.Mods.Common/Traits/World/ShroudRenderer.cs +++ b/OpenRA.Mods.Common/Traits/World/ShroudRenderer.cs @@ -201,7 +201,7 @@ namespace OpenRA.Mods.Common.Traits public void RenderShroud(WorldRenderer wr, Shroud shroud) { Update(shroud); - Render(CellRegion.Expand(wr.Viewport.VisibleCells, 1)); + Render(wr.Viewport.VisibleCells); } void Update(Shroud newShroud) @@ -269,6 +269,10 @@ namespace OpenRA.Mods.Common.Traits void Render(CellRegion visibleRegion) { + // Due to diamond tile staggering, we need to expand the cordon to get full shroud coverage. + if (map.TileShape == TileShape.Diamond) + visibleRegion = CellRegion.Expand(visibleRegion, 1); + if (currentShroud == null) RenderMapBorderShroud(visibleRegion); else @@ -279,7 +283,7 @@ namespace OpenRA.Mods.Common.Traits { // The map border shroud only affects the map border. If none of the visible cells are on the border, then // we don't need to render anything and can bail early for performance. - if (map.Cells.Contains(visibleRegion)) + if (CellRegion.Expand(map.Cells, -1).Contains(visibleRegion)) return; // Render the shroud that just encroaches at the map border. This shroud is always fully cached, so we can