126 lines
3.7 KiB
C#
126 lines
3.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Media;
|
|
using System.Windows.Media.Imaging;
|
|
using TransportGame.Model;
|
|
|
|
namespace TransportGame.MapViewer
|
|
{
|
|
public class MapRenderer
|
|
{
|
|
[Flags]
|
|
public enum Layers
|
|
{
|
|
None = 0,
|
|
Elevation = 1,
|
|
All = Elevation
|
|
};
|
|
|
|
/// <summary>
|
|
/// Gets or sets the scale
|
|
/// </summary>
|
|
private int _scale;
|
|
public int Scale
|
|
{
|
|
get
|
|
{
|
|
return _scale;
|
|
}
|
|
set
|
|
{
|
|
lock (this)
|
|
{
|
|
_scale = value;
|
|
}
|
|
}
|
|
}
|
|
|
|
private readonly Color WaterColor = Colors.Navy;
|
|
private readonly Color ElevationTerrainColor = Colors.White;
|
|
private readonly Color TerrainColor = Colors.White;
|
|
|
|
public MapRenderer()
|
|
{
|
|
Scale = 4;
|
|
}
|
|
|
|
///<summary>
|
|
///Renders a map to a file
|
|
///</summary>
|
|
///<param name="file"></param>
|
|
///<param name="map"></param>
|
|
///<param name="layers"></param>
|
|
public Color[,] Render(Map map, Layers layers = Layers.All)
|
|
{
|
|
lock (this)
|
|
{
|
|
// Create texture on which to draw
|
|
Color[,] pixels = new Color[map.Width * Scale, map.Height * Scale];
|
|
|
|
// First layer - cells
|
|
DrawCells(pixels, map, (layers & Layers.Elevation) > 0);
|
|
|
|
// Done
|
|
return pixels;
|
|
}
|
|
}
|
|
|
|
private void DrawCells(Color[,] pixels, Map map, bool elevation)
|
|
{
|
|
for (int x = 0; x < pixels.GetLength(0); x++)
|
|
for (int y = 0; y < pixels.GetLength(1); y++)
|
|
{
|
|
int mapX = x / Scale;
|
|
int mapY = y / Scale;
|
|
|
|
// Draw water
|
|
if (map.IsWater(mapX, mapY))
|
|
pixels[x, y] = WaterColor;
|
|
|
|
// Draw elevation
|
|
else if (elevation)
|
|
{
|
|
float alpha = (map[mapX, mapY] - map.Biome.HeightRange.Minimum) / (map.Biome.HeightRange.Maximum - map.Biome.HeightRange.Minimum);
|
|
pixels[x, y] = Color.Multiply(ElevationTerrainColor, alpha);
|
|
}
|
|
|
|
// Draw terrain
|
|
else
|
|
{
|
|
pixels[x, y] = TerrainColor;
|
|
}
|
|
}
|
|
}
|
|
|
|
public async Task<BitmapSource> RenderToImageSource(Map map, Layers layers = Layers.All)
|
|
{
|
|
var colors = await Task.Run(() => Render(map, layers));
|
|
colors[0, 0] = Colors.Red;
|
|
colors[colors.GetLength(0) - 1, 0] = Colors.Red;
|
|
|
|
// Convert to raw pixels
|
|
byte[] raw = new byte[colors.GetLength(0) * colors.GetLength(1) * 3];
|
|
|
|
for (int x = 0; x < colors.GetLength(0); x++)
|
|
for (int y = 0; y < colors.GetLength(1); y++)
|
|
{
|
|
int pixelIndex = x + y * colors.GetLength(0);
|
|
|
|
raw[3 * pixelIndex] = colors[x, y].R;
|
|
raw[3 * pixelIndex + 1] = colors[x, y].G;
|
|
raw[3 * pixelIndex + 2] = colors[x, y].B;
|
|
}
|
|
|
|
// Create bitmap source
|
|
BitmapSource bmp = BitmapSource.Create(colors.GetLength(0), colors.GetLength(1),
|
|
96, 96, PixelFormats.Rgb24, null, raw, colors.GetLength(0) * 3);
|
|
|
|
return bmp;
|
|
}
|
|
}
|
|
}
|