diff --git a/osu.Game.Tests/Visual/Background/TestSceneTrianglesV2Background.cs b/osu.Game.Tests/Visual/Background/TestSceneTrianglesV2Background.cs
index ae1f3de6bf..01a2464b8e 100644
--- a/osu.Game.Tests/Visual/Background/TestSceneTrianglesV2Background.cs
+++ b/osu.Game.Tests/Visual/Background/TestSceneTrianglesV2Background.cs
@@ -8,12 +8,14 @@ using osuTK;
using osuTK.Graphics;
using osu.Game.Graphics.Backgrounds;
using osu.Framework.Graphics.Colour;
+using osu.Game.Graphics.Sprites;
namespace osu.Game.Tests.Visual.Background
{
public partial class TestSceneTrianglesV2Background : OsuTestScene
{
private readonly TrianglesV2 triangles;
+ private readonly TrianglesV2 maskedTriangles;
private readonly Box box;
public TestSceneTrianglesV2Background()
@@ -31,12 +33,20 @@ namespace osu.Game.Tests.Visual.Background
Origin = Anchor.Centre,
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Vertical,
- Spacing = new Vector2(0, 5),
+ Spacing = new Vector2(0, 10),
Children = new Drawable[]
{
+ new OsuSpriteText
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Text = "Masked"
+ },
new Container
{
Size = new Vector2(500, 100),
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
Masking = true,
CornerRadius = 40,
Children = new Drawable[]
@@ -54,9 +64,43 @@ namespace osu.Game.Tests.Visual.Background
}
}
},
+ new OsuSpriteText
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Text = "Non-masked"
+ },
new Container
{
Size = new Vector2(500, 100),
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Children = new Drawable[]
+ {
+ new Box
+ {
+ RelativeSizeAxes = Axes.Both,
+ Colour = Color4.Red
+ },
+ maskedTriangles = new TrianglesV2
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ RelativeSizeAxes = Axes.Both
+ }
+ }
+ },
+ new OsuSpriteText
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Text = "Gradient comparison box"
+ },
+ new Container
+ {
+ Size = new Vector2(500, 100),
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
Masking = true,
CornerRadius = 40,
Child = box = new Box
@@ -75,14 +119,16 @@ namespace osu.Game.Tests.Visual.Background
AddSliderStep("Spawn ratio", 0f, 10f, 1f, s =>
{
- triangles.SpawnRatio = s;
+ triangles.SpawnRatio = maskedTriangles.SpawnRatio = s;
triangles.Reset(1234);
+ maskedTriangles.Reset(1234);
});
- AddSliderStep("Thickness", 0f, 1f, 0.02f, t => triangles.Thickness = t);
+ AddSliderStep("Thickness", 0f, 1f, 0.02f, t => triangles.Thickness = maskedTriangles.Thickness = t);
- AddStep("White colour", () => box.Colour = triangles.Colour = Color4.White);
- AddStep("Vertical gradient", () => box.Colour = triangles.Colour = ColourInfo.GradientVertical(Color4.White, Color4.Red));
- AddStep("Horizontal gradient", () => box.Colour = triangles.Colour = ColourInfo.GradientHorizontal(Color4.White, Color4.Red));
+ AddStep("White colour", () => box.Colour = triangles.Colour = maskedTriangles.Colour = Color4.White);
+ AddStep("Vertical gradient", () => box.Colour = triangles.Colour = maskedTriangles.Colour = ColourInfo.GradientVertical(Color4.White, Color4.Red));
+ AddStep("Horizontal gradient", () => box.Colour = triangles.Colour = maskedTriangles.Colour = ColourInfo.GradientHorizontal(Color4.White, Color4.Red));
+ AddToggleStep("Masking", m => maskedTriangles.Masking = m);
}
}
}
diff --git a/osu.Game/Graphics/Backgrounds/TrianglesV2.cs b/osu.Game/Graphics/Backgrounds/TrianglesV2.cs
index d543f082b4..3bc8bb6df1 100644
--- a/osu.Game/Graphics/Backgrounds/TrianglesV2.cs
+++ b/osu.Game/Graphics/Backgrounds/TrianglesV2.cs
@@ -34,6 +34,12 @@ namespace osu.Game.Graphics.Backgrounds
///
protected virtual bool CreateNewTriangles => true;
+ ///
+ /// If enabled, only the portion of triangles that falls within this 's
+ /// shape is drawn to the screen.
+ ///
+ public bool Masking { get; set; }
+
private readonly BindableFloat spawnRatio = new BindableFloat(1f);
///
@@ -189,6 +195,7 @@ namespace osu.Game.Graphics.Backgrounds
private Vector2 size;
private float thickness;
private float texelSize;
+ private bool masking;
private IVertexBatch? vertexBatch;
@@ -205,6 +212,7 @@ namespace osu.Game.Graphics.Backgrounds
texture = Source.texture;
size = Source.DrawSize;
thickness = Source.Thickness;
+ masking = Source.Masking;
Quad triangleQuad = new Quad(
Vector2Extensions.Transform(Vector2.Zero, DrawInfo.Matrix),
@@ -236,26 +244,31 @@ namespace osu.Game.Graphics.Backgrounds
shader.GetUniform("thickness").UpdateValue(ref thickness);
shader.GetUniform("texelSize").UpdateValue(ref texelSize);
- float relativeHeight = triangleSize.Y / size.Y;
- float relativeWidth = triangleSize.X / size.X;
+ Vector2 relativeSize = Vector2.Divide(triangleSize, size);
foreach (TriangleParticle particle in parts)
{
- Vector2 topLeft = particle.Position - new Vector2(relativeWidth * 0.5f, 0f);
- Vector2 topRight = topLeft + new Vector2(relativeWidth, 0f);
- Vector2 bottomLeft = topLeft + new Vector2(0f, relativeHeight);
- Vector2 bottomRight = bottomLeft + new Vector2(relativeWidth, 0f);
+ Vector2 topLeft = particle.Position - new Vector2(relativeSize.X * 0.5f, 0f);
+
+ Quad triangleQuad = masking ? clampToDrawable(topLeft, relativeSize) : new Quad(topLeft.X, topLeft.Y, relativeSize.X, relativeSize.Y);
var drawQuad = new Quad(
- Vector2Extensions.Transform(topLeft * size, DrawInfo.Matrix),
- Vector2Extensions.Transform(topRight * size, DrawInfo.Matrix),
- Vector2Extensions.Transform(bottomLeft * size, DrawInfo.Matrix),
- Vector2Extensions.Transform(bottomRight * size, DrawInfo.Matrix)
+ Vector2Extensions.Transform(triangleQuad.TopLeft * size, DrawInfo.Matrix),
+ Vector2Extensions.Transform(triangleQuad.TopRight * size, DrawInfo.Matrix),
+ Vector2Extensions.Transform(triangleQuad.BottomLeft * size, DrawInfo.Matrix),
+ Vector2Extensions.Transform(triangleQuad.BottomRight * size, DrawInfo.Matrix)
);
- ColourInfo colourInfo = triangleColourInfo(DrawColourInfo.Colour, new Quad(topLeft, topRight, bottomLeft, bottomRight));
+ ColourInfo colourInfo = triangleColourInfo(DrawColourInfo.Colour, triangleQuad);
- renderer.DrawQuad(texture, drawQuad, colourInfo, vertexAction: vertexBatch.AddAction);
+ RectangleF textureCoords = new RectangleF(
+ triangleQuad.TopLeft.X - topLeft.X,
+ triangleQuad.TopLeft.Y - topLeft.Y,
+ triangleQuad.Width,
+ triangleQuad.Height
+ ) / relativeSize;
+
+ renderer.DrawQuad(texture, drawQuad, colourInfo, new RectangleF(0, 0, 1, 1), vertexBatch.AddAction, textureCoords: textureCoords);
}
shader.Unbind();
@@ -272,6 +285,19 @@ namespace osu.Game.Graphics.Backgrounds
};
}
+ private static Quad clampToDrawable(Vector2 topLeft, Vector2 size)
+ {
+ float leftClamped = Math.Clamp(topLeft.X, 0f, 1f);
+ float topClamped = Math.Clamp(topLeft.Y, 0f, 1f);
+
+ return new Quad(
+ leftClamped,
+ topClamped,
+ Math.Clamp(topLeft.X + size.X, 0f, 1f) - leftClamped,
+ Math.Clamp(topLeft.Y + size.Y, 0f, 1f) - topClamped
+ );
+ }
+
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);