From 0b8e37fb1d15156a721268df40ab2510386ffc68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Mon, 28 Nov 2016 19:04:03 +0100 Subject: [PATCH] Improve slider rendering by using a buffered container (with depth attachment) and proper alpha blending. --- osu-framework | 2 +- .../Objects/Drawables/DrawableSlider.cs | 67 ++++++++++++++----- 2 files changed, 51 insertions(+), 18 deletions(-) diff --git a/osu-framework b/osu-framework index cc28af53d9..e125c03d8c 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit cc28af53d93e2f1c5f0707c5616ed601e0cf9339 +Subproject commit e125c03d8c39fd86e02e872a8d46654d2ea2759f diff --git a/osu.Game.Mode.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Mode.Osu/Objects/Drawables/DrawableSlider.cs index 3a8db60d61..1d55d704c4 100644 --- a/osu.Game.Mode.Osu/Objects/Drawables/DrawableSlider.cs +++ b/osu.Game.Mode.Osu/Objects/Drawables/DrawableSlider.cs @@ -8,6 +8,9 @@ using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Transformations; using OpenTK.Graphics; using osu.Framework.Input; +using OpenTK.Graphics.ES30; +using osu.Framework.Allocation; +using osu.Framework.Graphics.Textures; namespace osu.Game.Modes.Osu.Objects.Drawables { @@ -29,7 +32,10 @@ namespace osu.Game.Modes.Osu.Objects.Drawables Children = new Drawable[] { - body = new Body(s), + body = new Body(s) + { + Position = s.Position, + }, ball = new Ball(), startCircle = new DrawableHitCircle(new HitCircle { @@ -167,29 +173,40 @@ namespace osu.Game.Modes.Osu.Objects.Drawables private class Body : Container { private Path path; + private BufferedContainer container; private double? drawnProgress; private Slider slider; - public Body(Slider s) { slider = s; Children = new Drawable[] { - //new BufferedContainer - //{ - // RelativeSizeAxes = Axes.Both, - // Children = new Drawable[] - // { + container = new BufferedContainer + { + CacheDrawnFrameBuffer = true, + Children = new Drawable[] + { path = new Path { Colour = s.Colour, + BlendingMode = BlendingMode.None, }, - // } - //} + } + } }; + + container.Attach(RenderbufferInternalFormat.DepthComponent16); + } + + [BackgroundDependencyLoader] + private void load(TextureStore textures) + { + // Surprisingly, this looks somewhat okay and works well as a test for self-overlaps. + // TODO: Don't do this. + path.Texture = textures.Get(@"Menu/logo"); } protected override void LoadComplete() @@ -202,26 +219,40 @@ namespace osu.Game.Modes.Osu.Objects.Drawables { base.Update(); - updateSnaking(); + if (updateSnaking()) + { + // Autosizing does not give us the desired behaviour here. + // We want the container to have the same size as the slider, + // and to be positioned such that the slider head is at (0,0). + container.Size = path.Size; + container.Position = -path.HeadPosition; + + container.ForceRedraw(); + } } - private void updateSnaking() + private bool updateSnaking() { - double progress = MathHelper.Clamp((Time.Current - slider.StartTime + TIME_PREEMPT / 2) / TIME_FADEIN, 0, 1); + double progress = MathHelper.Clamp((Time.Current - slider.StartTime + TIME_PREEMPT) / TIME_FADEIN, 0, 1); - if (progress == drawnProgress) return; + if (progress == drawnProgress) return false; + bool madeChanges = false; if (progress == 0) { //if we have gone backwards, just clear the path for now. drawnProgress = 0; path.ClearVertices(); + madeChanges = true; } + Vector2 startPosition = slider.Curve.PositionAt(0); + if (drawnProgress == null) { drawnProgress = 0; - path.AddVertex(slider.Curve.PositionAt(drawnProgress.Value)); + path.AddVertex(slider.Curve.PositionAt(drawnProgress.Value) - startPosition); + madeChanges = true; } double segmentSize = 1 / (slider.Curve.Length / 5); @@ -229,16 +260,18 @@ namespace osu.Game.Modes.Osu.Objects.Drawables while (drawnProgress + segmentSize < progress) { drawnProgress += segmentSize; - path.AddVertex(slider.Curve.PositionAt(drawnProgress.Value)); + path.AddVertex(slider.Curve.PositionAt(drawnProgress.Value) - startPosition); + madeChanges = true; } if (progress == 1 && drawnProgress != progress) { drawnProgress = progress; - path.AddVertex(slider.Curve.PositionAt(drawnProgress.Value)); + path.AddVertex(slider.Curve.PositionAt(drawnProgress.Value) - startPosition); + madeChanges = true; } - path.Invalidate(Invalidation.DrawNode); + return madeChanges; } } }