From 97e57178a77af3fee0c8cd448df623f042115846 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Thu, 25 May 2017 21:33:04 +0900 Subject: [PATCH 1/5] Make triangles use raw vertices instead of sprites. --- osu-framework | 2 +- osu.Game/Graphics/Backgrounds/Triangles.cs | 211 ++++++++++++++++----- 2 files changed, 166 insertions(+), 47 deletions(-) diff --git a/osu-framework b/osu-framework index 777996fb97..3e989ae630 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 777996fb9731ba1895a5ab1323cbbc97259ff741 +Subproject commit 3e989ae63031a75e622225d6f4d14c6e26170b97 diff --git a/osu.Game/Graphics/Backgrounds/Triangles.cs b/osu.Game/Graphics/Backgrounds/Triangles.cs index 5cca57be8a..28e57eb470 100644 --- a/osu.Game/Graphics/Backgrounds/Triangles.cs +++ b/osu.Game/Graphics/Backgrounds/Triangles.cs @@ -5,16 +5,28 @@ using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Sprites; using osu.Framework.MathUtils; using OpenTK; using OpenTK.Graphics; using System; +using System.Runtime.InteropServices; +using osu.Framework.Graphics.OpenGL; +using osu.Framework.Graphics.Shaders; +using osu.Framework.Graphics.Textures; +using osu.Framework.Graphics.OpenGL.Buffers; +using OpenTK.Graphics.ES30; +using osu.Framework.Graphics.Colour; +using osu.Framework.Graphics.Primitives; +using osu.Framework.Allocation; +using System.Collections.Generic; +using osu.Framework.Graphics.Batches; namespace osu.Game.Graphics.Backgrounds { - public class Triangles : Container + public class Triangles : Drawable { + private const float triangle_size = 100; + public override bool HandleInput => false; public Color4 ColourLight = Color4.White; @@ -49,6 +61,28 @@ public class Triangles : Container /// public float Velocity = 1; + private readonly List parts = new List(); + + private Shader shader; + private readonly Texture texture; + + public Triangles() + { + texture = Texture.WhitePixel; + } + + [BackgroundDependencyLoader] + private void load(ShaderManager shaders) + { + shader = shaders?.Load("Triangles", FragmentShaderDescriptor.TEXTURE_ROUNDED); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + addTriangles(true); + } + public float TriangleScale { get { return triangleScale; } @@ -57,42 +91,69 @@ public float TriangleScale float change = value / triangleScale; triangleScale = value; - if (change != 1) - Children.ForEach(t => t.Scale *= change); + for (int i = 0; i < parts.Count; i++) + { + TriangleParticle newParticle = parts[i]; + newParticle.Scale *= change; + parts[i] = newParticle; + } } } - protected override void LoadComplete() - { - base.LoadComplete(); - - addTriangles(true); - } - - private int aimTriangleCount => (int)(DrawWidth * DrawHeight * 0.002f / (triangleScale * triangleScale) * SpawnRatio); - protected override void Update() { base.Update(); - float adjustedAlpha = HideAlphaDiscrepancies ? - // Cubically scale alpha to make it drop off more sharply. - (float)Math.Pow(DrawInfo.Colour.AverageColour.Linear.A, 3) : - 1; + Invalidate(Invalidation.DrawNode, shallPropagate: false); - foreach (var t in Children) + for (int i = 0; i < parts.Count; i++) { - t.Alpha = adjustedAlpha; - t.Position -= new Vector2(0, (float)(t.Scale.X * (50 / DrawHeight) * (Time.Elapsed / 950)) / triangleScale * Velocity); - if (ExpireOffScreenTriangles && t.DrawPosition.Y + t.DrawSize.Y * t.Scale.Y < 0) - t.Expire(); - } + TriangleParticle newParticle = parts[i]; - if (CreateNewTriangles) - addTriangles(false); + newParticle.Position += new Vector2(0, -(float)(parts[i].Scale * (50 / DrawHeight)) / triangleScale * Velocity) * ((float)Time.Elapsed / 950); + + float adjustedAlpha = HideAlphaDiscrepancies ? + // Cubically scale alpha to make it drop off more sharply. + (float)Math.Pow(DrawInfo.Colour.AverageColour.Linear.A, 3) : + 1; + + newParticle.Colour.A = adjustedAlpha; + + parts[i] = newParticle; + + if (!CreateNewTriangles) + continue; + + float bottomPos = parts[i].Position.Y + triangle_size * parts[i].Scale * 0.866f / DrawHeight; + + if (bottomPos < 0) + parts[i] = createTriangle(false); + } } - protected virtual Triangle CreateTriangle() + private void addTriangles(bool randomY) + { + int aimTriangleCount = (int)(DrawWidth * DrawHeight * 0.002f / (triangleScale * triangleScale) * SpawnRatio); + + for (int i = 0; i < aimTriangleCount; i++) + parts.Add(createTriangle(randomY)); + } + + private TriangleParticle createTriangle(bool randomY) + { + var particle = CreateTriangle(); + + particle.Position = new Vector2(RNG.NextSingle(), randomY ? RNG.NextSingle() : 1); + particle.Colour = CreateTriangleShade(); + + return particle; + } + + /// + /// Creates a triangle particle with a random scale. + /// + /// The triangle particle. + protected virtual TriangleParticle CreateTriangle() { const float std_dev = 0.16f; const float mean = 0.5f; @@ -102,32 +163,90 @@ protected virtual Triangle CreateTriangle() float randStdNormal = (float)(Math.Sqrt(-2.0 * Math.Log(u1)) * Math.Sin(2.0 * Math.PI * u2)); //random normal(0,1) var scale = Math.Max(triangleScale * (mean + std_dev * randStdNormal), 0.1f); //random normal(mean,stdDev^2) - const float size = 100; - - return new EquilateralTriangle - { - Origin = Anchor.TopCentre, - RelativePositionAxes = Axes.Both, - Size = new Vector2(size), - Scale = new Vector2(scale), - EdgeSmoothness = new Vector2(1), - Colour = GetTriangleShade(), - Depth = scale, - }; + return new TriangleParticle { Scale = scale }; } - protected virtual Color4 GetTriangleShade() => Interpolation.ValueAt(RNG.NextSingle(), ColourDark, ColourLight, 0, 1); + /// + /// Creates a shade of colour for the triangles. + /// + /// The colour. + protected virtual Color4 CreateTriangleShade() => Interpolation.ValueAt(RNG.NextSingle(), ColourDark, ColourLight, 0, 1); - private void addTriangles(bool randomY) + protected override DrawNode CreateDrawNode() => new TrianglesDrawNode(); + + private TrianglesDrawNodeSharedData sharedData = new TrianglesDrawNodeSharedData(); + protected override void ApplyDrawNode(DrawNode node) { - int addCount = aimTriangleCount - Children.Count(); - for (int i = 0; i < addCount; i++) + base.ApplyDrawNode(node); + + var trianglesNode = node as TrianglesDrawNode; + + trianglesNode.Shader = shader; + trianglesNode.Texture = texture; + trianglesNode.Size = DrawSize; + trianglesNode.Shared = sharedData; + + trianglesNode.Parts.Clear(); + trianglesNode.Parts.AddRange(parts); + } + + public class TrianglesDrawNodeSharedData + { + public LinearBatch VertexBatch = new LinearBatch(100 * 3, 10, PrimitiveType.Triangles); + } + + public class TrianglesDrawNode : DrawNode + { + public Shader Shader; + public Texture Texture; + + public float Time; + public TrianglesDrawNodeSharedData Shared; + + public readonly List Parts = new List(); + public Vector2 Size; + + public override void Draw(Action vertexAction) { - var sprite = CreateTriangle(); - float triangleHeight = sprite.DrawHeight / DrawHeight; - sprite.Position = new Vector2(RNG.NextSingle(), randomY ? RNG.NextSingle() * (1 + triangleHeight) - triangleHeight : 1); - Add(sprite); + base.Draw(vertexAction); + + Shader.Bind(); + Texture.TextureGL.Bind(); + + int updateStart = -1, updateEnd = 0; + for (int i = 0; i < Parts.Count; ++i) + { + if (updateStart == -1) + updateStart = i; + updateEnd = i + 1; + + TriangleParticle particle = Parts[i]; + + Vector2 offset = new Vector2(particle.Scale * 0.5f, particle.Scale * 0.866f); + + var triangle = new Triangle( + (particle.Position * Size) * DrawInfo.Matrix, + (particle.Position * Size + offset * triangle_size) * DrawInfo.Matrix, + (particle.Position * Size + new Vector2(-offset.X, offset.Y) * triangle_size) * DrawInfo.Matrix + ); + + int index = i * 6; + + ColourInfo colourInfo = DrawInfo.Colour; + colourInfo.ApplyChild(particle.Colour); + + Texture.DrawTriangle(triangle, colourInfo, null, Shared.VertexBatch.Add); + } + + Shader.Unbind(); } } + + public struct TriangleParticle + { + public Vector2 Position; + public Color4 Colour; + public float Scale; + } } } From 86f6db2d31da91beb0734e72b46426875ae6dfc0 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Thu, 25 May 2017 21:33:49 +0900 Subject: [PATCH 2/5] Cleanup. --- osu-framework | 2 +- osu.Game/Graphics/Backgrounds/Triangles.cs | 27 ++++++---------------- 2 files changed, 8 insertions(+), 21 deletions(-) diff --git a/osu-framework b/osu-framework index 3e989ae630..4c84c0ef14 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 3e989ae63031a75e622225d6f4d14c6e26170b97 +Subproject commit 4c84c0ef14ca1fab6098d900c036dff4c85987a5 diff --git a/osu.Game/Graphics/Backgrounds/Triangles.cs b/osu.Game/Graphics/Backgrounds/Triangles.cs index 28e57eb470..702dd7585b 100644 --- a/osu.Game/Graphics/Backgrounds/Triangles.cs +++ b/osu.Game/Graphics/Backgrounds/Triangles.cs @@ -1,19 +1,15 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System.Linq; -using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.MathUtils; using OpenTK; using OpenTK.Graphics; using System; -using System.Runtime.InteropServices; using osu.Framework.Graphics.OpenGL; using osu.Framework.Graphics.Shaders; using osu.Framework.Graphics.Textures; -using osu.Framework.Graphics.OpenGL.Buffers; using OpenTK.Graphics.ES30; using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Primitives; @@ -74,7 +70,7 @@ public Triangles() [BackgroundDependencyLoader] private void load(ShaderManager shaders) { - shader = shaders?.Load("Triangles", FragmentShaderDescriptor.TEXTURE_ROUNDED); + shader = shaders?.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.TEXTURE_ROUNDED); } protected override void LoadComplete() @@ -110,7 +106,7 @@ protected override void Update() { TriangleParticle newParticle = parts[i]; - newParticle.Position += new Vector2(0, -(float)(parts[i].Scale * (50 / DrawHeight)) / triangleScale * Velocity) * ((float)Time.Elapsed / 950); + newParticle.Position += new Vector2(0, -(parts[i].Scale * (50 / DrawHeight)) / triangleScale * Velocity) * ((float)Time.Elapsed / 950); float adjustedAlpha = HideAlphaDiscrepancies ? // Cubically scale alpha to make it drop off more sharply. @@ -174,12 +170,12 @@ protected virtual TriangleParticle CreateTriangle() protected override DrawNode CreateDrawNode() => new TrianglesDrawNode(); - private TrianglesDrawNodeSharedData sharedData = new TrianglesDrawNodeSharedData(); + private readonly TrianglesDrawNodeSharedData sharedData = new TrianglesDrawNodeSharedData(); protected override void ApplyDrawNode(DrawNode node) { base.ApplyDrawNode(node); - var trianglesNode = node as TrianglesDrawNode; + var trianglesNode = (TrianglesDrawNode)node; trianglesNode.Shader = shader; trianglesNode.Texture = texture; @@ -213,25 +209,16 @@ public override void Draw(Action vertexAction) Shader.Bind(); Texture.TextureGL.Bind(); - int updateStart = -1, updateEnd = 0; - for (int i = 0; i < Parts.Count; ++i) + foreach (TriangleParticle particle in Parts) { - if (updateStart == -1) - updateStart = i; - updateEnd = i + 1; - - TriangleParticle particle = Parts[i]; - - Vector2 offset = new Vector2(particle.Scale * 0.5f, particle.Scale * 0.866f); + var offset = new Vector2(particle.Scale * 0.5f, particle.Scale * 0.866f); var triangle = new Triangle( - (particle.Position * Size) * DrawInfo.Matrix, + particle.Position * Size * DrawInfo.Matrix, (particle.Position * Size + offset * triangle_size) * DrawInfo.Matrix, (particle.Position * Size + new Vector2(-offset.X, offset.Y) * triangle_size) * DrawInfo.Matrix ); - int index = i * 6; - ColourInfo colourInfo = DrawInfo.Colour; colourInfo.ApplyChild(particle.Colour); From 91dba765c2f572dcb1b5979ef8e506209441aeed Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Thu, 25 May 2017 22:03:36 +0900 Subject: [PATCH 3/5] Add back the concept of triangle ordering by size. --- osu.Game/Graphics/Backgrounds/Triangles.cs | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/osu.Game/Graphics/Backgrounds/Triangles.cs b/osu.Game/Graphics/Backgrounds/Triangles.cs index 702dd7585b..6cc7857fa9 100644 --- a/osu.Game/Graphics/Backgrounds/Triangles.cs +++ b/osu.Game/Graphics/Backgrounds/Triangles.cs @@ -16,6 +16,7 @@ using osu.Framework.Allocation; using System.Collections.Generic; using osu.Framework.Graphics.Batches; +using osu.Framework.Lists; namespace osu.Game.Graphics.Backgrounds { @@ -57,7 +58,7 @@ public class Triangles : Drawable /// public float Velocity = 1; - private readonly List parts = new List(); + private readonly SortedList parts = new SortedList(Comparer.Default); private Shader shader; private readonly Texture texture; @@ -123,15 +124,17 @@ protected override void Update() float bottomPos = parts[i].Position.Y + triangle_size * parts[i].Scale * 0.866f / DrawHeight; if (bottomPos < 0) - parts[i] = createTriangle(false); + parts.RemoveAt(i); } + + addTriangles(false); } private void addTriangles(bool randomY) { int aimTriangleCount = (int)(DrawWidth * DrawHeight * 0.002f / (triangleScale * triangleScale) * SpawnRatio); - for (int i = 0; i < aimTriangleCount; i++) + for (int i = 0; i < aimTriangleCount - parts.Count; i++) parts.Add(createTriangle(randomY)); } @@ -229,11 +232,20 @@ public override void Draw(Action vertexAction) } } - public struct TriangleParticle + public struct TriangleParticle : IComparable { public Vector2 Position; public Color4 Colour; public float Scale; + + /// + /// Compares two s. This is a reverse comparer because when the + /// triangles are added to the particles list, they should be drawn from largest to smallest + /// such that the smaller triangles appear on top. + /// + /// + /// + public int CompareTo(TriangleParticle other) => other.Scale.CompareTo(Scale); } } } From c8cf387f5ff1d6fc41d02d166ad37759bc5fffca Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Thu, 25 May 2017 22:09:02 +0900 Subject: [PATCH 4/5] A bit more cleanup. --- osu.Game/Graphics/Backgrounds/Triangles.cs | 26 +++++++++++++++------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/osu.Game/Graphics/Backgrounds/Triangles.cs b/osu.Game/Graphics/Backgrounds/Triangles.cs index 6cc7857fa9..9a19819af8 100644 --- a/osu.Game/Graphics/Backgrounds/Triangles.cs +++ b/osu.Game/Graphics/Backgrounds/Triangles.cs @@ -107,13 +107,13 @@ protected override void Update() { TriangleParticle newParticle = parts[i]; - newParticle.Position += new Vector2(0, -(parts[i].Scale * (50 / DrawHeight)) / triangleScale * Velocity) * ((float)Time.Elapsed / 950); - float adjustedAlpha = HideAlphaDiscrepancies ? // Cubically scale alpha to make it drop off more sharply. (float)Math.Pow(DrawInfo.Colour.AverageColour.Linear.A, 3) : 1; + + newParticle.Position += new Vector2(0, -(parts[i].Scale * (50 / DrawHeight)) / triangleScale * Velocity) * ((float)Time.Elapsed / 950); newParticle.Colour.A = adjustedAlpha; parts[i] = newParticle; @@ -140,7 +140,7 @@ private void addTriangles(bool randomY) private TriangleParticle createTriangle(bool randomY) { - var particle = CreateTriangle(); + TriangleParticle particle = CreateTriangle(); particle.Position = new Vector2(RNG.NextSingle(), randomY ? RNG.NextSingle() : 1); particle.Colour = CreateTriangleShade(); @@ -189,17 +189,16 @@ protected override void ApplyDrawNode(DrawNode node) trianglesNode.Parts.AddRange(parts); } - public class TrianglesDrawNodeSharedData + private class TrianglesDrawNodeSharedData { - public LinearBatch VertexBatch = new LinearBatch(100 * 3, 10, PrimitiveType.Triangles); + public readonly LinearBatch VertexBatch = new LinearBatch(100 * 3, 10, PrimitiveType.Triangles); } - public class TrianglesDrawNode : DrawNode + private class TrianglesDrawNode : DrawNode { public Shader Shader; public Texture Texture; - public float Time; public TrianglesDrawNodeSharedData Shared; public readonly List Parts = new List(); @@ -232,10 +231,21 @@ public override void Draw(Action vertexAction) } } - public struct TriangleParticle : IComparable + protected struct TriangleParticle : IComparable { + /// + /// The position of the top vertex of the triangle. + /// public Vector2 Position; + + /// + /// The colour of the triangle. + /// public Color4 Colour; + + /// + /// The scale of the triangle. + /// public float Scale; /// From ec8f49df0fce0b4bdca9c31915a523ffb0f8dc6d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 25 May 2017 22:46:50 +0900 Subject: [PATCH 5/5] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 4c84c0ef14..8baad1b948 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 4c84c0ef14ca1fab6098d900c036dff4c85987a5 +Subproject commit 8baad1b9484b9f35724e2f965c18cfe710907d80