Kav/Data/TextureAtlas.cs

97 lines
2.7 KiB
C#

using Kav.Data;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System.Collections.Generic;
using System.IO;
namespace Kav
{
public struct TextureAtlasSlice
{
public int X { get; }
public int Y { get; }
public int W { get; }
public int H { get; }
public UVData UVData { get; }
// for use with tiling
public Vector2 TiledUVOffset { get; }
public TextureAtlasSlice(int x, int y, int w, int h, int totalW, int totalH)
{
X = x;
Y = y;
W = w;
H = h;
UVData = new UVData(new Vector2(x, y), new Vector2(w, h), new Vector2(totalW, totalH));
TiledUVOffset = new Vector2(x / (float)totalW, y / (float)totalH);
}
}
public class TextureAtlas
{
public Texture2D Texture { get; }
protected List<string> Names { get; } = new List<string>();
protected Dictionary<string, TextureAtlasSlice> Slices { get; } = new Dictionary<string, TextureAtlasSlice>();
public TextureAtlas(GraphicsDevice graphicsDevice, FileInfo atlasMetadataFile)
{
var atlasData = CrunchAtlasReader.ReadTextureAtlas(atlasMetadataFile);
var textureData = atlasData.Textures[0];
using var stream = File.OpenRead(Path.Combine(atlasMetadataFile.DirectoryName, textureData.Name + ".png"));
Texture = Texture2D.FromStream(graphicsDevice, stream);
foreach (var slice in textureData.Images)
{
Names.Add(slice.N);
Slices.Add(
slice.N,
new TextureAtlasSlice(
slice.X,
slice.Y,
slice.W,
slice.H,
Texture.Width,
Texture.Height
)
);
}
}
public TextureAtlasSlice Lookup(string name)
{
return Slices[name];
}
public string Name(int index)
{
return Names[index];
}
public int Count()
{
return Names.Count;
}
}
// Assumes all subimages are the same size
public class TiledTextureAtlas : TextureAtlas
{
public int NumRows { get; }
public int NumColumns { get; }
public TiledTextureAtlas(GraphicsDevice graphicsDevice, FileInfo atlasMetadataFile) : base(graphicsDevice, atlasMetadataFile)
{
var subImageSlice = Slices[Names[0]];
NumRows = Texture.Height / subImageSlice.H;
NumColumns = Texture.Width / subImageSlice.W;
}
}
}