diff --git a/CHANGELOG.md b/CHANGELOG.md index a98ecf9..aff1632 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ Jump to version: ### MLEM Additions - Added consuming variants of IsPressed methods to InputHandler +- Added SpriteBatchContext struct and extensions ### MLEM.Ui Additions @@ -19,12 +20,16 @@ Additions Improvements - Ensure that Element.IsMouseOver is always accurate by making it an auto-property +- Started using SpriteBatchContext for Draw and DrawTransformed methods Fixes - Fixed auto-nav tooltip displaying on the selected element even when not in auto-nav mode - Fixed radio buttons not unchecking all other radio buttons with the same root element - Fixed elements not being deselected when removed through RemoveChild +Removals +- Marked old Draw and DrawTransformed overloads as obsolete in favor of SpriteBatchContext ones + ## 5.3.0 ### MLEM Additions diff --git a/MLEM.Ui/Elements/Button.cs b/MLEM.Ui/Elements/Button.cs index 2fd17bd..226426b 100644 --- a/MLEM.Ui/Elements/Button.cs +++ b/MLEM.Ui/Elements/Button.cs @@ -1,5 +1,6 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; +using MLEM.Graphics; using MLEM.Misc; using MLEM.Textures; using MLEM.Ui.Style; @@ -92,7 +93,7 @@ namespace MLEM.Ui.Elements { } /// - public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, Effect effect, Matrix matrix) { + public override void Draw(GameTime time, SpriteBatch batch, float alpha, SpriteBatchContext context) { var tex = this.Texture; var color = (Color) this.NormalColor * alpha; if (this.IsDisabled) { @@ -103,7 +104,7 @@ namespace MLEM.Ui.Elements { color = (Color) this.HoveredColor * alpha; } batch.Draw(tex, this.DisplayArea, color, this.Scale); - base.Draw(time, batch, alpha, blendState, samplerState, depthStencilState, effect, matrix); + base.Draw(time, batch, alpha, context); } /// diff --git a/MLEM.Ui/Elements/Checkbox.cs b/MLEM.Ui/Elements/Checkbox.cs index b371a26..e2854c7 100644 --- a/MLEM.Ui/Elements/Checkbox.cs +++ b/MLEM.Ui/Elements/Checkbox.cs @@ -1,5 +1,6 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; +using MLEM.Graphics; using MLEM.Misc; using MLEM.Textures; using MLEM.Ui.Style; @@ -108,7 +109,7 @@ namespace MLEM.Ui.Elements { } /// - public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, Effect effect, Matrix matrix) { + public override void Draw(GameTime time, SpriteBatch batch, float alpha, SpriteBatchContext context) { var tex = this.Texture; var color = Color.White * alpha; if (this.IsDisabled) { @@ -123,7 +124,7 @@ namespace MLEM.Ui.Elements { batch.Draw(tex, boxDisplayArea, color, this.Scale); if (this.Checked) batch.Draw(this.Checkmark, boxDisplayArea, Color.White * alpha); - base.Draw(time, batch, alpha, blendState, samplerState, depthStencilState, effect, matrix); + base.Draw(time, batch, alpha, context); } /// diff --git a/MLEM.Ui/Elements/Element.cs b/MLEM.Ui/Elements/Element.cs index 6e9ae99..aa8f883 100644 --- a/MLEM.Ui/Elements/Element.cs +++ b/MLEM.Ui/Elements/Element.cs @@ -7,6 +7,7 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using MLEM.Extensions; +using MLEM.Graphics; using MLEM.Input; using MLEM.Misc; using MLEM.Textures; @@ -234,7 +235,7 @@ namespace MLEM.Ui.Elements { public virtual bool PreventParentSpill { get; set; } /// /// The transparency (alpha value) that this element is rendered with. - /// Note that, when is called, this alpha value is multiplied with the 's alpha value and passed down to this element's . + /// Note that, when is called, this alpha value is multiplied with the 's alpha value and passed down to this element's . /// public virtual float DrawAlpha { get; set; } = 1; /// @@ -916,7 +917,7 @@ namespace MLEM.Ui.Elements { } /// - /// Draws this element by calling internally. + /// Draws this element by calling internally. /// If or is set, a new call is also started. /// /// The game's time @@ -927,25 +928,37 @@ namespace MLEM.Ui.Elements { /// The effect that is used for drawing /// The depth stencil state that is used for drawing /// The transformation matrix that is used for drawing + [Obsolete("Use DrawTransformed that takes a SpriteBatchContext instead")] public void DrawTransformed(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, Effect effect, Matrix matrix) { + this.DrawTransformed(time, batch, alpha, new SpriteBatchContext(SpriteSortMode.Deferred, blendState, samplerState, depthStencilState, null, effect, matrix)); + } + + /// + /// Draws this element by calling internally. + /// If or is set, a new call is also started. + /// + /// The game's time + /// The sprite batch to use for drawing + /// The alpha to draw this element and its children with + /// The sprite batch context to use for drawing + public void DrawTransformed(GameTime time, SpriteBatch batch, float alpha, SpriteBatchContext context) { #pragma warning disable CS0618 var customDraw = this.BeginImpl != null || this.Transform != Matrix.Identity; - var mat = this.Transform * matrix; + var transformed = context; + transformed.TransformMatrix = this.Transform * transformed.TransformMatrix; // TODO ending and beginning again when the matrix changes isn't ideal (https://github.com/MonoGame/MonoGame/issues/3156) if (customDraw) { // end the usual draw so that we can begin our own batch.End(); // begin our own draw call - if (this.BeginImpl != null) { - this.BeginImpl(this, time, batch, alpha, blendState, samplerState, depthStencilState, effect, mat); - } else { - batch.Begin(SpriteSortMode.Deferred, blendState, samplerState, depthStencilState, null, effect, mat); - } + batch.Begin(transformed); } #pragma warning restore CS0618 // draw content in custom begin call - this.Draw(time, batch, alpha, blendState, samplerState, depthStencilState, effect, mat); + #pragma warning disable CS0618 + this.Draw(time, batch, alpha, transformed.BlendState, transformed.SamplerState, transformed.DepthStencilState, transformed.Effect, transformed.TransformMatrix); + #pragma warning restore CS0618 if (this.System != null) this.System.Metrics.Draws++; @@ -953,7 +966,7 @@ namespace MLEM.Ui.Elements { // end our draw batch.End(); // begin the usual draw again for other elements - batch.Begin(SpriteSortMode.Deferred, blendState, samplerState, depthStencilState, null, effect, matrix); + batch.Begin(context); } } @@ -969,14 +982,30 @@ namespace MLEM.Ui.Elements { /// The effect that is used for drawing /// The depth stencil state that is used for drawing /// The transformation matrix that is used for drawing + [Obsolete("Use Draw that takes a SpriteBatchContext instead")] public virtual void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, Effect effect, Matrix matrix) { + this.Draw(time, batch, alpha, new SpriteBatchContext(SpriteSortMode.Deferred, blendState, samplerState, depthStencilState, null, effect, matrix)); + } + + /// + /// Draws this element and all of its children. Override this method to draw the content of custom elements. + /// Note that, when this is called, has already been called with custom etc. applied. + /// + /// The game's time + /// The sprite batch to use for drawing + /// The alpha to draw this element and its children with + /// The sprite batch context to use for drawing + public virtual void Draw(GameTime time, SpriteBatch batch, float alpha, SpriteBatchContext context) { this.System.InvokeOnElementDrawn(this, time, batch, alpha); if (this.IsSelected) this.System.InvokeOnSelectedElementDrawn(this, time, batch, alpha); foreach (var child in this.GetRelevantChildren()) { - if (!child.IsHidden) - child.DrawTransformed(time, batch, alpha * child.DrawAlpha, blendState, samplerState, depthStencilState, effect, matrix); + if (!child.IsHidden) { + #pragma warning disable CS0618 + child.DrawTransformed(time, batch, alpha * child.DrawAlpha, context.BlendState, context.SamplerState, context.DepthStencilState, context.Effect, context.TransformMatrix); + #pragma warning restore CS0618 + } } } @@ -1131,7 +1160,7 @@ namespace MLEM.Ui.Elements { public delegate void OtherElementCallback(Element thisElement, Element otherElement); /// - /// A delegate used inside of + /// A delegate used inside of /// /// The element that is being drawn /// The game's time diff --git a/MLEM.Ui/Elements/Group.cs b/MLEM.Ui/Elements/Group.cs index bc95a74..0e31ea2 100644 --- a/MLEM.Ui/Elements/Group.cs +++ b/MLEM.Ui/Elements/Group.cs @@ -1,5 +1,6 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; +using MLEM.Graphics; namespace MLEM.Ui.Elements { /// @@ -20,10 +21,10 @@ namespace MLEM.Ui.Elements { } /// - public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, Effect effect, Matrix matrix) { + public override void Draw(GameTime time, SpriteBatch batch, float alpha, SpriteBatchContext context) { // since the group never accesses its own area when drawing, we have to update it manually this.UpdateAreaIfDirty(); - base.Draw(time, batch, alpha, blendState, samplerState, depthStencilState, effect, matrix); + base.Draw(time, batch, alpha, context); } } diff --git a/MLEM.Ui/Elements/Image.cs b/MLEM.Ui/Elements/Image.cs index 5582c33..23ca2e9 100644 --- a/MLEM.Ui/Elements/Image.cs +++ b/MLEM.Ui/Elements/Image.cs @@ -1,6 +1,7 @@ using System; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; +using MLEM.Graphics; using MLEM.Misc; using MLEM.Textures; using MLEM.Ui.Style; @@ -103,7 +104,7 @@ namespace MLEM.Ui.Elements { } /// - public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, Effect effect, Matrix matrix) { + public override void Draw(GameTime time, SpriteBatch batch, float alpha, SpriteBatchContext context) { if (this.Texture == null) return; var center = new Vector2(this.Texture.Width / 2F, this.Texture.Height / 2F); @@ -116,7 +117,7 @@ namespace MLEM.Ui.Elements { var scale = new Vector2(1F / this.Texture.Width, 1F / this.Texture.Height) * this.DisplayArea.Size; batch.Draw(this.Texture, this.DisplayArea.Location + center * scale, color, this.ImageRotation, center, scale * this.ImageScale, this.ImageEffects, 0); } - base.Draw(time, batch, alpha, blendState, samplerState, depthStencilState, effect, matrix); + base.Draw(time, batch, alpha, context); } /// diff --git a/MLEM.Ui/Elements/Panel.cs b/MLEM.Ui/Elements/Panel.cs index 14980ff..513cb1c 100644 --- a/MLEM.Ui/Elements/Panel.cs +++ b/MLEM.Ui/Elements/Panel.cs @@ -4,6 +4,7 @@ using System.Linq; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using MLEM.Extensions; +using MLEM.Graphics; using MLEM.Misc; using MLEM.Textures; using MLEM.Ui.Style; @@ -167,7 +168,7 @@ namespace MLEM.Ui.Elements { } /// - public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, Effect effect, Matrix matrix) { + public override void Draw(GameTime time, SpriteBatch batch, float alpha, SpriteBatchContext context) { // draw children onto the render target if we have one if (this.scrollOverflow && this.renderTarget != null) { this.UpdateAreaIfDirty(); @@ -179,21 +180,22 @@ namespace MLEM.Ui.Elements { batch.GraphicsDevice.Clear(Color.Transparent); // offset children by the render target's location var area = this.GetRenderTargetArea(); - var trans = Matrix.CreateTranslation(-area.X, -area.Y, 0); // do the usual draw, but within the render target - batch.Begin(SpriteSortMode.Deferred, blendState, samplerState, depthStencilState, null, effect, trans); - base.Draw(time, batch, alpha, blendState, samplerState, depthStencilState, effect, trans); + var trans = context; + trans.TransformMatrix = Matrix.CreateTranslation(-area.X, -area.Y, 0); + batch.Begin(trans); + base.Draw(time, batch, alpha, trans); batch.End(); } batch.GraphicsDevice.PresentationParameters.RenderTargetUsage = lastUsage; - batch.Begin(SpriteSortMode.Deferred, blendState, samplerState, depthStencilState, null, effect, matrix); + batch.Begin(context); } if (this.Texture.HasValue()) batch.Draw(this.Texture, this.DisplayArea, this.DrawColor.OrDefault(Color.White) * alpha, this.Scale); // if we handle overflow, draw using the render target in DrawUnbound if (!this.scrollOverflow || this.renderTarget == null) { - base.Draw(time, batch, alpha, blendState, samplerState, depthStencilState, effect, matrix); + base.Draw(time, batch, alpha, context); } else { // draw the actual render target (don't apply the alpha here because it's already drawn onto with alpha) batch.Draw(this.renderTarget, this.GetRenderTargetArea(), Color.White); diff --git a/MLEM.Ui/Elements/Paragraph.cs b/MLEM.Ui/Elements/Paragraph.cs index 87d3ae4..41065a9 100644 --- a/MLEM.Ui/Elements/Paragraph.cs +++ b/MLEM.Ui/Elements/Paragraph.cs @@ -6,6 +6,7 @@ using MLEM.Extensions; using MLEM.Font; using MLEM.Formatting; using MLEM.Formatting.Codes; +using MLEM.Graphics; using MLEM.Misc; using MLEM.Ui.Style; @@ -144,12 +145,12 @@ namespace MLEM.Ui.Elements { } /// - public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, Effect effect, Matrix matrix) { + public override void Draw(GameTime time, SpriteBatch batch, float alpha, SpriteBatchContext context) { var pos = this.DisplayArea.Location + new Vector2(this.GetAlignmentOffset(), 0); var sc = this.TextScale * this.TextScaleMultiplier * this.Scale; var color = this.TextColor.OrDefault(Color.White) * alpha; this.TokenizedText.Draw(time, batch, pos, this.RegularFont, color, sc, 0); - base.Draw(time, batch, alpha, blendState, samplerState, depthStencilState, effect, matrix); + base.Draw(time, batch, alpha, context); } /// diff --git a/MLEM.Ui/Elements/ProgressBar.cs b/MLEM.Ui/Elements/ProgressBar.cs index ece0d4f..e8e1e38 100644 --- a/MLEM.Ui/Elements/ProgressBar.cs +++ b/MLEM.Ui/Elements/ProgressBar.cs @@ -2,6 +2,7 @@ using System; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using MLEM.Extensions; +using MLEM.Graphics; using MLEM.Misc; using MLEM.Textures; using MLEM.Ui.Style; @@ -73,7 +74,7 @@ namespace MLEM.Ui.Elements { } /// - public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, Effect effect, Matrix matrix) { + public override void Draw(GameTime time, SpriteBatch batch, float alpha, SpriteBatchContext context) { batch.Draw(this.Texture, this.DisplayArea, (Color) this.Color * alpha, this.Scale); var percentage = this.CurrentValue / this.MaxValue; @@ -106,7 +107,7 @@ namespace MLEM.Ui.Elements { } else { batch.Draw(batch.GetBlankTexture(), offsetArea, (Color) this.ProgressColor * alpha); } - base.Draw(time, batch, alpha, blendState, samplerState, depthStencilState, effect, matrix); + base.Draw(time, batch, alpha, context); } /// diff --git a/MLEM.Ui/Elements/ScrollBar.cs b/MLEM.Ui/Elements/ScrollBar.cs index 267601a..ef97e2a 100644 --- a/MLEM.Ui/Elements/ScrollBar.cs +++ b/MLEM.Ui/Elements/ScrollBar.cs @@ -3,6 +3,7 @@ using System.Linq; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input.Touch; +using MLEM.Graphics; using MLEM.Input; using MLEM.Misc; using MLEM.Textures; @@ -205,13 +206,13 @@ namespace MLEM.Ui.Elements { } /// - public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, Effect effect, Matrix matrix) { + public override void Draw(GameTime time, SpriteBatch batch, float alpha, SpriteBatchContext context) { batch.Draw(this.Background, this.DisplayArea, Color.White * alpha, this.Scale); if (this.MaxValue > 0) { var scrollerRect = new RectangleF(this.ScrollerPosition, this.ScrollerSize * this.Scale); batch.Draw(this.ScrollerTexture, scrollerRect, Color.White * alpha, this.Scale); } - base.Draw(time, batch, alpha, blendState, samplerState, depthStencilState, effect, matrix); + base.Draw(time, batch, alpha, context); } /// diff --git a/MLEM.Ui/Elements/TextField.cs b/MLEM.Ui/Elements/TextField.cs index 332fbd7..e2c9d80 100644 --- a/MLEM.Ui/Elements/TextField.cs +++ b/MLEM.Ui/Elements/TextField.cs @@ -7,6 +7,7 @@ using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using MLEM.Extensions; using MLEM.Font; +using MLEM.Graphics; using MLEM.Input; using MLEM.Misc; using MLEM.Textures; @@ -285,7 +286,7 @@ namespace MLEM.Ui.Elements { } /// - public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, Effect effect, Matrix matrix) { + public override void Draw(GameTime time, SpriteBatch batch, float alpha, SpriteBatchContext context) { var tex = this.Texture; var color = Color.White * alpha; if (this.IsMouseOver) { @@ -314,7 +315,7 @@ namespace MLEM.Ui.Elements { this.Font.Value.DrawString(batch, this.PlaceholderText, textPos, this.PlaceholderColor.OrDefault(Color.Gray) * alpha, 0, Vector2.Zero, this.TextScale * this.Scale, SpriteEffects.None, 0); } } - base.Draw(time, batch, alpha, blendState, samplerState, depthStencilState, effect, matrix); + base.Draw(time, batch, alpha, context); } /// diff --git a/MLEM.Ui/UiMetrics.cs b/MLEM.Ui/UiMetrics.cs index 7ee9314..5ecb323 100644 --- a/MLEM.Ui/UiMetrics.cs +++ b/MLEM.Ui/UiMetrics.cs @@ -33,12 +33,12 @@ namespace MLEM.Ui { public uint Updates { get; internal set; } /// - /// The amount of time that took. + /// The amount of time that took. /// Can be divided by to get an average per draw. /// public TimeSpan DrawTime { get; internal set; } /// - /// The amount of times that was called. + /// The amount of times that was called. /// public uint Draws { get; internal set; } diff --git a/MLEM.Ui/UiSystem.cs b/MLEM.Ui/UiSystem.cs index c8dcd23..da46119 100644 --- a/MLEM.Ui/UiSystem.cs +++ b/MLEM.Ui/UiSystem.cs @@ -7,6 +7,7 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using MLEM.Formatting; using MLEM.Formatting.Codes; +using MLEM.Graphics; using MLEM.Input; using MLEM.Misc; using MLEM.Textures; @@ -77,23 +78,32 @@ namespace MLEM.Ui { /// /// The blend state that this ui system and all of its elements draw with /// + [Obsolete("Set this through SpriteBatchContext instead")] public BlendState BlendState; /// /// The sampler state that this ui system and all of its elements draw with. /// The default is , as that is the one that works best with pixel graphics. /// - public SamplerState SamplerState = SamplerState.PointClamp; + [Obsolete("Set this through SpriteBatchContext instead")] + public SamplerState SamplerState; /// /// The depth stencil state that this ui system and all of its elements draw with. /// The default is , which is also the default for . /// - public DepthStencilState DepthStencilState = DepthStencilState.None; + [Obsolete("Set this through SpriteBatchContext instead")] + public DepthStencilState DepthStencilState; /// /// The effect that this ui system and all of its elements draw with. /// The default is null, which means that no custom effect will be used. /// + [Obsolete("Set this through SpriteBatchContext instead")] public Effect Effect; /// + /// The spriteb atch context that this ui system and all of its elements should draw with. + /// The default is , as that is the one that works best with pixel graphics. + /// + public SpriteBatchContext SpriteBatchContext = new SpriteBatchContext(samplerState: SamplerState.PointClamp); + /// /// The that this ui system's elements format their text with. /// To add new formatting codes to the ui system, add them to this formatter. /// @@ -296,9 +306,24 @@ namespace MLEM.Ui { foreach (var root in this.rootElements) { if (root.Element.IsHidden) continue; - batch.Begin(SpriteSortMode.Deferred, this.BlendState, this.SamplerState, this.DepthStencilState, null, this.Effect, root.Transform); - var alpha = this.DrawAlpha * root.Element.DrawAlpha; - root.Element.DrawTransformed(time, batch, alpha, this.BlendState, this.SamplerState, this.DepthStencilState, this.Effect, root.Transform); + var context = this.SpriteBatchContext; + context.TransformMatrix = root.Transform * context.TransformMatrix; + + #pragma warning disable CS0618 + if (this.BlendState != null) + context.BlendState = this.BlendState; + if (this.SamplerState != null) + context.SamplerState = this.SamplerState; + if (this.DepthStencilState != null) + context.DepthStencilState = this.DepthStencilState; + if (this.Effect != null) + context.Effect = this.Effect; + #pragma warning restore CS0618 + + batch.Begin(context); + #pragma warning disable CS0618 + root.Element.DrawTransformed(time, batch, this.DrawAlpha * root.Element.DrawAlpha, context.BlendState, context.SamplerState, context.DepthStencilState, context.Effect, context.TransformMatrix); + #pragma warning restore CS0618 batch.End(); } diff --git a/MLEM/Graphics/SpriteBatchContext.cs b/MLEM/Graphics/SpriteBatchContext.cs new file mode 100644 index 0000000..ad03034 --- /dev/null +++ b/MLEM/Graphics/SpriteBatchContext.cs @@ -0,0 +1,100 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; + +namespace MLEM.Graphics { + /// + /// A sprite batch context is a set of information for a to use, which encapsulates all of the information usually passed directly to . + /// To use a sprite batch context effectively, the extension methods in should be used. + /// + public struct SpriteBatchContext { + + /// + /// The drawing order for sprite and text drawing. + /// + public SpriteSortMode SortMode; + /// + /// State of the blending. + /// + public BlendState BlendState; + /// + /// State of the sampler. + /// + public SamplerState SamplerState; + /// + /// State of the depth-stencil buffer. + /// + public DepthStencilState DepthStencilState; + /// + /// State of the rasterization. + /// + public RasterizerState RasterizerState; + /// + /// A custom to override the default sprite effect. + /// + public Effect Effect; + /// + /// An optional matrix used to transform the sprite geometry. + /// + public Matrix TransformMatrix; + + /// + /// Creates a new sprite batch context with the given parameters. + /// + /// The drawing order for sprite and text drawing. by default. + /// State of the blending. Uses if null. + /// State of the sampler. Uses if null. + /// State of the depth-stencil buffer. Uses if null. + /// State of the rasterization. Uses if null. + /// A custom to override the default sprite effect. + /// An optional matrix used to transform the sprite geometry. Uses if null. + public SpriteBatchContext(SpriteSortMode sortMode = SpriteSortMode.Deferred, BlendState blendState = null, SamplerState samplerState = null, DepthStencilState depthStencilState = null, RasterizerState rasterizerState = null, Effect effect = null, Matrix? transformMatrix = null) { + this.SortMode = sortMode; + this.BlendState = blendState ?? BlendState.AlphaBlend; + this.SamplerState = samplerState ?? SamplerState.LinearClamp; + this.DepthStencilState = depthStencilState ?? DepthStencilState.None; + this.RasterizerState = rasterizerState ?? RasterizerState.CullCounterClockwise; + this.Effect = effect; + this.TransformMatrix = transformMatrix ?? Matrix.Identity; + } + + /// + /// Creates a new sprite batch context from the passed 's current information. + /// This can be useful to retrieve some information about drawing right after a call has occured. + /// + /// The graphics device to query data from. + /// The drawing order for sprite and text drawing. by default. + /// A custom to override the default sprite effect. + /// An optional matrix used to transform the sprite geometry. Uses if null. + /// A new sprite batch context from the 's current information. + public static SpriteBatchContext Current(GraphicsDevice device, SpriteSortMode sortMode = SpriteSortMode.Deferred, Effect effect = null, Matrix? transformMatrix = null) { + return new SpriteBatchContext(sortMode, device.BlendState, device.SamplerStates[0], device.DepthStencilState, device.RasterizerState, effect, transformMatrix); + } + + } + + /// + /// A set of extensions for . + /// + public static class SpriteBatchContextExtensions { + + /// + /// Begins a new sprite and text batch with the specified + /// + /// The sprite batch to use for drawing. + /// The sprite batch context to use. + public static void Begin(this SpriteBatch batch, SpriteBatchContext context) { + batch.Begin(context.SortMode, context.BlendState, context.SamplerState, context.DepthStencilState, context.RasterizerState, context.Effect, context.TransformMatrix); + } + + /// + /// Draws the given batch's content onto the 's current render target (or the back buffer) with the given settings. + /// Note that this method should not be called while a regular is currently active. + /// + /// The static sprite batch to use for drawing. + /// The sprite batch context to use. + public static void Draw(this StaticSpriteBatch batch, SpriteBatchContext context) { + batch.Draw(context.BlendState, context.SamplerState, context.DepthStencilState, context.RasterizerState, context.Effect, context.TransformMatrix); + } + + } +} \ No newline at end of file