1
0
Fork 0
mirror of https://github.com/Ellpeck/MLEM.git synced 2024-11-22 20:58:34 +01:00

Allow setting a custom effect and depth stencil state for ui drawing

This commit is contained in:
Ell 2021-11-22 17:42:08 +01:00
parent 5b99f29490
commit 84e2544dc8
12 changed files with 54 additions and 35 deletions

View file

@ -29,6 +29,7 @@ Additions
Improvements Improvements
- *Made Image ScaleToImage take ui scale into account* - *Made Image ScaleToImage take ui scale into account*
- *Added style properties for a lot of hardcoded default element styles* - *Added style properties for a lot of hardcoded default element styles*
- *Allow setting a custom effect and depth stencil state for ui drawing*
- Exposed the epsilon value used by Element calculations - Exposed the epsilon value used by Element calculations
- Allow style properties to set style values with a higher priority, which allows elements to style their default children - Allow style properties to set style values with a higher priority, which allows elements to style their default children
- Allow changing the entire ui style for a single element - Allow changing the entire ui style for a single element

View file

@ -91,7 +91,7 @@ namespace MLEM.Ui.Elements {
} }
/// <inheritdoc /> /// <inheritdoc />
public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix) { public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, Effect effect, Matrix matrix) {
var tex = this.Texture; var tex = this.Texture;
var color = (Color) this.NormalColor * alpha; var color = (Color) this.NormalColor * alpha;
if (this.IsDisabled) { if (this.IsDisabled) {
@ -102,7 +102,7 @@ namespace MLEM.Ui.Elements {
color = (Color) this.HoveredColor * alpha; color = (Color) this.HoveredColor * alpha;
} }
batch.Draw(tex, this.DisplayArea, color, this.Scale); batch.Draw(tex, this.DisplayArea, color, this.Scale);
base.Draw(time, batch, alpha, blendState, samplerState, matrix); base.Draw(time, batch, alpha, blendState, samplerState, depthStencilState, effect, matrix);
} }
/// <inheritdoc /> /// <inheritdoc />

View file

@ -84,7 +84,7 @@ namespace MLEM.Ui.Elements {
} }
/// <inheritdoc /> /// <inheritdoc />
public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix) { public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, Effect effect, Matrix matrix) {
var tex = this.Texture; var tex = this.Texture;
var color = Color.White * alpha; var color = Color.White * alpha;
if (this.IsMouseOver) { if (this.IsMouseOver) {
@ -96,7 +96,7 @@ namespace MLEM.Ui.Elements {
batch.Draw(tex, boxDisplayArea, color, this.Scale); batch.Draw(tex, boxDisplayArea, color, this.Scale);
if (this.Checked) if (this.Checked)
batch.Draw(this.Checkmark, boxDisplayArea, Color.White * alpha); batch.Draw(this.Checkmark, boxDisplayArea, Color.White * alpha);
base.Draw(time, batch, alpha, blendState, samplerState, matrix); base.Draw(time, batch, alpha, blendState, samplerState, depthStencilState, effect, matrix);
} }
/// <inheritdoc /> /// <inheritdoc />

View file

@ -885,8 +885,10 @@ namespace MLEM.Ui.Elements {
/// <param name="alpha">The alpha to draw this element and its children with</param> /// <param name="alpha">The alpha to draw this element and its children with</param>
/// <param name="blendState">The blend state that is used for drawing</param> /// <param name="blendState">The blend state that is used for drawing</param>
/// <param name="samplerState">The sampler state that is used for drawing</param> /// <param name="samplerState">The sampler state that is used for drawing</param>
/// <param name="effect">The effect that is used for drawing</param>
/// <param name="depthStencilState">The depth stencil state that is used for drawing</param>
/// <param name="matrix">The transformation matrix that is used for drawing</param> /// <param name="matrix">The transformation matrix that is used for drawing</param>
public void DrawTransformed(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix) { public void DrawTransformed(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, Effect effect, Matrix matrix) {
var customDraw = this.BeginImpl != null || this.Transform != Matrix.Identity; var customDraw = this.BeginImpl != null || this.Transform != Matrix.Identity;
var mat = this.Transform * matrix; var mat = this.Transform * matrix;
if (customDraw) { if (customDraw) {
@ -894,18 +896,18 @@ namespace MLEM.Ui.Elements {
batch.End(); batch.End();
// begin our own draw call // begin our own draw call
if (this.BeginImpl != null) { if (this.BeginImpl != null) {
this.BeginImpl(this, time, batch, alpha, blendState, samplerState, mat); this.BeginImpl(this, time, batch, alpha, blendState, samplerState, depthStencilState, effect, mat);
} else { } else {
batch.Begin(SpriteSortMode.Deferred, blendState, samplerState, null, null, null, mat); batch.Begin(SpriteSortMode.Deferred, blendState, samplerState, depthStencilState, null, effect, mat);
} }
} }
// draw content in custom begin call // draw content in custom begin call
this.Draw(time, batch, alpha, blendState, samplerState, mat); this.Draw(time, batch, alpha, blendState, samplerState, depthStencilState, effect, mat);
if (customDraw) { if (customDraw) {
// end our draw // end our draw
batch.End(); batch.End();
// begin the usual draw again for other elements // begin the usual draw again for other elements
batch.Begin(SpriteSortMode.Deferred, blendState, samplerState, null, null, null, matrix); batch.Begin(SpriteSortMode.Deferred, blendState, samplerState, depthStencilState, null, effect, matrix);
} }
} }
@ -918,15 +920,17 @@ namespace MLEM.Ui.Elements {
/// <param name="alpha">The alpha to draw this element and its children with</param> /// <param name="alpha">The alpha to draw this element and its children with</param>
/// <param name="blendState">The blend state that is used for drawing</param> /// <param name="blendState">The blend state that is used for drawing</param>
/// <param name="samplerState">The sampler state that is used for drawing</param> /// <param name="samplerState">The sampler state that is used for drawing</param>
/// <param name="effect">The effect that is used for drawing</param>
/// <param name="depthStencilState">The depth stencil state that is used for drawing</param>
/// <param name="matrix">The transformation matrix that is used for drawing</param> /// <param name="matrix">The transformation matrix that is used for drawing</param>
public virtual void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix) { public virtual void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, Effect effect, Matrix matrix) {
this.System.InvokeOnElementDrawn(this, time, batch, alpha); this.System.InvokeOnElementDrawn(this, time, batch, alpha);
if (this.IsSelected) if (this.IsSelected)
this.System.InvokeOnSelectedElementDrawn(this, time, batch, alpha); this.System.InvokeOnSelectedElementDrawn(this, time, batch, alpha);
foreach (var child in this.GetRelevantChildren()) { foreach (var child in this.GetRelevantChildren()) {
if (!child.IsHidden) if (!child.IsHidden)
child.DrawTransformed(time, batch, alpha * child.DrawAlpha, blendState, samplerState, matrix); child.DrawTransformed(time, batch, alpha * child.DrawAlpha, blendState, samplerState, depthStencilState, effect, matrix);
} }
} }
@ -940,11 +944,13 @@ namespace MLEM.Ui.Elements {
/// <param name="alpha">The alpha to draw this element and its children with</param> /// <param name="alpha">The alpha to draw this element and its children with</param>
/// <param name="blendState">The blend state that is used for drawing</param> /// <param name="blendState">The blend state that is used for drawing</param>
/// <param name="samplerState">The sampler state that is used for drawing</param> /// <param name="samplerState">The sampler state that is used for drawing</param>
/// <param name="effect">The effect that is used for drawing</param>
/// <param name="depthStencilState">The depth stencil state that is used for drawing</param>
/// <param name="matrix">The transformation matrix that is used for drawing</param> /// <param name="matrix">The transformation matrix that is used for drawing</param>
public virtual void DrawEarly(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix) { 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()) { foreach (var child in this.GetRelevantChildren()) {
if (!child.IsHidden) if (!child.IsHidden)
child.DrawEarly(time, batch, alpha * child.DrawAlpha, blendState, samplerState, matrix); child.DrawEarly(time, batch, alpha * child.DrawAlpha, blendState, samplerState, depthStencilState, effect, matrix);
} }
} }
@ -1100,8 +1106,10 @@ namespace MLEM.Ui.Elements {
/// <param name="alpha">This element's draw alpha</param> /// <param name="alpha">This element's draw alpha</param>
/// <param name="blendState">The blend state used for drawing</param> /// <param name="blendState">The blend state used for drawing</param>
/// <param name="samplerState">The sampler state used for drawing</param> /// <param name="samplerState">The sampler state used for drawing</param>
/// <param name="effect">The effect used for drawing</param>
/// <param name="depthStencilState">The depth stencil state used for drawing</param>
/// <param name="matrix">The transform matrix used for drawing</param> /// <param name="matrix">The transform matrix used for drawing</param>
public delegate void BeginDelegate(Element element, GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix); public delegate void BeginDelegate(Element element, GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, Effect effect, Matrix matrix);
} }
} }

View file

@ -20,10 +20,10 @@ namespace MLEM.Ui.Elements {
} }
/// <inheritdoc /> /// <inheritdoc />
public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix) { public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, Effect effect, Matrix matrix) {
// since the group never accesses its own area when drawing, we have to update it manually // since the group never accesses its own area when drawing, we have to update it manually
this.UpdateAreaIfDirty(); this.UpdateAreaIfDirty();
base.Draw(time, batch, alpha, blendState, samplerState, matrix); base.Draw(time, batch, alpha, blendState, samplerState, depthStencilState, effect, matrix);
} }
} }

View file

@ -103,7 +103,7 @@ namespace MLEM.Ui.Elements {
} }
/// <inheritdoc /> /// <inheritdoc />
public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix) { public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, Effect effect, Matrix matrix) {
if (this.Texture == null) if (this.Texture == null)
return; return;
var center = new Vector2(this.Texture.Width / 2F, this.Texture.Height / 2F); var center = new Vector2(this.Texture.Width / 2F, this.Texture.Height / 2F);
@ -116,7 +116,7 @@ namespace MLEM.Ui.Elements {
var scale = new Vector2(1F / this.Texture.Width, 1F / this.Texture.Height) * this.DisplayArea.Size; 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); 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, matrix); base.Draw(time, batch, alpha, blendState, samplerState, depthStencilState, effect, matrix);
} }
/// <summary> /// <summary>

View file

@ -155,12 +155,12 @@ namespace MLEM.Ui.Elements {
} }
/// <inheritdoc /> /// <inheritdoc />
public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix) { public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, Effect effect, Matrix matrix) {
if (this.Texture.HasValue()) if (this.Texture.HasValue())
batch.Draw(this.Texture, this.DisplayArea, this.DrawColor.OrDefault(Color.White) * alpha, this.Scale); 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 we handle overflow, draw using the render target in DrawUnbound
if (!this.scrollOverflow || this.renderTarget == null) { if (!this.scrollOverflow || this.renderTarget == null) {
base.Draw(time, batch, alpha, blendState, samplerState, matrix); base.Draw(time, batch, alpha, blendState, samplerState, depthStencilState, effect, matrix);
} else { } else {
// draw the actual render target (don't apply the alpha here because it's already drawn onto with alpha) // 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); batch.Draw(this.renderTarget, this.GetRenderTargetArea(), Color.White);
@ -168,7 +168,7 @@ namespace MLEM.Ui.Elements {
} }
/// <inheritdoc /> /// <inheritdoc />
public override void DrawEarly(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix) { public override void DrawEarly(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, Effect effect, Matrix matrix) {
this.UpdateAreaIfDirty(); this.UpdateAreaIfDirty();
if (this.scrollOverflow && this.renderTarget != null) { if (this.scrollOverflow && this.renderTarget != null) {
// draw children onto the render target // draw children onto the render target
@ -178,12 +178,12 @@ namespace MLEM.Ui.Elements {
var area = this.GetRenderTargetArea(); var area = this.GetRenderTargetArea();
var trans = Matrix.CreateTranslation(-area.X, -area.Y, 0); var trans = Matrix.CreateTranslation(-area.X, -area.Y, 0);
// do the usual draw, but within the render target // do the usual draw, but within the render target
batch.Begin(SpriteSortMode.Deferred, blendState, samplerState, null, null, null, trans); batch.Begin(SpriteSortMode.Deferred, blendState, samplerState, depthStencilState, null, effect, trans);
base.Draw(time, batch, alpha, blendState, samplerState, trans); base.Draw(time, batch, alpha, blendState, samplerState, depthStencilState, effect, trans);
batch.End(); batch.End();
} }
} }
base.DrawEarly(time, batch, alpha, blendState, samplerState, matrix); base.DrawEarly(time, batch, alpha, blendState, samplerState, depthStencilState, effect, matrix);
} }
/// <inheritdoc /> /// <inheritdoc />

View file

@ -139,12 +139,12 @@ namespace MLEM.Ui.Elements {
} }
/// <inheritdoc /> /// <inheritdoc />
public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix) { public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, Effect effect, Matrix matrix) {
var pos = this.DisplayArea.Location + new Vector2(GetAlignmentOffset(), 0); var pos = this.DisplayArea.Location + new Vector2(GetAlignmentOffset(), 0);
var sc = this.TextScale * this.TextScaleMultiplier * this.Scale; var sc = this.TextScale * this.TextScaleMultiplier * this.Scale;
var color = this.TextColor.OrDefault(Color.White) * alpha; var color = this.TextColor.OrDefault(Color.White) * alpha;
this.TokenizedText.Draw(time, batch, pos, this.RegularFont, color, sc, 0, this.Alignment); this.TokenizedText.Draw(time, batch, pos, this.RegularFont, color, sc, 0, this.Alignment);
base.Draw(time, batch, alpha, blendState, samplerState, matrix); base.Draw(time, batch, alpha, blendState, samplerState, depthStencilState, effect, matrix);
} }
/// <inheritdoc /> /// <inheritdoc />

View file

@ -73,7 +73,7 @@ namespace MLEM.Ui.Elements {
} }
/// <inheritdoc /> /// <inheritdoc />
public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix) { public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, Effect effect, Matrix matrix) {
batch.Draw(this.Texture, this.DisplayArea, (Color) this.Color * alpha, this.Scale); batch.Draw(this.Texture, this.DisplayArea, (Color) this.Color * alpha, this.Scale);
var percentage = this.CurrentValue / this.MaxValue; var percentage = this.CurrentValue / this.MaxValue;
@ -106,7 +106,7 @@ namespace MLEM.Ui.Elements {
} else { } else {
batch.Draw(batch.GetBlankTexture(), offsetArea, (Color) this.ProgressColor * alpha); batch.Draw(batch.GetBlankTexture(), offsetArea, (Color) this.ProgressColor * alpha);
} }
base.Draw(time, batch, alpha, blendState, samplerState, matrix); base.Draw(time, batch, alpha, blendState, samplerState, depthStencilState, effect, matrix);
} }
/// <inheritdoc /> /// <inheritdoc />

View file

@ -205,13 +205,13 @@ namespace MLEM.Ui.Elements {
} }
/// <inheritdoc /> /// <inheritdoc />
public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix) { public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, Effect effect, Matrix matrix) {
batch.Draw(this.Background, this.DisplayArea, Color.White * alpha, this.Scale); batch.Draw(this.Background, this.DisplayArea, Color.White * alpha, this.Scale);
if (this.MaxValue > 0) { if (this.MaxValue > 0) {
var scrollerRect = new RectangleF(this.ScrollerPosition, this.ScrollerSize * this.Scale); var scrollerRect = new RectangleF(this.ScrollerPosition, this.ScrollerSize * this.Scale);
batch.Draw(this.ScrollerTexture, scrollerRect, Color.White * alpha, this.Scale); batch.Draw(this.ScrollerTexture, scrollerRect, Color.White * alpha, this.Scale);
} }
base.Draw(time, batch, alpha, blendState, samplerState, matrix); base.Draw(time, batch, alpha, blendState, samplerState, depthStencilState, effect, matrix);
} }
/// <inheritdoc /> /// <inheritdoc />

View file

@ -285,7 +285,7 @@ namespace MLEM.Ui.Elements {
} }
/// <inheritdoc /> /// <inheritdoc />
public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix) { public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, Effect effect, Matrix matrix) {
var tex = this.Texture; var tex = this.Texture;
var color = Color.White * alpha; var color = Color.White * alpha;
if (this.IsMouseOver) { if (this.IsMouseOver) {
@ -314,7 +314,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); 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, matrix); base.Draw(time, batch, alpha, blendState, samplerState, depthStencilState, effect, matrix);
} }
/// <summary> /// <summary>

View file

@ -83,6 +83,16 @@ namespace MLEM.Ui {
/// </summary> /// </summary>
public SamplerState SamplerState = SamplerState.PointClamp; public SamplerState SamplerState = SamplerState.PointClamp;
/// <summary> /// <summary>
/// The depth stencil state that this ui system and all of its elements draw with.
/// The default is <see cref="Microsoft.Xna.Framework.Graphics.DepthStencilState.None"/>, which is also the default for <see cref="SpriteBatch.Begin"/>.
/// </summary>
public DepthStencilState DepthStencilState = DepthStencilState.None;
/// <summary>
/// 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.
/// </summary>
public Effect Effect;
/// <summary>
/// The <see cref="TextFormatter"/> that this ui system's <see cref="Paragraph"/> elements format their text with. /// The <see cref="TextFormatter"/> that this ui system's <see cref="Paragraph"/> elements format their text with.
/// To add new formatting codes to the ui system, add them to this formatter. /// To add new formatting codes to the ui system, add them to this formatter.
/// </summary> /// </summary>
@ -236,7 +246,7 @@ namespace MLEM.Ui {
public void DrawEarly(GameTime time, SpriteBatch batch) { public void DrawEarly(GameTime time, SpriteBatch batch) {
foreach (var root in this.rootElements) { foreach (var root in this.rootElements) {
if (!root.Element.IsHidden) if (!root.Element.IsHidden)
root.Element.DrawEarly(time, batch, this.DrawAlpha * root.Element.DrawAlpha, this.BlendState, this.SamplerState, root.Transform); root.Element.DrawEarly(time, batch, this.DrawAlpha * root.Element.DrawAlpha, this.BlendState, this.SamplerState, this.DepthStencilState, this.Effect, root.Transform);
} }
} }
@ -250,9 +260,9 @@ namespace MLEM.Ui {
foreach (var root in this.rootElements) { foreach (var root in this.rootElements) {
if (root.Element.IsHidden) if (root.Element.IsHidden)
continue; continue;
batch.Begin(SpriteSortMode.Deferred, this.BlendState, this.SamplerState, null, null, null, root.Transform); batch.Begin(SpriteSortMode.Deferred, this.BlendState, this.SamplerState, this.DepthStencilState, null, this.Effect, root.Transform);
var alpha = this.DrawAlpha * root.Element.DrawAlpha; var alpha = this.DrawAlpha * root.Element.DrawAlpha;
root.Element.DrawTransformed(time, batch, alpha, this.BlendState, this.SamplerState, root.Transform); root.Element.DrawTransformed(time, batch, alpha, this.BlendState, this.SamplerState, this.DepthStencilState, this.Effect, root.Transform);
batch.End(); batch.End();
} }
} }