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 787e1f73d3..7f31a923b8 100644 --- a/OpenRA.Mods.Common/Traits/World/ShroudRenderer.cs +++ b/OpenRA.Mods.Common/Traits/World/ShroudRenderer.cs @@ -269,22 +269,26 @@ namespace OpenRA.Mods.Common.Traits void Render(CellRegion visibleRegion) { - var renderRegion = CellRegion.Expand(visibleRegion, 1).MapCoords; + // 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(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 (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 // 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 +296,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 +307,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])