From 98937ee83fba3971cc1b2815b6502ae94f4b4bf1 Mon Sep 17 00:00:00 2001 From: Ellpeck Date: Sun, 12 Jul 2020 19:41:25 +0200 Subject: [PATCH] added a method for generating square and circle textures --- MLEM/Extensions/SpriteBatchExtensions.cs | 64 +++++++++++++++++++----- MLEM/Extensions/TextureExtensions.cs | 8 ++- Sandbox/GameImpl.cs | 23 ++++++--- 3 files changed, 73 insertions(+), 22 deletions(-) diff --git a/MLEM/Extensions/SpriteBatchExtensions.cs b/MLEM/Extensions/SpriteBatchExtensions.cs index 93be9ca..d31e517 100644 --- a/MLEM/Extensions/SpriteBatchExtensions.cs +++ b/MLEM/Extensions/SpriteBatchExtensions.cs @@ -1,3 +1,4 @@ +using System; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using MLEM.Misc; @@ -21,18 +22,14 @@ namespace MLEM.Extensions { if (blankTexture == null) { blankTexture = new Texture2D(batch.GraphicsDevice, 1, 1); blankTexture.SetData(new[] {Color.White}); - batch.Disposing += (sender, args) => { - if (blankTexture != null) { - blankTexture.Dispose(); - blankTexture = null; - } - }; + AutoDispose(batch, blankTexture); } return blankTexture; } /// - /// Generates a that has a texture with a given color and outline color + /// Generates a that has a texture with a given color and outline color. + /// This texture is automatically disposed of when the batch is disposed. /// /// The sprite batch /// The fill color of the texture @@ -46,15 +43,47 @@ namespace MLEM.Extensions { outli, color, outli, outli, outli, outli }); - batch.Disposing += (sender, args) => { - if (tex != null) { - tex.Dispose(); - tex = null; - } - }; + AutoDispose(batch, tex); return new NinePatch(tex, 1); } + /// + /// Generates a 1x1 texture with the given color. + /// This texture is automatically disposed of when the batch is disposed. + /// + /// The sprite batch + /// The color of the texture + /// A new texture with the given data + public static Texture2D GenerateSquareTexture(this SpriteBatch batch, Color color) { + var tex = new Texture2D(batch.GraphicsDevice, 1, 1); + tex.SetData(new[] {color}); + AutoDispose(batch, tex); + return tex; + } + + /// + /// Generates a texture with the given size that contains a circle. + /// The circle's center will be the center of the texture, and the circle will lead up to the edges of the texture. + /// This texture is automatically disposed of when the batch is disposed. + /// + /// The sprite batch + /// The color of the texture + /// The width and height of the texture, and the diameter of the circle + /// A new texture with the given data + public static Texture2D GenerateCircleTexture(this SpriteBatch batch, Color color, int size) { + var tex = new Texture2D(batch.GraphicsDevice, size, size); + using (var data = tex.GetTextureData()) { + for (var x = 0; x < tex.Width; x++) { + for (var y = 0; y < tex.Height; y++) { + var dist = Vector2.Distance(new Vector2(size / 2), new Vector2(x, y)); + data[x, y] = dist <= size / 2 ? color : Color.Transparent; + } + } + } + AutoDispose(batch, tex); + return tex; + } + /// public static void Draw(this SpriteBatch batch, Texture2D texture, RectangleF destinationRectangle, Rectangle? sourceRectangle, Color color, float rotation, Vector2 origin, SpriteEffects effects, float layerDepth) { var source = sourceRectangle ?? new Rectangle(0, 0, texture.Width, texture.Height); @@ -72,5 +101,14 @@ namespace MLEM.Extensions { batch.Draw(texture, destinationRectangle, null, color); } + private static void AutoDispose(SpriteBatch batch, Texture2D texture) { + batch.Disposing += (sender, ars) => { + if (texture != null) { + texture.Dispose(); + texture = null; + } + }; + } + } } \ No newline at end of file diff --git a/MLEM/Extensions/TextureExtensions.cs b/MLEM/Extensions/TextureExtensions.cs index 127774b..977670c 100644 --- a/MLEM/Extensions/TextureExtensions.cs +++ b/MLEM/Extensions/TextureExtensions.cs @@ -10,6 +10,7 @@ namespace MLEM.Extensions { /// /// Returns a new instance of which allows easily managing a texture's data with texture coordinates rather than indices. + /// When this is used in a using statement, the texture data is automatically stored back in the texture at the end. /// /// The texture whose data to get /// The texture's data @@ -20,7 +21,7 @@ namespace MLEM.Extensions { /// /// A struct that represents the data of a texture, accessed through . /// - public struct TextureData { + public class TextureData : IDisposable { private readonly Texture2D texture; private readonly Color[] data; @@ -92,6 +93,11 @@ namespace MLEM.Extensions { return x >= 0 && y >= 0 && x < this.texture.Width && y < this.texture.Height; } + /// + public void Dispose() { + this.Store(); + } + } } diff --git a/Sandbox/GameImpl.cs b/Sandbox/GameImpl.cs index e0d8bbf..cc6c8ea 100644 --- a/Sandbox/GameImpl.cs +++ b/Sandbox/GameImpl.cs @@ -61,10 +61,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(); + using (var data = tex.GetTextureData()) { + var textureData = data; + textureData[1, 9] = Color.Pink; + textureData[textureData.FromIndex(textureData.ToIndex(25, 9))] = Color.Yellow; + } //var font = new GenericSpriteFont(LoadContent("Fonts/TestFont")); var font = new GenericBitmapFont(LoadContent("Fonts/Regular")); @@ -134,12 +135,18 @@ namespace Sandbox { this.tokenized = formatter.Tokenize(font, strg); this.tokenized.Split(font, 400, sc); + var square = this.SpriteBatch.GenerateSquareTexture(Color.Yellow); + var round = this.SpriteBatch.GenerateCircleTexture(Color.Green, 1024); + 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, sc, SpriteEffects.None, 0); - this.tokenized.Draw(time, this.SpriteBatch, new Vector2(400, 20), font, Color.White, sc, 0); - this.SpriteBatch.DrawGrid(new Vector2(30, 30), new Vector2(40, 60), new Point(10, 5), Color.Yellow, 3); + this.SpriteBatch.Draw(square, new Rectangle(10, 10, 400, 400), Color.White); + this.SpriteBatch.Draw(round, new Rectangle(10, 10, 400, 400), Color.White); + + //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, sc, SpriteEffects.None, 0); + //this.tokenized.Draw(time, this.SpriteBatch, new Vector2(400, 20), font, Color.White, sc, 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) => {