diff --git a/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs b/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs index 236bd3366d..868ef9283d 100644 --- a/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs +++ b/osu.Game/Screens/Play/HUD/ArgonHealthDisplay.cs @@ -19,6 +19,7 @@ using osu.Game.Configuration; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; +using osu.Game.Screens.Play.HUD.ArgonHealthDisplayParts; using osu.Game.Skinning; using osuTK; using osuTK.Graphics; @@ -100,6 +101,14 @@ namespace osu.Game.Screens.Play.HUD background = new BackgroundPath { PathRadius = MAIN_PATH_RADIUS, + Alpha = 0, + AlwaysPresent = true + }, + new ArgonHealthDisplayBackground + { + RelativeSizeAxes = Axes.Both, + PathRadius = MAIN_PATH_RADIUS, + PathPadding = MAIN_PATH_RADIUS }, glowBar = new BarPath { @@ -121,7 +130,7 @@ namespace osu.Game.Screens.Play.HUD GlowColour = main_bar_glow_colour, PathRadius = MAIN_PATH_RADIUS, GlowPortion = 0.6f, - }, + } } }; } diff --git a/osu.Game/Screens/Play/HUD/ArgonHealthDisplayParts/ArgonHealthDisplayBackground.cs b/osu.Game/Screens/Play/HUD/ArgonHealthDisplayParts/ArgonHealthDisplayBackground.cs new file mode 100644 index 0000000000..a819fb6f30 --- /dev/null +++ b/osu.Game/Screens/Play/HUD/ArgonHealthDisplayParts/ArgonHealthDisplayBackground.cs @@ -0,0 +1,168 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +#nullable disable + +using System; +using System.Runtime.InteropServices; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Rendering; +using osu.Framework.Graphics.Shaders; +using osu.Framework.Graphics.Shaders.Types; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; +using osuTK; + +namespace osu.Game.Screens.Play.HUD.ArgonHealthDisplayParts +{ + public partial class ArgonHealthDisplayBackground : Box + { + private float endProgress = 1f; + + public float EndProgress + { + get => endProgress; + set + { + if (endProgress == value) + return; + + endProgress = value; + Invalidate(Invalidation.DrawNode); + } + } + + private float startProgress = 0f; + + public float StartProgress + { + get => startProgress; + set + { + if (startProgress == value) + return; + + startProgress = value; + Invalidate(Invalidation.DrawNode); + } + } + + private float radius = 10f; + + public float PathRadius + { + get => radius; + set + { + if (radius == value) + return; + + radius = value; + Invalidate(Invalidation.DrawNode); + } + } + + private float padding = 10f; + + public float PathPadding + { + get => padding; + set + { + if (padding == value) + return; + + padding = value; + Invalidate(Invalidation.DrawNode); + } + } + + [BackgroundDependencyLoader] + private void load(ShaderManager shaders) + { + TextureShader = shaders.Load(VertexShaderDescriptor.TEXTURE_2, "ArgonBarPathBackground"); + } + + protected override void Update() + { + base.Update(); + Invalidate(Invalidation.DrawNode); + } + + protected override DrawNode CreateDrawNode() => new ArgonBarPathDrawNode(this); + + private class ArgonBarPathDrawNode : SpriteDrawNode + { + protected new ArgonHealthDisplayBackground Source => (ArgonHealthDisplayBackground)base.Source; + + public ArgonBarPathDrawNode(ArgonHealthDisplayBackground source) + : base(source) + { + } + + private Vector2 size; + private float startProgress; + private float endProgress; + private float pathRadius; + private float padding; + + public override void ApplyState() + { + base.ApplyState(); + + size = Source.DrawSize; + endProgress = Source.endProgress; + startProgress = Math.Min(Source.startProgress, endProgress); + pathRadius = Source.PathRadius; + padding = Source.PathPadding; + } + + protected override void Draw(IRenderer renderer) + { + if (pathRadius == 0) + return; + + base.Draw(renderer); + } + + private IUniformBuffer parametersBuffer; + + protected override void BindUniformResources(IShader shader, IRenderer renderer) + { + base.BindUniformResources(shader, renderer); + + parametersBuffer ??= renderer.CreateUniformBuffer(); + parametersBuffer.Data = new ArgonBarPathBackgroundParameters + { + Size = size, + StartProgress = startProgress, + EndProgress = endProgress, + PathRadius = pathRadius, + Padding = padding + }; + + shader.BindUniformBlock("m_ArgonBarPathBackgroundParameters", parametersBuffer); + } + + protected override bool CanDrawOpaqueInterior => false; + + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + parametersBuffer?.Dispose(); + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + private record struct ArgonBarPathBackgroundParameters + { + public UniformVector2 Size; + public UniformFloat StartProgress; + public UniformFloat EndProgress; + public UniformFloat PathRadius; + public UniformFloat Padding; + private UniformPadding8 pad; + } + } + } +}