diff --git a/MLEM/Extensions/TextureExtensions.cs b/MLEM/Extensions/TextureExtensions.cs new file mode 100644 index 0000000..127774b --- /dev/null +++ b/MLEM/Extensions/TextureExtensions.cs @@ -0,0 +1,98 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; + +namespace MLEM.Extensions { + /// + /// A set of extensions for dealing with + /// + public static class TextureExtensions { + + /// + /// Returns a new instance of which allows easily managing a texture's data with texture coordinates rather than indices. + /// + /// The texture whose data to get + /// The texture's data + public static TextureData GetTextureData(this Texture2D texture) { + return new TextureData(texture); + } + + /// + /// A struct that represents the data of a texture, accessed through . + /// + public struct TextureData { + + private readonly Texture2D texture; + private readonly Color[] data; + /// + /// Returns the color at the given x,y position of the texture, where 0,0 represents the bottom left. + /// + /// The x coordinate of the texture location + /// The y coordinate of the texture location + public Color this[int x, int y] { + get => this.data[this.ToIndex(x, y)]; + set => this.data[this.ToIndex(x, y)] = value; + } + /// + public Color this[Point point] { + get => this[point.X, point.Y]; + set => this[point.X, point.Y] = value; + } + + /// + /// Creates a new texture data instance for the given texture. + /// Note that this can more easily be invoked using . + /// + /// The texture whose data to get + public TextureData(Texture2D texture) { + this.texture = texture; + this.data = new Color[texture.Width * texture.Height]; + this.texture.GetData(this.data); + } + + /// + /// Stores this texture data back into the underlying texture + /// + public void Store() { + this.texture.SetData(this.data); + } + + /// + /// Converts the given x,y texture coordinate to the corresponding index in the array. + /// + /// The x coordinate + /// The y coordinate + /// The corresponding texture array index + /// If the given coordinate is out of bounds + public int ToIndex(int x, int y) { + if (!this.IsInBounds(x, y)) + throw new ArgumentException(); + return y * this.texture.Width + x; + } + + /// + /// Converts the given index from the array into the corresponding x,y texture coordinate. + /// + /// The texture array index + /// The corresponding texture coordinate + /// If the given index is out of bounds + public Point FromIndex(int index) { + if (index < 0 || index >= this.data.Length) + throw new ArgumentException(); + return new Point(index % this.texture.Width, index / this.texture.Width); + } + + /// + /// Checks if the given x,y texture coordinates is within the bounds of the underlying texture. + /// + /// The x coordinate + /// The y coordinate + /// Whether the given coordinate is within bounds of the underlying texture + public bool IsInBounds(int x, int y) { + return x >= 0 && y >= 0 && x < this.texture.Width && y < this.texture.Height; + } + + } + + } +} \ No newline at end of file diff --git a/Sandbox/GameImpl.cs b/Sandbox/GameImpl.cs index 21844e0..1dc9f6b 100644 --- a/Sandbox/GameImpl.cs +++ b/Sandbox/GameImpl.cs @@ -62,6 +62,11 @@ namespace Sandbox { }; var tex = this.rawContent.Load("Textures/Test"); + var data = tex.GetTextureData(); + data[1, 9] = Color.Pink; + data[data.FromIndex(data.ToIndex(25, 9))] = Color.Yellow; + data.Store(); + //var font = new GenericSpriteFont(LoadContent("Fonts/TestFont")); var font = new GenericBitmapFont(LoadContent("Fonts/Regular")); this.UiSystem.Style = new UntexturedStyle(this.SpriteBatch) { @@ -126,14 +131,14 @@ namespace Sandbox { this.tokenized = formatter.Tokenize(font, strg); this.tokenized.Split(font, 400, 5); - this.OnDraw += (g, time) => { + /*this.OnDraw += (g, time) => { this.SpriteBatch.Begin(samplerState: SamplerState.PointClamp); this.SpriteBatch.FillRectangle(new RectangleF(400, 20, 400, 1000), Color.Green); font.DrawString(this.SpriteBatch, this.tokenized.DisplayString, new Vector2(400, 20), Color.White * 0.25F, 0, Vector2.Zero, 5, SpriteEffects.None, 0); this.tokenized.Draw(time, this.SpriteBatch, new Vector2(400, 20), font, Color.White, 5, 0); this.SpriteBatch.DrawGrid(new Vector2(30, 30), new Vector2(40, 60), new Point(10, 5), Color.Yellow, 3); this.SpriteBatch.End(); - }; + };*/ this.OnUpdate += (g, time) => { if (this.InputHandler.IsPressed(Keys.W)) { this.tokenized = formatter.Tokenize(font, strg);