From fe89fc24eab19bada0942a35ee6b8a28e0282e87 Mon Sep 17 00:00:00 2001 From: Ellpeck Date: Fri, 24 Jul 2020 00:33:11 +0200 Subject: [PATCH] added data-based texture atlases --- MLEM/Textures/DataTextureAtlas.cs | 92 +++++++++++++++++++++++ Sandbox/Content/Content.mgcb | 15 ++++ Sandbox/Content/Textures/Furniture.atlas | 16 ++++ Sandbox/Content/Textures/Furniture.png | Bin 0 -> 3241 bytes Sandbox/GameImpl.cs | 5 ++ Sandbox/Sandbox.csproj | 6 ++ 6 files changed, 134 insertions(+) create mode 100644 MLEM/Textures/DataTextureAtlas.cs create mode 100644 Sandbox/Content/Textures/Furniture.atlas create mode 100644 Sandbox/Content/Textures/Furniture.png diff --git a/MLEM/Textures/DataTextureAtlas.cs b/MLEM/Textures/DataTextureAtlas.cs new file mode 100644 index 0000000..1c746da --- /dev/null +++ b/MLEM/Textures/DataTextureAtlas.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Text.RegularExpressions; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; + +namespace MLEM.Textures { + /// + /// This class represents an atlas of objects which are loaded from a special texture atlas file. + /// To load a data texture atlas, you can use . + /// + public class DataTextureAtlas { + + /// + /// The texture to use for this atlas + /// + public readonly Texture2D Texture; + /// + /// Returns the texture region with the given name. + /// + /// The region's name + public TextureRegion this[string name] => this.regions[name]; + /// + /// Returns an enumerable of all of the s in this atlas. + /// + public IEnumerable Regions => this.regions.Values; + + private readonly Dictionary regions = new Dictionary(); + + /// + /// Creates a new data texture atlas with the given texture and region amount. + /// + /// The texture to use for this atlas + public DataTextureAtlas(Texture2D texture) { + this.Texture = texture; + } + + internal static DataTextureAtlas Load(ContentManager content, string texturePath, string infoPath, bool pivotRelative) { + var info = new FileInfo(Path.Combine(content.RootDirectory, infoPath ?? $"{texturePath}.atlas")); + string text; + using (var reader = info.OpenText()) + text = reader.ReadToEnd(); + + var texture = content.Load(texturePath); + var atlas = new DataTextureAtlas(texture); + + // parse each texture region: " loc piv " + const string regex = @"(.+)\W+loc\W+([0-9]+)\W+([0-9]+)\W+([0-9]+)\W+([0-9]+)\W+(?:piv\W+([0-9.]+)\W+([0-9.]+))?"; + foreach (Match match in Regex.Matches(text, regex)) { + var name = match.Groups[1].Value.Trim(); + var loc = new Rectangle( + int.Parse(match.Groups[2].Value), int.Parse(match.Groups[3].Value), + int.Parse(match.Groups[4].Value), int.Parse(match.Groups[5].Value)); + var piv = Vector2.Zero; + if (match.Groups[6].Success) { + piv = new Vector2( + float.Parse(match.Groups[6].Value, CultureInfo.InvariantCulture) - (pivotRelative ? 0 : loc.X), + float.Parse(match.Groups[7].Value, CultureInfo.InvariantCulture) - (pivotRelative ? 0 : loc.Y)); + } + atlas.regions.Add(name, new TextureRegion(texture, loc) { + PivotPixels = piv, + Name = name + }); + } + + return atlas; + } + + } + + /// + /// A set of extension methods for dealing with . + /// + public static class DataTextureAtlasExtensions { + + /// + /// Loads a from the given texture and texture data file. + /// + /// The content manager to use for loading + /// The path to the texture file + /// The path, including extension, to the atlas info file, or null if ".atlas" should be used + /// If this value is true, then the pivot points passed in the info file will be relative to the coordinates of the texture region, not relative to the entire texture's origin. + /// A new data texture atlas with the given settings + public static DataTextureAtlas LoadTextureAtlas(this ContentManager content, string texturePath, string infoPath = null, bool pivotRelative = false) { + return DataTextureAtlas.Load(content, texturePath, infoPath, pivotRelative); + } + + } +} \ No newline at end of file diff --git a/Sandbox/Content/Content.mgcb b/Sandbox/Content/Content.mgcb index b3ff1d0..e4b5d48 100644 --- a/Sandbox/Content/Content.mgcb +++ b/Sandbox/Content/Content.mgcb @@ -41,6 +41,21 @@ #begin Test.json /copy:Test.json +#begin Textures/Furniture.atlas +/copy:Textures/Furniture.atlas + +#begin Textures/Furniture.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:Textures/Furniture.png + #begin Tiled/Map.tmx /importer:TiledMapImporter /processor:TiledMapProcessor diff --git a/Sandbox/Content/Textures/Furniture.atlas b/Sandbox/Content/Textures/Furniture.atlas new file mode 100644 index 0000000..9bc74c8 --- /dev/null +++ b/Sandbox/Content/Textures/Furniture.atlas @@ -0,0 +1,16 @@ +SimpleDeskUp +loc 0 0 48 32 +piv 16 16 +SimpleDeskRight +loc 48 0 48 32 +piv 80 16 + +Plant +loc 96 0 16 32 + +LongTableUp +loc 0 32 64 48 +piv 16 48 +LongTableRight +loc 64 32 64 48 +piv 112 48 \ No newline at end of file diff --git a/Sandbox/Content/Textures/Furniture.png b/Sandbox/Content/Textures/Furniture.png new file mode 100644 index 0000000000000000000000000000000000000000..2aae963590cef9413526815680edc932c42a1a62 GIT binary patch literal 3241 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 literal 0 HcmV?d00001 diff --git a/Sandbox/GameImpl.cs b/Sandbox/GameImpl.cs index c811dc1..bb9e9a1 100644 --- a/Sandbox/GameImpl.cs +++ b/Sandbox/GameImpl.cs @@ -143,6 +143,11 @@ namespace Sandbox { var region = new TextureRegion(round) {Pivot = new Vector2(0.5F)}; var region2 = new TextureRegion(round); + var atlas = this.Content.LoadTextureAtlas("Textures/Furniture"); + foreach (var r in atlas.Regions) { + Console.WriteLine(r.Name + ": " + r.U + " " + r.V + " " + r.Width + " " + r.Height + " " + r.PivotPixels); + } + this.OnDraw += (g, time) => { this.SpriteBatch.Begin(samplerState: SamplerState.PointClamp); //this.SpriteBatch.Draw(square, new Rectangle(10, 10, 400, 400), Color.White); diff --git a/Sandbox/Sandbox.csproj b/Sandbox/Sandbox.csproj index 45565c1..5ef7fce 100644 --- a/Sandbox/Sandbox.csproj +++ b/Sandbox/Sandbox.csproj @@ -25,6 +25,12 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest +