From 4add103f949af24d6a94d111c502e178d778baa2 Mon Sep 17 00:00:00 2001 From: Recrown Date: Sun, 10 Mar 2019 00:50:03 -0600 Subject: [PATCH] Added sprite batch settings to maintain sprite batch begin settings and keep consistency and control over settings. Ninepatch uses this. --- RecrownedAthenaeum/Configuration.cs | 5 +- RecrownedAthenaeum/RecrownedAthenaeum.csproj | 1 + .../Render/SpriteBatchSettings.cs | 61 +++++++++++++++++++ .../ScreenSystem/ScreenManager.cs | 38 ++++++------ RecrownedAthenaeum/SpecialTypes/NinePatch.cs | 44 ++++++++----- .../SpecialTypes/TextureAtlas.cs | 2 +- 6 files changed, 113 insertions(+), 38 deletions(-) create mode 100644 RecrownedAthenaeum/Render/SpriteBatchSettings.cs diff --git a/RecrownedAthenaeum/Configuration.cs b/RecrownedAthenaeum/Configuration.cs index 416134e..4f2e0e7 100644 --- a/RecrownedAthenaeum/Configuration.cs +++ b/RecrownedAthenaeum/Configuration.cs @@ -1,5 +1,6 @@ using Microsoft.Xna.Framework; using RecrownedAthenaeum.Camera; +using RecrownedAthenaeum.Render; using RecrownedAthenaeum.ScreenSystem; using System; @@ -23,10 +24,10 @@ namespace RecrownedAthenaeum /// public static Camera2D Camera2D { set { camera2D = value; } get { if (camera2D == null) throw new InvalidOperationException("2D camera property requested as substitute but configuration does not have one."); return camera2D; } } - private static BeginBatch beginBatchFunction; + private static SpriteBatchSettings? beginBatchFunction; /// /// The begin sprite batch to use for custom begins and consistency. /// - public static BeginBatch BeginBatchFunction { set { beginBatchFunction = value; } get { if (beginBatchFunction == null) throw new InvalidOperationException("No default begin batch has been set yet has been requested."); return beginBatchFunction; } } + public static SpriteBatchSettings? spriteBatchSettings { set { beginBatchFunction = value.Value; } get { if (!beginBatchFunction.HasValue) throw new InvalidOperationException("No default begin batch has been set yet has been requested."); return beginBatchFunction; } } } } diff --git a/RecrownedAthenaeum/RecrownedAthenaeum.csproj b/RecrownedAthenaeum/RecrownedAthenaeum.csproj index 87b1f4a..fccb30f 100644 --- a/RecrownedAthenaeum/RecrownedAthenaeum.csproj +++ b/RecrownedAthenaeum/RecrownedAthenaeum.csproj @@ -51,6 +51,7 @@ + diff --git a/RecrownedAthenaeum/Render/SpriteBatchSettings.cs b/RecrownedAthenaeum/Render/SpriteBatchSettings.cs new file mode 100644 index 0000000..79e1135 --- /dev/null +++ b/RecrownedAthenaeum/Render/SpriteBatchSettings.cs @@ -0,0 +1,61 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace RecrownedAthenaeum.Render +{ + /// + /// The settings the sprite batch should use. + /// + public struct SpriteBatchSettings + { + /// + /// Defines sprites sort mode. + /// + public SpriteSortMode spriteSortMode; + + /// + /// The blend state to use. + /// + public BlendState blendState; + + /// + /// Sampler state to use. + /// + public SamplerState samplerState; + + /// + /// The depth stencil state to use. + /// + public DepthStencilState depthStencilState; + + /// + /// The rasterizer state to use. + /// + public RasterizerState rasterizerState; + + /// + /// The effect to use. + /// + public Effect effect; + + /// + /// The transformation matrix to use. + /// + public Matrix transformMatrix; + + + /// + /// Begins the given sprite batch with the current set of settings. + /// + /// Begins the spritebatch with the given settings. + public void BeginSpriteBatch(SpriteBatch spriteBatch) + { + spriteBatch.Begin(spriteSortMode, blendState, samplerState, depthStencilState, rasterizerState, effect, transformMatrix); + } + } +} diff --git a/RecrownedAthenaeum/ScreenSystem/ScreenManager.cs b/RecrownedAthenaeum/ScreenSystem/ScreenManager.cs index 50a389a..8cce222 100644 --- a/RecrownedAthenaeum/ScreenSystem/ScreenManager.cs +++ b/RecrownedAthenaeum/ScreenSystem/ScreenManager.cs @@ -1,6 +1,7 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using RecrownedAthenaeum.Camera; +using RecrownedAthenaeum.Render; using System; using System.Diagnostics; @@ -12,12 +13,6 @@ namespace RecrownedAthenaeum.ScreenSystem /// The screen to show after the loading screen. public delegate void ShowFirstScreen(Screen screen); - /// - /// Custom spritebatch begin call. - /// - /// - public delegate void BeginBatch(SpriteBatch spriteBatch); - /// /// A manager for screens. Helps with transitions and updating screens as well as resizes. /// @@ -31,9 +26,9 @@ namespace RecrownedAthenaeum.ScreenSystem public event ShowFirstScreen ShowFirstScreenEvent; /// - /// The function to call that begins the batch. + /// The settings this manager will use to begin a sprite batch. /// - public BeginBatch beginBatchFunc; + public SpriteBatchSettings batchSettings; private GraphicsDeviceManager graphics; private Screen previousScreen; @@ -77,16 +72,24 @@ namespace RecrownedAthenaeum.ScreenSystem /// /// The camera to be used to perform the correct translations and transformations. Will use default set in if left null. /// The graphics device manager to be used. Will use default set in if left null. - /// The function to call to begin a batch to be used generally. Will use the built-in one in screen manager if not provided. - public ScreenManager(Camera2D camera = null, GraphicsDeviceManager graphicsDeviceManager = null, BeginBatch beginBatchFunction = null) + /// The settings to begin spritebatch with. Will use the built-in one in screen manager if not provided. + public ScreenManager(Camera2D camera = null, GraphicsDeviceManager graphicsDeviceManager = null, SpriteBatchSettings? spriteBatchSettings = null) { - if (beginBatchFunction == null) beginBatchFunction = BasicBeginBatch; + if (camera == null) camera = Configuration.Camera2D; + if (!spriteBatchSettings.HasValue) + { + SpriteBatchSettings basicSettings = new SpriteBatchSettings(); + basicSettings.effect = camera.BasicEffect; + basicSettings.blendState = BlendState.Additive; + basicSettings.samplerState = null; + spriteBatchSettings = basicSettings; + } if (graphicsDeviceManager == null) graphicsDeviceManager = Configuration.GraphicsDeviceManager; graphics = graphicsDeviceManager ?? throw new ArgumentNullException("Graphics device manager argument cannot be null if setup's graphics device manager is also null."); this.camera = camera ?? throw new ArgumentNullException("2d camera argument cannot be null if setup's 2d camera is also null."); - beginBatchFunc = beginBatchFunction; + batchSettings = spriteBatchSettings.Value; } /// @@ -144,13 +147,13 @@ namespace RecrownedAthenaeum.ScreenSystem { graphics.GraphicsDevice.SetRenderTarget(previousScreenRenderTarget); graphics.GraphicsDevice.Clear(previousScreen.BackgroundColor); - beginBatchFunc(spriteBatch); + batchSettings.BeginSpriteBatch(spriteBatch); previousScreen.Draw(spriteBatch); spriteBatch.End(); graphics.GraphicsDevice.SetRenderTarget(null); Screen.UpdatePreviousScreenFrame(previousScreenRenderTarget); } - beginBatchFunc(spriteBatch); + batchSettings.BeginSpriteBatch(spriteBatch); Screen.Draw(spriteBatch); spriteBatch.End(); } @@ -169,7 +172,7 @@ namespace RecrownedAthenaeum.ScreenSystem previousScreenRenderTarget.Dispose(); previousScreenRenderTarget = null; } - + /// /// Notifies all screen that assets have completed being loaded after a resize. /// @@ -214,10 +217,5 @@ namespace RecrownedAthenaeum.ScreenSystem { Dispose(false); } - - private void BasicBeginBatch(SpriteBatch spriteBatch) - { - spriteBatch.Begin(effect: camera.BasicEffect, blendState: BlendState.NonPremultiplied); - } } } diff --git a/RecrownedAthenaeum/SpecialTypes/NinePatch.cs b/RecrownedAthenaeum/SpecialTypes/NinePatch.cs index 13a685d..e858b0a 100644 --- a/RecrownedAthenaeum/SpecialTypes/NinePatch.cs +++ b/RecrownedAthenaeum/SpecialTypes/NinePatch.cs @@ -59,10 +59,8 @@ namespace RecrownedAthenaeum.SpecialTypes for (int i = 0; i < patches.Length; i++) { - patches[i].X += textureRegion.X + 1; - patches[i].Y += textureRegion.Y + 1; - patches[i].Width -= 2; - patches[i].Height -= 2; + patches[i].X += textureRegion.X; + patches[i].Y += textureRegion.Y; } return patches; } @@ -71,15 +69,15 @@ namespace RecrownedAthenaeum.SpecialTypes { Rectangle[] patches = { - new Rectangle(-left, -bottom, left, bottom), - new Rectangle(0, -bottom, width, bottom), - new Rectangle(width, -bottom, right, bottom), - new Rectangle(-left, 0, left, height), - new Rectangle(0, 0, width, height), - new Rectangle(width, 0, right, height), - new Rectangle(-left, height, left, top), - new Rectangle(0, height, width, top), - new Rectangle(width, height, right, top), + new Rectangle(0, 0, left, bottom), + new Rectangle(left, 0, width - left - right, bottom), + new Rectangle(width -right, 0, right, bottom), + new Rectangle(0, bottom, left, height - bottom - top), + new Rectangle(left, bottom, width - left - right, height - top - bottom), + new Rectangle(width - right, bottom, right, height - top - bottom), + new Rectangle(0, height - top, left, top), + new Rectangle(left, height - top, width - left - right, top), + new Rectangle(width - right, height - top, right, top), }; return patches; } @@ -90,8 +88,19 @@ namespace RecrownedAthenaeum.SpecialTypes /// Batch to use. /// Where to the patch. /// The color of the patch. - public void Draw(SpriteBatch spriteBatch, Rectangle destination, Color color) + /// The sprite batch settings to use to begin the batch in after drawing the ninepatch. + public void Draw(SpriteBatch spriteBatch, Color color, Rectangle destination, SpriteBatchSettings? spriteBatchSettings = null) { + if (spriteBatchSettings == null) spriteBatchSettings = Configuration.spriteBatchSettings; + spriteBatch.End(); + + SpriteBatchSettings ss = spriteBatchSettings.Value; + SamplerState nSS = ss.samplerState; + + ss.samplerState = SamplerState.PointClamp; + + ss.BeginSpriteBatch(spriteBatch); + Rectangle[] destinations = GenenerateDestinationRectangles(destination.Width, destination.Height); for (int i = 0; i < destinations.Length; i++) { @@ -99,10 +108,15 @@ namespace RecrownedAthenaeum.SpecialTypes destinations[i].Y += destination.Y; spriteBatch.Draw(texture, destinations[i], sourcePatches[i], color); } + spriteBatch.End(); + + ss.samplerState = nSS; + ss.BeginSpriteBatch(spriteBatch); } /// /// Draw with more options. + /// Uses the default for the spritebatch settings. /// /// Spritebatch to use. /// The destination to draw the patch. @@ -113,7 +127,7 @@ namespace RecrownedAthenaeum.SpecialTypes { if (rotation != 0) throw new NotImplementedException("Ninepatches can't be rotated."); if (origin != default(Vector2)) throw new NotImplementedException("Ninepatches can't have origin changed (hint: use the destination rectangle to shift and position)."); - Draw(spriteBatch, destination, color); + Draw(spriteBatch, color, destination); } } } diff --git a/RecrownedAthenaeum/SpecialTypes/TextureAtlas.cs b/RecrownedAthenaeum/SpecialTypes/TextureAtlas.cs index 8475568..9c5207b 100644 --- a/RecrownedAthenaeum/SpecialTypes/TextureAtlas.cs +++ b/RecrownedAthenaeum/SpecialTypes/TextureAtlas.cs @@ -174,7 +174,7 @@ namespace RecrownedAthenaeum.SpecialTypes if (ninepatch != null) { - ninepatch.Draw(batch, destination, Color.White); + ninepatch.Draw(batch, Color.White, destination); } else {