diff --git a/OpenRA.Game/Graphics/TerrainRenderer.cs b/OpenRA.Game/Graphics/TerrainRenderer.cs index fe6cb84410..f8562ed359 100644 --- a/OpenRA.Game/Graphics/TerrainRenderer.cs +++ b/OpenRA.Game/Graphics/TerrainRenderer.cs @@ -46,9 +46,9 @@ namespace OpenRA.Graphics public void Draw(WorldRenderer wr, Viewport viewport) { var verticesPerRow = 4*map.Bounds.Width; - var bounds = viewport.CellBounds; - var firstRow = bounds.Top - map.Bounds.Top; - var lastRow = bounds.Bottom - map.Bounds.Top; + var cells = viewport.VisibleCells; + var firstRow = cells.TopLeft.Y - map.Bounds.Top; + var lastRow = cells.BottomRight.Y - map.Bounds.Top + 1; if (lastRow < 0 || firstRow > map.Bounds.Height) return; diff --git a/OpenRA.Game/Graphics/Viewport.cs b/OpenRA.Game/Graphics/Viewport.cs index 4c61e2e18c..540e97f379 100755 --- a/OpenRA.Game/Graphics/Viewport.cs +++ b/OpenRA.Game/Graphics/Viewport.cs @@ -9,6 +9,7 @@ #endregion using System; +using System.Collections; using System.Collections.Generic; using System.Drawing; using System.Linq; @@ -48,6 +49,9 @@ namespace OpenRA.Graphics int2 viewportSize; bool cellBoundsDirty = true; + CellRegion cells; + bool cellsDirty = true; + float zoom = 1f; public float Zoom { @@ -61,6 +65,7 @@ namespace OpenRA.Graphics zoom = value; viewportSize = (1f / zoom * new float2(Game.Renderer.Resolution)).ToInt2(); cellBoundsDirty = true; + cellsDirty = true; } } @@ -111,6 +116,7 @@ namespace OpenRA.Graphics { CenterLocation = worldRenderer.ScreenPxPosition(pos).Clamp(mapBounds); cellBoundsDirty = true; + cellsDirty = true; } public void Scroll(float2 delta, bool ignoreBorders) @@ -118,6 +124,7 @@ namespace OpenRA.Graphics // Convert scroll delta from world-px to viewport-px CenterLocation += (1f / Zoom * delta).ToInt2(); cellBoundsDirty = true; + cellsDirty = true; if (!ignoreBorders) CenterLocation = CenterLocation.Clamp(mapBounds); @@ -158,5 +165,24 @@ namespace OpenRA.Graphics return b.HasValue ? Rectangle.Intersect(cachedRect, b.Value) : cachedRect; } } + + public CellRegion VisibleCells + { + get + { + if (cellsDirty) + { + // Calculate the intersection of the visible rectangle and the map. + var map = worldRenderer.world.Map; + var tl = map.Clamp(worldRenderer.Position(TopLeft).ToCPos() - new CVec(1, 1)); + var br = map.Clamp(worldRenderer.Position(BottomRight).ToCPos()); + + cells = new CellRegion(tl, br); + cellsDirty = false; + } + + return cells; + } + } } } \ No newline at end of file diff --git a/OpenRA.Game/Map/Map.cs b/OpenRA.Game/Map/Map.cs index 01f5685963..4fc1858558 100644 --- a/OpenRA.Game/Map/Map.cs +++ b/OpenRA.Game/Map/Map.cs @@ -9,6 +9,7 @@ #endregion using System; +using System.Collections; using System.Collections.Generic; using System.Drawing; using System.IO; @@ -118,6 +119,8 @@ namespace OpenRA public Ruleset Rules { get { return rules != null ? rules.Value : null; } } public SequenceProvider SequenceProvider { get { return Rules.Sequences[Tileset]; } } + [FieldLoader.Ignore] public CellRegion Cells; + public static Map FromTileset(TileSet tileset) { var tile = tileset.Templates.First(); @@ -229,11 +232,6 @@ namespace OpenRA NotificationDefinitions = MiniYaml.NodesOrEmpty(yaml, "Notifications"); TranslationDefinitions = MiniYaml.NodesOrEmpty(yaml, "Translations"); - CustomTerrain = new int[MapSize.X, MapSize.Y]; - for (var x = 0; x < MapSize.X; x++) - for (var y = 0; y < MapSize.Y; y++) - CustomTerrain[x, y] = -1; - MapTiles = Exts.Lazy(() => LoadMapTiles()); MapResources = Exts.Lazy(() => LoadResourceTiles()); @@ -254,6 +252,14 @@ namespace OpenRA void PostInit() { rules = Exts.Lazy(() => Game.modData.RulesetCache.LoadMapRules(this)); + + var tl = new CPos(Bounds.Left, Bounds.Top); + var br = new CPos(Bounds.Right - 1, Bounds.Bottom - 1); + Cells = new CellRegion(tl, br); + + CustomTerrain = new int[MapSize.X, MapSize.Y]; + foreach (var cell in Cells) + CustomTerrain[cell.X, cell.Y] = -1; } public Ruleset PreloadRules() @@ -455,6 +461,7 @@ namespace OpenRA public void ResizeCordon(int left, int top, int right, int bottom) { Bounds = Rectangle.FromLTRB(left, top, right, bottom); + Cells = new CellRegion(new CPos(Bounds.Left, Bounds.Top), new CPos(Bounds.Right - 1, Bounds.Bottom - 1)); } string ComputeHash()