From d7ca521b9b3b7795171273d601233a5bc59cd29f Mon Sep 17 00:00:00 2001 From: Recrown Date: Wed, 27 Mar 2019 02:35:20 -0500 Subject: [PATCH] Scissoring now works and implemented; Refactoring as well; --- RecrownedAthenaeum/RecrownedAthenaeum.csproj | 3 +- RecrownedAthenaeum/Render/BasicCamera.cs | 3 +- RecrownedAthenaeum/Render/BasicScissor.cs | 60 ++++++++++++++++ RecrownedAthenaeum/Render/Camera2D.cs | 2 +- .../Render/ConsistentSpriteBatch.cs | 68 ++++++++++++------- RecrownedAthenaeum/Render/PrimitiveBatch.cs | 7 +- .../Render/RectangleRenderer.cs | 1 - RecrownedAthenaeum/Render/ScissorBox.cs | 52 -------------- RecrownedAthenaeum/ScreenSystem/Screen.cs | 1 - .../ScreenSystem/ScreenManager.cs | 1 - .../SpecialTypes/ISpecialDrawable.cs | 1 - RecrownedAthenaeum/SpecialTypes/NinePatch.cs | 6 +- RecrownedAthenaeum/UI/BookSystem/Book.cs | 18 ++--- RecrownedAthenaeum/UI/BookSystem/Page.cs | 6 +- .../UI/Modular/Modules/Interactive/Button.cs | 3 +- RecrownedAthenaeum/UI/Modular/UIModule.cs | 1 - .../UI/Modular/UIModuleGroup.cs | 15 ++-- 17 files changed, 129 insertions(+), 119 deletions(-) create mode 100644 RecrownedAthenaeum/Render/BasicScissor.cs delete mode 100644 RecrownedAthenaeum/Render/ScissorBox.cs diff --git a/RecrownedAthenaeum/RecrownedAthenaeum.csproj b/RecrownedAthenaeum/RecrownedAthenaeum.csproj index f938b9f..b7af5a4 100644 --- a/RecrownedAthenaeum/RecrownedAthenaeum.csproj +++ b/RecrownedAthenaeum/RecrownedAthenaeum.csproj @@ -52,8 +52,9 @@ + - + diff --git a/RecrownedAthenaeum/Render/BasicCamera.cs b/RecrownedAthenaeum/Render/BasicCamera.cs index 1f63b7c..37ef2c1 100644 --- a/RecrownedAthenaeum/Render/BasicCamera.cs +++ b/RecrownedAthenaeum/Render/BasicCamera.cs @@ -1,8 +1,7 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; -using System; -namespace RecrownedAthenaeum.Camera +namespace RecrownedAthenaeum.Render { /// /// A generic camera. Functions in 3D. diff --git a/RecrownedAthenaeum/Render/BasicScissor.cs b/RecrownedAthenaeum/Render/BasicScissor.cs new file mode 100644 index 0000000..19cf022 --- /dev/null +++ b/RecrownedAthenaeum/Render/BasicScissor.cs @@ -0,0 +1,60 @@ +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 +{ + /// + /// A simple utility object that will start and end a scissor setup given a to work with. + /// + public class BasicScissor + { + ConsistentSpriteBatch spriteBatch; + RasterizerState scissorRasterizer; + Rectangle scissorRectangle; + + RasterizerState originalRasterizer; + Rectangle originalScissor; + + /// + /// Initializes the basic scissor. + /// + public BasicScissor() + { + scissorRasterizer = new RasterizerState(); + scissorRasterizer.MultiSampleAntiAlias = false; + scissorRasterizer.ScissorTestEnable = true; + + } + + /// + /// Begins the with scissoring in mind. + /// + /// The rectangle to use to outline the scissor. + /// The consistent sprite batch to use for this process. + public void Begin(Rectangle scissorRectangle, ConsistentSpriteBatch consistentSpriteBatch) + { + originalRasterizer = consistentSpriteBatch.rasterizerState; + this.scissorRectangle = scissorRectangle; + + spriteBatch = consistentSpriteBatch; + spriteBatch.Begin(rasterizerState: scissorRasterizer); + } + + /// + /// Ends the scissor state of the spritebatch. + /// + public void End() + { + originalScissor = spriteBatch.GraphicsDevice.ScissorRectangle; + spriteBatch.GraphicsDevice.ScissorRectangle = scissorRectangle; + spriteBatch.End(); + spriteBatch.rasterizerState = originalRasterizer; + spriteBatch.GraphicsDevice.ScissorRectangle = originalScissor; + } + } +} diff --git a/RecrownedAthenaeum/Render/Camera2D.cs b/RecrownedAthenaeum/Render/Camera2D.cs index 80a7f8f..bc93655 100644 --- a/RecrownedAthenaeum/Render/Camera2D.cs +++ b/RecrownedAthenaeum/Render/Camera2D.cs @@ -2,7 +2,7 @@ using Microsoft.Xna.Framework.Graphics; using System; -namespace RecrownedAthenaeum.Camera +namespace RecrownedAthenaeum.Render { /// /// A virtual 2D camera that wraps the normal . Default projection is orthographic. diff --git a/RecrownedAthenaeum/Render/ConsistentSpriteBatch.cs b/RecrownedAthenaeum/Render/ConsistentSpriteBatch.cs index e7ad7ed..376f7bf 100644 --- a/RecrownedAthenaeum/Render/ConsistentSpriteBatch.cs +++ b/RecrownedAthenaeum/Render/ConsistentSpriteBatch.cs @@ -1,15 +1,11 @@ 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 { /// /// A that keeps it's settings through begin and end unless manually changed either by the or through changing the fields. Note that changing the fields while the batch has begun will not take effect until the next time the batch is started. + /// Casting this as a will not persist the configuration and will call the normal . /// public class ConsistentSpriteBatch : SpriteBatch { @@ -17,37 +13,37 @@ namespace RecrownedAthenaeum.Render /// How to blend the colors. Uses 's default if not set before or during call. /// Changes will only take effect on call. /// - public BlendState BlendState; + public BlendState blendState; /// /// The state of sampler to use for the spritebatch. Uses 's default if not set before or during call. /// Changes will only take effect on call. /// - public SamplerState SamplerState; + public SamplerState samplerState; /// /// The state of the depth-stencil buffer. Uses 's defaultdefault if not set before or during call. /// Changes will only take effect on call. /// - public DepthStencilState DepthStencilState; + public DepthStencilState depthStencilState; /// /// The state of rasterizer to use. Uses 's default if not set before or during call. /// Changes will only take effect on call. /// - public RasterizerState RasterizerState; + public RasterizerState rasterizerState; /// /// An effect to apply to the batch. Uses 's default if not set before or during call. /// Changes will only take effect on call. /// - public Effect Effect; + public Effect effect; /// /// A matrix to be applied to transform the sprites geometry. An identity matrix is used if not provided before or during call. /// Changes will only take effect on call. /// - public Matrix? TransformMatrix; + public Matrix? transformMatrix; /// /// Creates a consistent sprite batch with default values. @@ -58,7 +54,7 @@ namespace RecrownedAthenaeum.Render } /// - /// Begins the consistent sprite batch. + /// Begins the consistent sprite batch. The configuration passed to this function is saved for later begin calls. /// /// Defines the spritebatch's method of sorting the items in each batch. Uses 's default. /// How to blend the colors. Uses 's default if not set and field is also not set. @@ -66,24 +62,46 @@ namespace RecrownedAthenaeum.Render /// What type of rasterization to use. Uses 's default if not set and field is also not set. /// What type of rasterization to use. Uses 's default if not set and field is also not set. /// An effect to apply to the batch. Uses 's default if not set and field is also not set. - /// A matrix to be applied to transform the sprites geometry. An identity is used if not provided. + /// A matrix to be applied to transform the sprites geometry. Uses 's default if not set and field is also not set. public new void Begin(SpriteSortMode sortMode = SpriteSortMode.Deferred, BlendState blendState = null, SamplerState samplerState = null, DepthStencilState depthStencilState = null, RasterizerState rasterizerState = null, Effect effect = null, Matrix? transformMatrix = null) { - if (blendState != null) this.BlendState = blendState; - if (samplerState != null) this.SamplerState = samplerState; - if (depthStencilState != null) this.DepthStencilState = depthStencilState; - if (rasterizerState != null) this.RasterizerState = rasterizerState; - if (effect != null) this.Effect = effect; - if (transformMatrix != null) this.TransformMatrix = transformMatrix; + if (blendState != null) this.blendState = blendState; + if (samplerState != null) this.samplerState = samplerState; + if (depthStencilState != null) this.depthStencilState = depthStencilState; + if (rasterizerState != null) this.rasterizerState = rasterizerState; + if (effect != null) this.effect = effect; + if (transformMatrix != null) this.transformMatrix = transformMatrix; base.Begin( sortMode: sortMode, - blendState: blendState, - samplerState: samplerState, - depthStencilState: depthStencilState, - rasterizerState: rasterizerState, - effect: effect, - transformMatrix: transformMatrix); + blendState: this.blendState, + samplerState: this.samplerState, + depthStencilState: this.depthStencilState, + rasterizerState: this.rasterizerState, + effect: this.effect, + transformMatrix: this.transformMatrix); + } + + /// + /// Begins the consistent sprite batch without saving the configuration. Useful for one time changes to one portion of the configuration. + /// + /// Defines the spritebatch's method of sorting the items in each batch. Uses 's default. + /// How to blend the colors. Uses 's default if not set and field is also not set. + /// The state of sampler to use for the spritebatch. Uses 's default if not set and field is also not set. + /// What type of rasterization to use. Uses 's default if not set and field is also not set. + /// What type of rasterization to use. Uses 's default if not set and field is also not set. + /// An effect to apply to the batch. Uses 's default if not set and field is also not set. + /// A matrix to be applied to transform the sprites geometry. Uses 's default if not set and field is also not set. + public void BeginWithoutSaving(SpriteSortMode sortMode = SpriteSortMode.Deferred, BlendState blendState = null, SamplerState samplerState = null, DepthStencilState depthStencilState = null, RasterizerState rasterizerState = null, Effect effect = null, Matrix? transformMatrix = null) + { + base.Begin( + sortMode: sortMode, + blendState: blendState ?? this.blendState, + samplerState: samplerState ?? this.samplerState, + depthStencilState: depthStencilState ?? this.depthStencilState, + rasterizerState: rasterizerState ?? this.rasterizerState, + effect: effect ?? this.effect, + transformMatrix: transformMatrix ?? this.transformMatrix); } } } diff --git a/RecrownedAthenaeum/Render/PrimitiveBatch.cs b/RecrownedAthenaeum/Render/PrimitiveBatch.cs index 8eb5e63..87004a5 100644 --- a/RecrownedAthenaeum/Render/PrimitiveBatch.cs +++ b/RecrownedAthenaeum/Render/PrimitiveBatch.cs @@ -1,6 +1,5 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; -using RecrownedAthenaeum.Camera; using System; namespace RecrownedAthenaeum.Render @@ -36,13 +35,17 @@ namespace RecrownedAthenaeum.Render vertices = new VertexPositionColor[verticesPerBatch + 1]; this.graphicsDevice = graphicsDevice; basicEffect = new BasicEffect(graphicsDevice); + basicEffect.VertexColorEnabled = true; + basicEffect.Projection = Matrix.CreateOrthographicOffCenter(0, graphicsDevice.Viewport.Width, graphicsDevice.Viewport.Height, 0, 0, 1); + basicEffect.World = Matrix.Identity; + basicEffect.View = Matrix.CreateLookAt(Vector3.Zero, Vector3.Forward, Vector3.Up); } /// /// Starts the batch. Batch cannot be started twice. /// /// The type of primitive this batch would be drawing. - /// Effect to use to render the primitives. Default will use a . + /// Effect to use to render the primitives. Default will use a with parameters set up during creation. public void Begin(PrimitiveType primitiveType, Effect effect = null) { if (began) throw new InvalidOperationException("Begin is being called twice before being ended."); diff --git a/RecrownedAthenaeum/Render/RectangleRenderer.cs b/RecrownedAthenaeum/Render/RectangleRenderer.cs index ee2d70e..224b1ec 100644 --- a/RecrownedAthenaeum/Render/RectangleRenderer.cs +++ b/RecrownedAthenaeum/Render/RectangleRenderer.cs @@ -1,6 +1,5 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; -using RecrownedAthenaeum.Camera; using System; namespace RecrownedAthenaeum.Render diff --git a/RecrownedAthenaeum/Render/ScissorBox.cs b/RecrownedAthenaeum/Render/ScissorBox.cs deleted file mode 100644 index 0ec77f1..0000000 --- a/RecrownedAthenaeum/Render/ScissorBox.cs +++ /dev/null @@ -1,52 +0,0 @@ -using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Graphics; - -namespace RecrownedAthenaeum.Render -{ - /// - /// Box that crops off anything outside of the bounds. - /// - public class ScissorBox - { - - ConsistentSpriteBatch spriteBatch; - Rectangle originalScissor; - RasterizerState originalRasterizerState; - - RasterizerState scissorRasterizerState; - - /// - /// Used to crop off anything that doesn't fit into the defined space. - /// - public ScissorBox() - { - scissorRasterizerState = new RasterizerState(); - scissorRasterizerState.ScissorTestEnable = true; - } - - /// - /// Starts spritebatch with scissoring enabled. - /// - /// - /// - public void Begin(Rectangle rectangle, ConsistentSpriteBatch spriteBatch) - { - this.spriteBatch = spriteBatch; - originalRasterizerState = spriteBatch.RasterizerState; - spriteBatch.Begin(rasterizerState: scissorRasterizerState); - - originalScissor = spriteBatch.GraphicsDevice.ScissorRectangle; - spriteBatch.GraphicsDevice.ScissorRectangle = rectangle; - } - - /// - /// Ends the scissoring and spritebatch. - /// - public void End() - { - spriteBatch.GraphicsDevice.ScissorRectangle = originalScissor; - spriteBatch.RasterizerState = originalRasterizerState; - spriteBatch.End(); - } - } -} diff --git a/RecrownedAthenaeum/ScreenSystem/Screen.cs b/RecrownedAthenaeum/ScreenSystem/Screen.cs index fa301f7..724d6c3 100644 --- a/RecrownedAthenaeum/ScreenSystem/Screen.cs +++ b/RecrownedAthenaeum/ScreenSystem/Screen.cs @@ -1,6 +1,5 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; -using RecrownedAthenaeum.Camera; using RecrownedAthenaeum.Render; using System.Collections.Generic; diff --git a/RecrownedAthenaeum/ScreenSystem/ScreenManager.cs b/RecrownedAthenaeum/ScreenSystem/ScreenManager.cs index 991d18a..415342a 100644 --- a/RecrownedAthenaeum/ScreenSystem/ScreenManager.cs +++ b/RecrownedAthenaeum/ScreenSystem/ScreenManager.cs @@ -1,6 +1,5 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; -using RecrownedAthenaeum.Camera; using RecrownedAthenaeum.Render; using System; using System.Diagnostics; diff --git a/RecrownedAthenaeum/SpecialTypes/ISpecialDrawable.cs b/RecrownedAthenaeum/SpecialTypes/ISpecialDrawable.cs index cc84cc5..13d0bfa 100644 --- a/RecrownedAthenaeum/SpecialTypes/ISpecialDrawable.cs +++ b/RecrownedAthenaeum/SpecialTypes/ISpecialDrawable.cs @@ -1,5 +1,4 @@ using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Graphics; using RecrownedAthenaeum.Render; namespace RecrownedAthenaeum.SpecialTypes diff --git a/RecrownedAthenaeum/SpecialTypes/NinePatch.cs b/RecrownedAthenaeum/SpecialTypes/NinePatch.cs index 20fe5d5..17c8c07 100644 --- a/RecrownedAthenaeum/SpecialTypes/NinePatch.cs +++ b/RecrownedAthenaeum/SpecialTypes/NinePatch.cs @@ -98,9 +98,7 @@ namespace RecrownedAthenaeum.SpecialTypes throw new InvalidOperationException("Begin must be called to draw a nine patch!"); } - SamplerState originalSamplerState = spriteBatch.SamplerState; - GraphicsDevice graphics = spriteBatch.GraphicsDevice; - spriteBatch.Begin(samplerState: SamplerState.PointClamp); + spriteBatch.BeginWithoutSaving(samplerState: SamplerState.PointClamp); Rectangle[] destinations = GenenerateDestinationRectangles(destination.Width, destination.Height); for (int i = 0; i < destinations.Length; i++) @@ -111,7 +109,7 @@ namespace RecrownedAthenaeum.SpecialTypes } spriteBatch.End(); - spriteBatch.Begin(samplerState: originalSamplerState); + spriteBatch.Begin(); } /// diff --git a/RecrownedAthenaeum/UI/BookSystem/Book.cs b/RecrownedAthenaeum/UI/BookSystem/Book.cs index 7f2edd0..c8044fa 100644 --- a/RecrownedAthenaeum/UI/BookSystem/Book.cs +++ b/RecrownedAthenaeum/UI/BookSystem/Book.cs @@ -1,7 +1,5 @@ using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; -using RecrownedAthenaeum.Camera; using RecrownedAthenaeum.ContentSystem; using RecrownedAthenaeum.Input; using RecrownedAthenaeum.Render; @@ -28,11 +26,7 @@ namespace RecrownedAthenaeum.UI.BookSystem /// The camera to use to change between pages. /// public Camera2D camera; - - /// - /// The scissorbox used to crop things. - /// - public ScissorBox scissorBox; + private BasicScissor basicScissor; /// /// Creates a book. @@ -40,14 +34,13 @@ namespace RecrownedAthenaeum.UI.BookSystem /// that holds the assets that are to be used in the pages for this book during initialization. /// The skin that will be passed to pages during their initialization. /// Camera to move to change pages. - /// The scissor box to use to crop the pages to the given dimensions. Default is null, and will not crop anything. - public Book(ContentManagerController assets, ISkin skin, Camera2D camera, ScissorBox scissorBox = null) + public Book(ContentManagerController assets, ISkin skin, Camera2D camera) { this.assets = assets; this.skin = skin; this.camera = camera ?? throw new ArgumentNullException("Camera can't be null since book needs a camera to move to change between the slides (pages)."); - this.scissorBox = scissorBox; + this.basicScissor = new BasicScissor(); } /// @@ -57,8 +50,7 @@ namespace RecrownedAthenaeum.UI.BookSystem /// /// Camera to move to change pages. /// Dimensions of the book and the dimensions the pages will use. - /// The scissor box to use to crop the pages to the given dimensions. Default is null, and will not crop anything. - public void Initiate(Camera2D camera, Rectangle dimensions, ScissorBox scissorBox = null) + public void Initiate(Camera2D camera, Rectangle dimensions) { this.camera = camera; } @@ -133,7 +125,7 @@ namespace RecrownedAthenaeum.UI.BookSystem { orderedPages.Add(page); this.pages.Add(page.name, page); - page.Initialize(assets, skin, scissorBox); + page.Initialize(assets, skin, basicScissor); } } diff --git a/RecrownedAthenaeum/UI/BookSystem/Page.cs b/RecrownedAthenaeum/UI/BookSystem/Page.cs index 7e7ea05..ccb9992 100644 --- a/RecrownedAthenaeum/UI/BookSystem/Page.cs +++ b/RecrownedAthenaeum/UI/BookSystem/Page.cs @@ -48,10 +48,10 @@ namespace RecrownedAthenaeum.UI.BookSystem /// /// The assets to be used during initialization passed by the book this page belongs to. /// The skin the book containing this page is given that can be used by this page. - /// The scissor box to use for cropping. - protected internal virtual void Initialize(ContentManagerController assets, ISkin skin, ScissorBox scissorBox) + /// The scissor box to use for cropping. + protected internal virtual void Initialize(ContentManagerController assets, ISkin skin, BasicScissor basicScissor) { - this.scissorBox = scissorBox; + this.basicScissor = basicScissor; } } } diff --git a/RecrownedAthenaeum/UI/Modular/Modules/Interactive/Button.cs b/RecrownedAthenaeum/UI/Modular/Modules/Interactive/Button.cs index 2e46c69..2d1cdc9 100644 --- a/RecrownedAthenaeum/UI/Modular/Modules/Interactive/Button.cs +++ b/RecrownedAthenaeum/UI/Modular/Modules/Interactive/Button.cs @@ -1,5 +1,4 @@ -using Microsoft.Xna.Framework.Graphics; -using Microsoft.Xna.Framework.Input; +using Microsoft.Xna.Framework.Input; using RecrownedAthenaeum.SpecialTypes; using RecrownedAthenaeum.Input; using RecrownedAthenaeum.UI.SkinSystem.Definitions; diff --git a/RecrownedAthenaeum/UI/Modular/UIModule.cs b/RecrownedAthenaeum/UI/Modular/UIModule.cs index 225e8df..a5ec66b 100644 --- a/RecrownedAthenaeum/UI/Modular/UIModule.cs +++ b/RecrownedAthenaeum/UI/Modular/UIModule.cs @@ -1,5 +1,4 @@ using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using RecrownedAthenaeum.Input; using RecrownedAthenaeum.Render; diff --git a/RecrownedAthenaeum/UI/Modular/UIModuleGroup.cs b/RecrownedAthenaeum/UI/Modular/UIModuleGroup.cs index 21d18cb..1dc152a 100644 --- a/RecrownedAthenaeum/UI/Modular/UIModuleGroup.cs +++ b/RecrownedAthenaeum/UI/Modular/UIModuleGroup.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using RecrownedAthenaeum.Render; @@ -18,18 +17,18 @@ namespace RecrownedAthenaeum.UI.Modular /// /// Set this to crop anything that flows out of the boundaries of this group. Will not crop if this is null. /// - public ScissorBox scissorBox; + public BasicScissor basicScissor; /// - /// Draws this group of modules. If scissoring, will use the matrix and effect designated in the to begin the batch normally again. + /// Draws this group of modules. If scissoring, will use the matrix and effect designated in the to begin the batch normally again. /// /// Batch used to draw the group. public override void Draw(ConsistentSpriteBatch spriteBatch) { - if (scissorBox != null) + if (basicScissor != null) { spriteBatch.End(); - scissorBox.Begin(Boundaries, spriteBatch); + basicScissor.Begin(Boundaries, spriteBatch); } foreach (UIModule module in modules) @@ -43,11 +42,9 @@ namespace RecrownedAthenaeum.UI.Modular module.situation.Y = offsetY; } - if (scissorBox != null) + if (basicScissor != null) { - scissorBox.End(); - - GraphicsDevice graphics = spriteBatch.GraphicsDevice; + basicScissor.End(); spriteBatch.Begin(); } }