From 94dec344707fa3896bc6c41832f0f19cce3b1bfd Mon Sep 17 00:00:00 2001 From: Ellpeck Date: Sat, 26 Mar 2022 21:13:05 +0100 Subject: [PATCH] render panel's render target in the Draw method --- CHANGELOG.md | 3 ++- MLEM.Ui/Elements/Element.cs | 5 +++-- MLEM.Ui/Elements/Panel.cs | 35 ++++++++++++++++++----------------- MLEM.Ui/UiSystem.cs | 4 ++-- 4 files changed, 25 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c47ae21..32b2657 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -73,7 +73,8 @@ Fixes Removals - Marked StyleProp equality members as obsolete -- Marked BeginDelegate and BeginImpl as obsolete +- Marked Element.BeginDelegate and Element.BeginImpl as obsolete +- Marked Element.DrawEarly and UiSystem.DrawEarly as obsolete ### MLEM.Extended Improvements diff --git a/MLEM.Ui/Elements/Element.cs b/MLEM.Ui/Elements/Element.cs index 8afe267..f191585 100644 --- a/MLEM.Ui/Elements/Element.cs +++ b/MLEM.Ui/Elements/Element.cs @@ -185,7 +185,7 @@ namespace MLEM.Ui.Elements { /// Note that, when this is non-null, a new call is used for this element. /// #pragma warning disable CS0618 - [Obsolete("BeginImpl is deprecated. You can create a custom element class and override DrawEarly or Draw instead.")] + [Obsolete("BeginImpl is deprecated. You can create a custom element class and override Draw instead.")] public BeginDelegate BeginImpl; #pragma warning restore CS0618 /// @@ -990,6 +990,7 @@ 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("DrawEarly is deprecated. For custom implementations, see Panel.Draw for how to replace this method.")] public virtual void DrawEarly(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, Effect effect, Matrix matrix) { foreach (var child in this.GetRelevantChildren()) { if (!child.IsHidden) @@ -1168,7 +1169,7 @@ namespace MLEM.Ui.Elements { /// The effect used for drawing /// The depth stencil state used for drawing /// The transform matrix used for drawing - [Obsolete("BeginDelegate is deprecated. You can create a custom element class and override DrawEarly or Draw instead.")] + [Obsolete("BeginDelegate is deprecated. You can create a custom element class and override Draw instead.")] public delegate void BeginDelegate(Element element, GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, Effect effect, Matrix matrix); } diff --git a/MLEM.Ui/Elements/Panel.cs b/MLEM.Ui/Elements/Panel.cs index 6d86fdd..14980ff 100644 --- a/MLEM.Ui/Elements/Panel.cs +++ b/MLEM.Ui/Elements/Panel.cs @@ -13,7 +13,6 @@ namespace MLEM.Ui.Elements { /// A panel element to be used inside of a . /// The panel is a complex element that displays a box as a background to all of its child elements. /// Additionally, a panel can be set to on construction, which causes all elements that don't fit into the panel to be hidden until scrolled to using a . - /// As this behavior is accomplished using a , scrolling panels need to have their methods called using . /// public class Panel : Element { @@ -169,22 +168,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) { - 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); - } 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); - } - } - - /// - public override void DrawEarly(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, Effect effect, Matrix matrix) { - this.UpdateAreaIfDirty(); + // draw children onto the render target if we have one if (this.scrollOverflow && this.renderTarget != null) { - // draw children onto the render target + this.UpdateAreaIfDirty(); + batch.End(); + // force render target usage to preserve so that previous content isn't cleared + var lastUsage = batch.GraphicsDevice.PresentationParameters.RenderTargetUsage; + batch.GraphicsDevice.PresentationParameters.RenderTargetUsage = RenderTargetUsage.PreserveContents; using (batch.GraphicsDevice.WithRenderTarget(this.renderTarget)) { batch.GraphicsDevice.Clear(Color.Transparent); // offset children by the render target's location @@ -195,8 +185,19 @@ namespace MLEM.Ui.Elements { base.Draw(time, batch, alpha, blendState, samplerState, depthStencilState, effect, trans); batch.End(); } + batch.GraphicsDevice.PresentationParameters.RenderTargetUsage = lastUsage; + batch.Begin(SpriteSortMode.Deferred, blendState, samplerState, depthStencilState, null, effect, matrix); + } + + 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); + } 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); } - base.DrawEarly(time, batch, alpha, blendState, samplerState, depthStencilState, effect, matrix); } /// diff --git a/MLEM.Ui/UiSystem.cs b/MLEM.Ui/UiSystem.cs index e93b68c..c8dcd23 100644 --- a/MLEM.Ui/UiSystem.cs +++ b/MLEM.Ui/UiSystem.cs @@ -105,7 +105,7 @@ namespace MLEM.Ui { public UiControls Controls; /// /// The update and rendering statistics to be used for runtime debugging and profiling. - /// The metrics are reset accordingly every frame: is called at the start of , and is called at the start of , or at the start of if was not called. + /// The metrics are reset accordingly every frame: is called at the start of , and is called at the start of . /// public UiMetrics Metrics; @@ -268,6 +268,7 @@ namespace MLEM.Ui { /// /// The game's time /// The sprite batch to use for drawing + [Obsolete("DrawEarly is deprecated. Calling it is not required anymore, and there is no replacement.")] public void DrawEarly(GameTime time, SpriteBatch batch) { this.Metrics.ResetDraws(); this.stopwatch.Restart(); @@ -284,7 +285,6 @@ namespace MLEM.Ui { /// /// Draws any s onto the screen. - /// Note that, when using s with a scroll bar, needs to be called as well. /// /// The game's time /// The sprite batch to use for drawing