Add support for diamond cell grids.

This commit is contained in:
Paul Chote
2014-06-30 11:25:39 +12:00
parent af0e948a67
commit a30c8b53a7
11 changed files with 191 additions and 82 deletions

View File

@@ -20,11 +20,12 @@ namespace OpenRA.Graphics
{
public static Bitmap TerrainBitmap(TileSet tileset, Map map, bool actualSize = false)
{
var width = map.Bounds.Width;
var height = map.Bounds.Height;
var b = map.Bounds;
var width = b.Width;
var height = b.Height;
if (!actualSize)
width = height = Exts.NextPowerOf2(Math.Max(map.Bounds.Width, map.Bounds.Height));
width = height = Exts.NextPowerOf2(Math.Max(b.Width, b.Height));
var terrain = new Bitmap(width, height);
@@ -37,15 +38,17 @@ namespace OpenRA.Graphics
{
var c = (int*)bitmapData.Scan0;
for (var x = 0; x < map.Bounds.Width; x++)
for (var y = 0; y < map.Bounds.Height; y++)
for (var x = 0; x < b.Width; x++)
{
for (var y = 0; y < b.Height; y++)
{
var mapX = x + map.Bounds.Left;
var mapY = y + map.Bounds.Top;
var mapX = x + b.Left;
var mapY = y + b.Top;
var type = tileset.GetTerrainInfo(mapTiles[mapX, mapY]);
*(c + (y * bitmapData.Stride >> 2) + x) = type.Color.ToArgb();
}
}
}
terrain.UnlockBits(bitmapData);
@@ -57,6 +60,7 @@ namespace OpenRA.Graphics
static Bitmap AddStaticResources(TileSet tileset, Map map, Ruleset resourceRules, Bitmap terrainBitmap)
{
var terrain = new Bitmap(terrainBitmap);
var b = map.Bounds;
var bitmapData = terrain.LockBits(terrain.Bounds(),
ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
@@ -65,11 +69,12 @@ namespace OpenRA.Graphics
{
var c = (int*)bitmapData.Scan0;
for (var x = 0; x < map.Bounds.Width; x++)
for (var y = 0; y < map.Bounds.Height; y++)
for (var x = 0; x < b.Width; x++)
{
for (var y = 0; y < b.Height; y++)
{
var mapX = x + map.Bounds.Left;
var mapY = y + map.Bounds.Top;
var mapX = x + b.Left;
var mapY = y + b.Top;
if (map.MapResources.Value[mapX, mapY].Type == 0)
continue;
@@ -82,6 +87,7 @@ namespace OpenRA.Graphics
*(c + (y * bitmapData.Stride >> 2) + x) = tileset[tileset.GetTerrainIndex(res)].Color.ToArgb();
}
}
}
terrain.UnlockBits(bitmapData);
@@ -92,7 +98,9 @@ namespace OpenRA.Graphics
public static Bitmap CustomTerrainBitmap(World world)
{
var map = world.Map;
var size = Exts.NextPowerOf2(Math.Max(map.Bounds.Width, map.Bounds.Height));
var b = map.Bounds;
var size = Exts.NextPowerOf2(Math.Max(b.Width, b.Height));
var bitmap = new Bitmap(size, size);
var bitmapData = bitmap.LockBits(bitmap.Bounds(),
ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
@@ -101,16 +109,19 @@ namespace OpenRA.Graphics
{
var c = (int*)bitmapData.Scan0;
for (var x = 0; x < map.Bounds.Width; x++)
for (var y = 0; y < map.Bounds.Height; y++)
for (var x = 0; x < b.Width; x++)
{
for (var y = 0; y < b.Height; y++)
{
var mapX = x + map.Bounds.Left;
var mapY = y + map.Bounds.Top;
var mapX = x + b.Left;
var mapY = y + b.Top;
var custom = map.CustomTerrain[mapX, mapY];
if (custom == -1)
continue;
*(c + (y * bitmapData.Stride >> 2) + x) = world.TileSet[custom].Color.ToArgb();
}
}
}
bitmap.UnlockBits(bitmapData);
@@ -120,7 +131,9 @@ namespace OpenRA.Graphics
public static Bitmap ActorsBitmap(World world)
{
var map = world.Map;
var size = Exts.NextPowerOf2(Math.Max(map.Bounds.Width, map.Bounds.Height));
var b = map.Bounds;
var size = Exts.NextPowerOf2(Math.Max(b.Width, b.Height));
var bitmap = new Bitmap(size, size);
var bitmapData = bitmap.LockBits(bitmap.Bounds(),
ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
@@ -136,8 +149,11 @@ namespace OpenRA.Graphics
var color = t.Trait.RadarSignatureColor(t.Actor);
foreach (var cell in t.Trait.RadarSignatureCells(t.Actor))
if (world.Map.Contains(cell))
*(c + ((cell.Y - world.Map.Bounds.Top) * bitmapData.Stride >> 2) + cell.X - world.Map.Bounds.Left) = color.ToArgb();
{
var uv = Map.CellToMap(map.TileShape, cell);
if (b.Contains(uv.X, uv.Y))
*(c + ((uv.Y - b.Top) * bitmapData.Stride >> 2) + uv.X - b.Left) = color.ToArgb();
}
}
}
@@ -148,7 +164,9 @@ namespace OpenRA.Graphics
public static Bitmap ShroudBitmap(World world)
{
var map = world.Map;
var size = Exts.NextPowerOf2(Math.Max(map.Bounds.Width, map.Bounds.Height));
var b = map.Bounds;
var size = Exts.NextPowerOf2(Math.Max(b.Width, b.Height));
var bitmap = new Bitmap(size, size);
if (world.RenderPlayer == null)
return bitmap;
@@ -158,20 +176,20 @@ namespace OpenRA.Graphics
var shroud = Color.Black.ToArgb();
var fog = Color.FromArgb(128, Color.Black).ToArgb();
var offset = new CVec(b.Left, b.Top);
unsafe
{
var c = (int*)bitmapData.Scan0;
for (var x = 0; x < map.Bounds.Width; x++)
for (var y = 0; y < map.Bounds.Height; y++)
{
var p = new CPos(x + map.Bounds.Left, y + map.Bounds.Top);
if (world.ShroudObscures(p))
*(c + (y * bitmapData.Stride >> 2) + x) = shroud;
else if (world.FogObscures(p))
*(c + (y * bitmapData.Stride >> 2) + x) = fog;
}
foreach (var cell in map.Cells)
{
var uv = Map.CellToMap(map.TileShape, cell) - offset;
if (world.ShroudObscures(cell))
*(c + (uv.Y * bitmapData.Stride >> 2) + uv.X) = shroud;
else if (world.FogObscures(cell))
*(c + (uv.Y * bitmapData.Stride >> 2) + uv.X) = fog;
}
}
bitmap.UnlockBits(bitmapData);

View File

@@ -44,11 +44,12 @@ namespace OpenRA.Graphics
{
var verticesPerRow = 4*map.Bounds.Width;
var cells = viewport.VisibleCells;
var firstRow = cells.TopLeft.Y - map.Bounds.Top;
var lastRow = cells.BottomRight.Y - map.Bounds.Top + 1;
var shape = wr.world.Map.TileShape;
if (lastRow < 0 || firstRow > map.Bounds.Height)
return;
// Only draw the rows that are visible.
// VisibleCells is clamped to the map, so additional checks are unnecessary
var firstRow = Map.CellToMap(shape, cells.TopLeft).Y - map.Bounds.Top;
var lastRow = Map.CellToMap(shape, cells.BottomRight).Y - map.Bounds.Top + 1;
Game.Renderer.WorldSpriteRenderer.DrawVertexBuffer(
vertexBuffer, verticesPerRow * firstRow, verticesPerRow * (lastRow - firstRow),

View File

@@ -92,8 +92,8 @@ namespace OpenRA.Graphics
var b = map.Bounds;
// Expand to corners of cells
var tl = wr.ScreenPxPosition(map.CenterOfCell(new CPos(b.Left, b.Top)) - new WVec(512, 512, 0));
var br = wr.ScreenPxPosition(map.CenterOfCell(new CPos(b.Right, b.Bottom)) + new WVec(511, 511, 0));
var tl = wr.ScreenPxPosition(map.CenterOfCell(Map.MapToCell(map.TileShape, new CPos(b.Left, b.Top))) - new WVec(512, 512, 0));
var br = wr.ScreenPxPosition(map.CenterOfCell(Map.MapToCell(map.TileShape, new CPos(b.Right, b.Bottom))) + new WVec(511, 511, 0));
mapBounds = Rectangle.FromLTRB(tl.X, tl.Y, br.X, br.Y);
CenterLocation = (tl + br) / 2;
@@ -138,8 +138,13 @@ namespace OpenRA.Graphics
{
get
{
var ctl = worldRenderer.world.Map.CenterOfCell(VisibleCells.TopLeft) - new WVec(512, 512, 0);
var cbr = worldRenderer.world.Map.CenterOfCell(VisibleCells.BottomRight) + new WVec(511, 511, 0);
// Visible rectangle in world coordinates (expanded to the corners of the cells)
// Expand the cordon by an additional cell to account for staggered rows on diamond cell grids.
var map = worldRenderer.world.Map;
var ctl = map.CenterOfCell(VisibleCells.TopLeft) - new WVec(1536, 1536, 0);
var cbr = map.CenterOfCell(VisibleCells.BottomRight) + new WVec(1535, 1535, 0);
// Convert to screen coordinates
var tl = WorldToViewPx(worldRenderer.ScreenPxPosition(ctl)).Clamp(ScreenClip);
var br = WorldToViewPx(worldRenderer.ScreenPxPosition(cbr)).Clamp(ScreenClip);
return Rectangle.FromLTRB(tl.X, tl.Y, br.X, br.Y);
@@ -152,12 +157,16 @@ namespace OpenRA.Graphics
{
if (cellsDirty)
{
// Calculate the intersection of the visible rectangle and the map.
// Visible rectangle in map coordinates
var map = worldRenderer.world.Map;
var tl = map.Clamp(map.CellContaining(worldRenderer.Position(TopLeft)) - new CVec(1, 1));
var br = map.Clamp(map.CellContaining(worldRenderer.Position(BottomRight)));
var ctl = Map.CellToMap(map.TileShape, map.CellContaining(worldRenderer.Position(TopLeft)));
var cbr = Map.CellToMap(map.TileShape, map.CellContaining(worldRenderer.Position(BottomRight)));
cells = new CellRegion(tl, br);
// Add a 2 cell cordon to prevent holes, then convert back to cell coordinates
var tl = map.Clamp(Map.MapToCell(map.TileShape, ctl - new CVec(2, 2)));
var br = map.Clamp(Map.MapToCell(map.TileShape, cbr + new CVec(2, 2)));
cells = new CellRegion(map.TileShape, tl, br);
cellsDirty = false;
}