From 31fb855a43eef8f8354e4d45f5bebe6dbcb0d9d1 Mon Sep 17 00:00:00 2001 From: Ellpeck Date: Fri, 9 Aug 2019 15:15:22 +0200 Subject: [PATCH] added ninepatch and textureregion classes --- MLEM.Extended/Extensions/TextureExtensions.cs | 24 +++++++ MLEM.Startup/MLEM.Startup.csproj | 1 + MLEM/Textures/NinePatch.cs | 70 +++++++++++++++++++ MLEM/Textures/TextureRegion.cs | 56 +++++++++++++++ Tests/Content/Content.mgcb | 27 +++++++ Tests/GameImpl.cs | 32 +++++++++ Tests/Tests.csproj | 14 ++-- 7 files changed, 220 insertions(+), 4 deletions(-) create mode 100644 MLEM.Extended/Extensions/TextureExtensions.cs create mode 100644 MLEM/Textures/NinePatch.cs create mode 100644 MLEM/Textures/TextureRegion.cs create mode 100644 Tests/Content/Content.mgcb diff --git a/MLEM.Extended/Extensions/TextureExtensions.cs b/MLEM.Extended/Extensions/TextureExtensions.cs new file mode 100644 index 0000000..c65606d --- /dev/null +++ b/MLEM.Extended/Extensions/TextureExtensions.cs @@ -0,0 +1,24 @@ +using MLEM.Textures; +using MonoGame.Extended.TextureAtlases; + +namespace MLEM.Extended.Extensions { + public static class TextureExtensions { + + public static NinePatchRegion2D ToExtended(this NinePatch patch) { + return new NinePatchRegion2D(patch.Region.ToExtended(), patch.PaddingLeft, patch.PaddingTop, patch.PaddingRight, patch.PaddingBottom); + } + + public static TextureRegion2D ToExtended(this TextureRegion region) { + return new TextureRegion2D(region.Texture, region.U, region.V, region.Width, region.Height); + } + + public static NinePatch ToMlem(this NinePatchRegion2D patch) { + return new NinePatch(new TextureRegion(patch.Texture, patch.Bounds), patch.LeftPadding, patch.RightPadding, patch.TopPadding, patch.BottomPadding); + } + + public static TextureRegion ToMlem(this TextureRegion2D region) { + return new TextureRegion(region.Texture, region.Bounds); + } + + } +} \ No newline at end of file diff --git a/MLEM.Startup/MLEM.Startup.csproj b/MLEM.Startup/MLEM.Startup.csproj index f9b8de4..03110cd 100644 --- a/MLEM.Startup/MLEM.Startup.csproj +++ b/MLEM.Startup/MLEM.Startup.csproj @@ -16,6 +16,7 @@ + all diff --git a/MLEM/Textures/NinePatch.cs b/MLEM/Textures/NinePatch.cs new file mode 100644 index 0000000..9fa5afd --- /dev/null +++ b/MLEM/Textures/NinePatch.cs @@ -0,0 +1,70 @@ +using System.Collections.Generic; +using System.Linq; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; + +namespace MLEM.Textures { + public class NinePatch { + + public readonly TextureRegion Region; + public readonly int PaddingLeft; + public readonly int PaddingRight; + public readonly int PaddingTop; + public readonly int PaddingBottom; + + public readonly Rectangle[] SourceRectangles; + + public NinePatch(TextureRegion texture, int paddingLeft, int paddingRight, int paddingTop, int paddingBottom) { + this.Region = texture; + this.PaddingLeft = paddingLeft; + this.PaddingRight = paddingRight; + this.PaddingTop = paddingTop; + this.PaddingBottom = paddingBottom; + this.SourceRectangles = this.CreateRectangles(this.Region.Area).ToArray(); + } + + public NinePatch(Texture2D texture, int paddingLeft, int paddingRight, int paddingTop, int paddingBottom) : + this(new TextureRegion(texture), paddingLeft, paddingRight, paddingTop, paddingBottom) { + } + + public NinePatch(TextureRegion texture, int padding) : this(texture, padding, padding, padding, padding) { + } + + public IEnumerable CreateRectangles(Rectangle area) { + var centerW = area.Width - this.PaddingLeft - this.PaddingRight; + var centerH = area.Height - this.PaddingTop - this.PaddingBottom; + var leftX = area.X + this.PaddingLeft; + var rightX = area.X + area.Width - this.PaddingRight; + var topY = area.Y + this.PaddingTop; + var bottomY = area.Y + area.Height - this.PaddingBottom; + + yield return new Rectangle(area.X, area.Y, this.PaddingLeft, this.PaddingTop); + yield return new Rectangle(leftX, area.Y, centerW, this.PaddingTop); + yield return new Rectangle(rightX, area.Y, this.PaddingRight, this.PaddingTop); + yield return new Rectangle(area.X, topY, this.PaddingLeft, centerH); + yield return new Rectangle(leftX, topY, centerW, centerH); + yield return new Rectangle(rightX, topY, this.PaddingRight, centerH); + yield return new Rectangle(area.X, bottomY, this.PaddingLeft, this.PaddingBottom); + yield return new Rectangle(leftX, bottomY, centerW, this.PaddingBottom); + yield return new Rectangle(rightX, bottomY, this.PaddingRight, this.PaddingBottom); + } + + } + + public static class NinePatchExtensions { + + public static void Draw(this SpriteBatch batch, NinePatch texture, Rectangle destinationRectangle, Color color, float rotation, Vector2 origin, SpriteEffects effects, float layerDepth) { + var dest = texture.CreateRectangles(destinationRectangle); + var count = 0; + foreach (var rect in dest) { + batch.Draw(texture.Region.Texture, rect, texture.SourceRectangles[count], color, rotation, origin, effects, layerDepth); + count++; + } + } + + public static void Draw(this SpriteBatch batch, NinePatch texture, Rectangle destinationRectangle, Color color) { + batch.Draw(texture, destinationRectangle, color, 0, Vector2.Zero, SpriteEffects.None, 0); + } + + } +} \ No newline at end of file diff --git a/MLEM/Textures/TextureRegion.cs b/MLEM/Textures/TextureRegion.cs new file mode 100644 index 0000000..91abd3e --- /dev/null +++ b/MLEM/Textures/TextureRegion.cs @@ -0,0 +1,56 @@ +using System.Diagnostics.Tracing; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; + +namespace MLEM.Textures { + public class TextureRegion { + + public readonly Texture2D Texture; + public readonly Rectangle Area; + public Point Position => this.Area.Location; + public int U => this.Area.X; + public int V => this.Area.Y; + public Point Size => this.Area.Size; + public int Width => this.Area.Width; + public int Height => this.Area.Height; + + public TextureRegion(Texture2D texture, Rectangle area) { + this.Texture = texture; + this.Area = area; + } + + public TextureRegion(Texture2D texture) : this(texture, new Rectangle(0, 0, texture.Width, texture.Height)) { + } + + public TextureRegion(Texture2D texture, int u, int v, int width, int height) : this(texture, new Rectangle(u, v, width, height)) { + } + + public TextureRegion(Texture2D texture, Point uv, Point size) : this(texture, new Rectangle(uv, size)) { + } + + } + + public static class TextureRegionExtensions { + + public static void Draw(this SpriteBatch batch, TextureRegion texture, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth) { + batch.Draw(texture.Texture, position, texture.Area, color, rotation, origin, scale, effects, layerDepth); + } + + public static void Draw(this SpriteBatch batch, TextureRegion texture, Vector2 position, Color color, float rotation, Vector2 origin, float scale, SpriteEffects effects, float layerDepth) { + batch.Draw(texture, position, color, rotation, origin, new Vector2(scale), SpriteEffects.None, 0); + } + + public static void Draw(this SpriteBatch batch, TextureRegion texture, Rectangle destinationRectangle, Color color, float rotation, Vector2 origin, SpriteEffects effects, float layerDepth) { + batch.Draw(texture.Texture, destinationRectangle, texture.Area, color, rotation, origin, effects, layerDepth); + } + + public static void Draw(this SpriteBatch batch, TextureRegion texture, Vector2 position, Color color) { + batch.Draw(texture, position, color, 0, Vector2.Zero, Vector2.One, SpriteEffects.None, 0); + } + + public static void Draw(this SpriteBatch batch, TextureRegion texture, Rectangle destinationRectangle, Color color) { + batch.Draw(texture, destinationRectangle, color, 0, Vector2.Zero, SpriteEffects.None, 0); + } + + } +} \ No newline at end of file diff --git a/Tests/Content/Content.mgcb b/Tests/Content/Content.mgcb new file mode 100644 index 0000000..d80adce --- /dev/null +++ b/Tests/Content/Content.mgcb @@ -0,0 +1,27 @@ + +#----------------------------- Global Properties ----------------------------# + +/outputDir:bin +/intermediateDir:obj +/platform:DesktopGL +/config: +/profile:Reach +/compress:False + +#-------------------------------- References --------------------------------# + + +#---------------------------------- Content ---------------------------------# + +#begin Textures/Test.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/Test.png + diff --git a/Tests/GameImpl.cs b/Tests/GameImpl.cs index ba63c6a..57bcceb 100644 --- a/Tests/GameImpl.cs +++ b/Tests/GameImpl.cs @@ -1,12 +1,29 @@ using System; using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; +using MLEM.Extended.Extensions; using MLEM.Input; using MLEM.Startup; +using MLEM.Textures; +using MonoGame.Extended.TextureAtlases; namespace Tests { public class GameImpl : MlemGame { + private Texture2D testTexture; + private TextureRegion testRegion; + private NinePatch testPatch; + private NinePatchRegion2D extendedPatch; + + protected override void LoadContent() { + base.LoadContent(); + this.testTexture = LoadContent("Textures/Test"); + this.testRegion = new TextureRegion(this.testTexture, 32, 0, 8, 8); + this.testPatch = new NinePatch(new TextureRegion(this.testTexture, 0, 8, 24, 24), 8); + this.extendedPatch = this.testPatch.ToExtended(); + } + protected override void Update(GameTime gameTime) { base.Update(gameTime); @@ -19,5 +36,20 @@ namespace Tests { Console.WriteLine("Gamepad A was pressed"); } + protected override void Draw(GameTime gameTime) { + base.Draw(gameTime); + this.GraphicsDevice.Clear(Color.Black); + + // Texture region tests + this.SpriteBatch.Begin(samplerState: SamplerState.PointClamp); + this.SpriteBatch.Draw(this.testRegion, new Vector2(10, 10), Color.White); + this.SpriteBatch.Draw(this.testRegion, new Vector2(30, 10), Color.White, 0, Vector2.Zero, 10, SpriteEffects.None, 0); + this.SpriteBatch.End(); + this.SpriteBatch.Begin(samplerState: SamplerState.PointClamp, transformMatrix: Matrix.CreateScale(10)); + this.SpriteBatch.Draw(this.testPatch, new Rectangle(20, 20, 40, 20), Color.White); + this.SpriteBatch.Draw(this.extendedPatch, new Rectangle(80, 20, 40, 20), Color.White); + this.SpriteBatch.End(); + } + } } \ No newline at end of file diff --git a/Tests/Tests.csproj b/Tests/Tests.csproj index 6ff6d48..82aed58 100644 --- a/Tests/Tests.csproj +++ b/Tests/Tests.csproj @@ -6,13 +6,19 @@ - - - + + + - + + + + + + +