@@ -24,7 +24,7 @@ namespace OpenRA.Graphics
|
||||
theater = wr.Theater;
|
||||
mapTiles = world.Map.MapTiles.Value;
|
||||
|
||||
terrain = new TerrainSpriteLayer(world, wr, theater.Sheet, BlendMode.Alpha, wr.Palette("terrain"));
|
||||
terrain = new TerrainSpriteLayer(world, wr, theater.Sheet, BlendMode.Alpha, wr.Palette("terrain"), true);
|
||||
foreach (var cell in world.Map.AllCells)
|
||||
UpdateCell(cell);
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ namespace OpenRA.Graphics
|
||||
readonly Vertex[] vertices;
|
||||
readonly HashSet<int> dirtyRows = new HashSet<int>();
|
||||
readonly int rowStride;
|
||||
readonly bool restrictToBounds;
|
||||
|
||||
readonly WorldRenderer worldRenderer;
|
||||
readonly Map map;
|
||||
@@ -34,9 +35,10 @@ namespace OpenRA.Graphics
|
||||
|
||||
float paletteIndex;
|
||||
|
||||
public TerrainSpriteLayer(World world, WorldRenderer wr, Sheet sheet, BlendMode blendMode, PaletteReference palette)
|
||||
public TerrainSpriteLayer(World world, WorldRenderer wr, Sheet sheet, BlendMode blendMode, PaletteReference palette, bool restrictToBounds)
|
||||
{
|
||||
worldRenderer = wr;
|
||||
this.restrictToBounds = restrictToBounds;
|
||||
this.sheet = sheet;
|
||||
this.blendMode = blendMode;
|
||||
paletteIndex = palette.TextureIndex;
|
||||
@@ -92,7 +94,7 @@ namespace OpenRA.Graphics
|
||||
|
||||
public void Draw(Viewport viewport)
|
||||
{
|
||||
var cells = viewport.VisibleCells;
|
||||
var cells = restrictToBounds ? viewport.VisibleCellsInsideBounds : viewport.AllVisibleCells;
|
||||
|
||||
// Only draw the rows that are visible.
|
||||
var firstRow = cells.MapCoords.TopLeft.V;
|
||||
|
||||
@@ -53,6 +53,9 @@ namespace OpenRA.Graphics
|
||||
CellRegion cells;
|
||||
bool cellsDirty = true;
|
||||
|
||||
CellRegion allCells;
|
||||
bool allCellsDirty = true;
|
||||
|
||||
float zoom = 1f;
|
||||
public float Zoom
|
||||
{
|
||||
@@ -66,6 +69,7 @@ namespace OpenRA.Graphics
|
||||
zoom = value;
|
||||
viewportSize = (1f / zoom * new float2(Game.Renderer.Resolution)).ToInt2();
|
||||
cellsDirty = true;
|
||||
allCellsDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,6 +191,7 @@ namespace OpenRA.Graphics
|
||||
{
|
||||
CenterLocation = worldRenderer.ScreenPxPosition(pos).Clamp(mapBounds);
|
||||
cellsDirty = true;
|
||||
allCellsDirty = true;
|
||||
}
|
||||
|
||||
public void Scroll(float2 delta, bool ignoreBorders)
|
||||
@@ -194,6 +199,7 @@ namespace OpenRA.Graphics
|
||||
// Convert scroll delta from world-px to viewport-px
|
||||
CenterLocation += (1f / Zoom * delta).ToInt2();
|
||||
cellsDirty = true;
|
||||
allCellsDirty = true;
|
||||
|
||||
if (!ignoreBorders)
|
||||
CenterLocation = CenterLocation.Clamp(mapBounds);
|
||||
@@ -207,8 +213,8 @@ namespace OpenRA.Graphics
|
||||
{
|
||||
// Visible rectangle in world coordinates (expanded to the corners of the cells)
|
||||
var map = worldRenderer.World.Map;
|
||||
var ctl = map.CenterOfCell(VisibleCells.TopLeft) - new WVec(512, 512, 0);
|
||||
var cbr = map.CenterOfCell(VisibleCells.BottomRight) + new WVec(512, 512, 0);
|
||||
var ctl = map.CenterOfCell(VisibleCellsInsideBounds.TopLeft) - new WVec(512, 512, 0);
|
||||
var cbr = map.CenterOfCell(VisibleCellsInsideBounds.BottomRight) + new WVec(512, 512, 0);
|
||||
|
||||
// Convert to screen coordinates
|
||||
var tl = WorldToViewPx(worldRenderer.ScreenPxPosition(ctl - new WVec(0, 0, ctl.Z))).Clamp(ScreenClip);
|
||||
@@ -220,42 +226,61 @@ namespace OpenRA.Graphics
|
||||
}
|
||||
}
|
||||
|
||||
public CellRegion VisibleCells
|
||||
CellRegion CalculateVisibleCells(bool insideBounds)
|
||||
{
|
||||
var map = worldRenderer.World.Map;
|
||||
var wtl = worldRenderer.Position(TopLeft);
|
||||
var wbr = worldRenderer.Position(BottomRight);
|
||||
|
||||
// Map editor shows the full map (including the area outside the regular bounds)
|
||||
Func<MPos, MPos> clamp = map.Clamp;
|
||||
if (!insideBounds)
|
||||
clamp = map.MapTiles.Value.Clamp;
|
||||
|
||||
// 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 ctl = new MPos(wtl.X / 1024, wtl.Y / dy);
|
||||
var cbr = new MPos(wbr.X / 1024, wbr.Y / dy);
|
||||
|
||||
var tl = clamp(ctl).ToCPos(map.TileShape);
|
||||
|
||||
// Also need to account for height of cells in rows below the bottom.
|
||||
var heightPadding = map.TileShape == TileShape.Diamond ? 3 : 0;
|
||||
var br = clamp(new MPos(cbr.U, cbr.V + heightPadding + maxGroundHeight / 2 + 1)).ToCPos(map.TileShape);
|
||||
|
||||
return new CellRegion(map.TileShape, tl, br);
|
||||
}
|
||||
|
||||
public CellRegion VisibleCellsInsideBounds
|
||||
{
|
||||
get
|
||||
{
|
||||
if (cellsDirty)
|
||||
{
|
||||
var map = worldRenderer.World.Map;
|
||||
var wtl = worldRenderer.Position(TopLeft);
|
||||
var wbr = worldRenderer.Position(BottomRight);
|
||||
|
||||
// Map editor shows the full map (including the area outside the regular bounds)
|
||||
Func<MPos, MPos> clamp = map.Clamp;
|
||||
if (worldRenderer.World.Type == WorldType.Editor)
|
||||
clamp = map.MapTiles.Value.Clamp;
|
||||
|
||||
// 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 ctl = new MPos(wtl.X / 1024, wtl.Y / dy);
|
||||
var cbr = new MPos(wbr.X / 1024, wbr.Y / dy);
|
||||
|
||||
var tl = clamp(ctl).ToCPos(map.TileShape);
|
||||
|
||||
// Also need to account for height of cells in rows below the bottom.
|
||||
var heightPadding = map.TileShape == TileShape.Diamond ? 3 : 0;
|
||||
var br = clamp(new MPos(cbr.U, cbr.V + heightPadding + maxGroundHeight / 2 + 1)).ToCPos(map.TileShape);
|
||||
|
||||
cells = new CellRegion(map.TileShape, tl, br);
|
||||
cells = CalculateVisibleCells(worldRenderer.World.Type != WorldType.Editor);
|
||||
cellsDirty = false;
|
||||
}
|
||||
|
||||
return cells;
|
||||
}
|
||||
}
|
||||
|
||||
public CellRegion AllVisibleCells
|
||||
{
|
||||
get
|
||||
{
|
||||
if (allCellsDirty)
|
||||
{
|
||||
allCells = CalculateVisibleCells(false);
|
||||
allCellsDirty = false;
|
||||
}
|
||||
|
||||
return allCells;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -146,7 +146,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
Dirty.Clear();
|
||||
|
||||
foreach (var uv in wr.Viewport.VisibleCells.MapCoords)
|
||||
foreach (var uv in wr.Viewport.VisibleCellsInsideBounds.MapCoords)
|
||||
{
|
||||
var t = Tiles[uv];
|
||||
if (t.Sprite != null)
|
||||
|
||||
@@ -66,7 +66,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
var layer = pair.Value;
|
||||
|
||||
// Only render quads in viewing range:
|
||||
foreach (var cell in wr.Viewport.VisibleCells)
|
||||
foreach (var cell in wr.Viewport.VisibleCellsInsideBounds)
|
||||
{
|
||||
if (layer[cell] <= 0)
|
||||
continue;
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public void Render(WorldRenderer wr)
|
||||
{
|
||||
var shroudObscured = world.ShroudObscuresTest;
|
||||
foreach (var uv in wr.Viewport.VisibleCells.MapCoords)
|
||||
foreach (var uv in wr.Viewport.VisibleCellsInsideBounds.MapCoords)
|
||||
{
|
||||
if (shroudObscured(uv))
|
||||
continue;
|
||||
|
||||
@@ -189,8 +189,8 @@ namespace OpenRA.Mods.Common.Traits
|
||||
if (fogSprites.Any(s => s.BlendMode != fogBlend))
|
||||
throw new InvalidDataException("Fog sprites must all use the same blend mode.");
|
||||
|
||||
shroudLayer = new TerrainSpriteLayer(w, wr, shroudSheet, shroudBlend, wr.Palette(info.ShroudPalette));
|
||||
fogLayer = new TerrainSpriteLayer(w, wr, fogSheet, fogBlend, wr.Palette(info.FogPalette));
|
||||
shroudLayer = new TerrainSpriteLayer(w, wr, shroudSheet, shroudBlend, wr.Palette(info.ShroudPalette), false);
|
||||
fogLayer = new TerrainSpriteLayer(w, wr, fogSheet, fogBlend, wr.Palette(info.FogPalette), false);
|
||||
}
|
||||
|
||||
Edges GetEdges(MPos uv, Func<MPos, bool> isVisible)
|
||||
|
||||
@@ -144,7 +144,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
foreach (var kv in tiles)
|
||||
{
|
||||
if (!wr.Viewport.VisibleCells.Contains(kv.Key))
|
||||
if (!wr.Viewport.VisibleCellsInsideBounds.Contains(kv.Key))
|
||||
continue;
|
||||
|
||||
if (world.ShroudObscures(kv.Key))
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
var colors = wr.World.TileSet.HeightDebugColors;
|
||||
var mouseCell = wr.Viewport.ViewToWorld(Viewport.LastMousePos).ToMPos(wr.World.Map);
|
||||
|
||||
foreach (var uv in wr.Viewport.VisibleCells.MapCoords)
|
||||
foreach (var uv in wr.Viewport.VisibleCellsInsideBounds.MapCoords)
|
||||
{
|
||||
var height = (int)map.MapHeight.Value[uv];
|
||||
var tile = map.MapTiles.Value[uv];
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace OpenRA.Mods.D2k.Traits
|
||||
|
||||
foreach (var kv in tiles)
|
||||
{
|
||||
if (!wr.Viewport.VisibleCells.Contains(kv.Key))
|
||||
if (!wr.Viewport.VisibleCellsInsideBounds.Contains(kv.Key))
|
||||
continue;
|
||||
|
||||
if (wr.World.ShroudObscures(kv.Key))
|
||||
|
||||
Reference in New Issue
Block a user