A game framework written with osu! in mind.
1// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
2// See the LICENCE file in the repository root for full licence text.
3
4using System;
5using NUnit.Framework;
6using osu.Framework.Allocation;
7using osu.Framework.Configuration;
8using osu.Framework.Graphics;
9using osu.Framework.Graphics.Containers;
10using osu.Framework.Graphics.Shapes;
11using osu.Framework.Graphics.Sprites;
12using osu.Framework.Testing;
13using osuTK;
14using osuTK.Graphics;
15
16namespace osu.Framework.Tests.Visual.Containers
17{
18 public class TestSceneFrontToBackBox : FrameworkTestScene
19 {
20 [Resolved]
21 private FrameworkDebugConfigManager debugConfig { get; set; }
22
23 private TestBox blendedBox;
24
25 [SetUp]
26 public void Setup() => Schedule(() =>
27 {
28 Clear();
29 });
30
31 [TearDownSteps]
32 public void TearDownSteps()
33 {
34 AddToggleStep("disable front to back", val => debugConfig.SetValue(DebugSetting.BypassFrontToBackPass, val));
35 }
36
37 [Test]
38 public void TestOpaqueBoxWithMixedBlending()
39 {
40 createBlendedBox();
41 AddAssert("renders interior", () => blendedBox.CanDrawOpaqueInterior);
42 }
43
44 [Test]
45 public void TestTransparentBoxWithMixedBlending()
46 {
47 createBlendedBox(b => b.Alpha = 0.5f);
48 AddAssert("doesn't render interior", () => !blendedBox.CanDrawOpaqueInterior);
49 }
50
51 [Test]
52 public void TestOpaqueBoxWithAdditiveBlending()
53 {
54 createBlendedBox(b => b.Blending = BlendingParameters.Additive);
55 AddAssert("doesn't render interior", () => !blendedBox.CanDrawOpaqueInterior);
56 }
57
58 [Test]
59 public void TestTransparentBoxWithAdditiveBlending()
60 {
61 createBlendedBox(b =>
62 {
63 b.Blending = BlendingParameters.Additive;
64 b.Alpha = 0.5f;
65 });
66
67 AddAssert("doesn't render interior", () => !blendedBox.CanDrawOpaqueInterior);
68 }
69
70 [TestCase(BlendingEquation.Max)]
71 [TestCase(BlendingEquation.Min)]
72 [TestCase(BlendingEquation.Subtract)]
73 [TestCase(BlendingEquation.ReverseSubtract)]
74 public void TestOpaqueBoxWithNonAddRGBEquation(BlendingEquation equationMode)
75 {
76 createBlendedBox(b =>
77 {
78 var blending = BlendingParameters.Inherit;
79 blending.RGBEquation = equationMode;
80 b.Blending = blending;
81 });
82
83 AddAssert("doesn't render interior", () => !blendedBox.CanDrawOpaqueInterior);
84 }
85
86 [TestCase(BlendingEquation.Max)]
87 [TestCase(BlendingEquation.Min)]
88 [TestCase(BlendingEquation.Subtract)]
89 [TestCase(BlendingEquation.ReverseSubtract)]
90 public void TestOpaqueBoxWithNonAddAlphaEquation(BlendingEquation equationMode)
91 {
92 createBlendedBox(b =>
93 {
94 var blending = BlendingParameters.Inherit;
95 blending.AlphaEquation = equationMode;
96 b.Blending = blending;
97 });
98
99 AddAssert("doesn't render interior", () => !blendedBox.CanDrawOpaqueInterior);
100 }
101
102 [Test]
103 public void TestSmallSizeMasking()
104 {
105 AddStep("create test", () =>
106 {
107 Children = new Drawable[]
108 {
109 new SpriteText
110 {
111 Anchor = Anchor.Centre,
112 Origin = Anchor.Centre,
113 Y = -120,
114 Text = "No rounded corners should be visible below",
115 },
116 new Container
117 {
118 Anchor = Anchor.Centre,
119 Origin = Anchor.Centre,
120 Size = new Vector2(20),
121 Children = new Drawable[]
122 {
123 new Box
124 {
125 RelativeSizeAxes = Axes.Both,
126 Colour = Color4.Green
127 },
128 new Container
129 {
130 Anchor = Anchor.Centre,
131 Origin = Anchor.Centre,
132 RelativeSizeAxes = Axes.Both,
133 Masking = true,
134 CornerRadius = 40,
135 Child = new Box
136 {
137 Anchor = Anchor.Centre,
138 Origin = Anchor.Centre,
139 RelativeSizeAxes = Axes.Both,
140 Colour = Color4.Green
141 }
142 }
143 }
144 }
145 };
146 });
147 }
148
149 [Test]
150 public void TestNegativeSizeMasking()
151 {
152 AddStep("create test", () =>
153 {
154 Children = new Drawable[]
155 {
156 new SpriteText
157 {
158 Anchor = Anchor.Centre,
159 Origin = Anchor.Centre,
160 Y = -120,
161 Text = "No rounded corners should be visible below",
162 },
163 new Container
164 {
165 Anchor = Anchor.Centre,
166 Origin = Anchor.Centre,
167 Size = new Vector2(200),
168 Children = new Drawable[]
169 {
170 new Box
171 {
172 RelativeSizeAxes = Axes.Both,
173 Colour = Color4.Green
174 },
175 new Container
176 {
177 Anchor = Anchor.Centre,
178 Origin = Anchor.Centre,
179 RelativeSizeAxes = Axes.Both,
180 Size = new Vector2(-1f),
181 Masking = true,
182 CornerRadius = 20,
183 Child = new Box
184 {
185 Anchor = Anchor.Centre,
186 Origin = Anchor.Centre,
187 RelativeSizeAxes = Axes.Both,
188 Colour = Color4.Green
189 }
190 }
191 }
192 }
193 };
194 });
195 }
196
197 private void createBlendedBox(Action<Box> setupAction = null) => AddStep("create box", () =>
198 {
199 Child = new Container
200 {
201 Anchor = Anchor.Centre,
202 Origin = Anchor.Centre,
203 Size = new Vector2(200),
204 Children = new Drawable[]
205 {
206 new Box
207 {
208 RelativeSizeAxes = Axes.Both,
209 Colour = new Color4(50, 50, 50, 255)
210 },
211 blendedBox = new TestBox
212 {
213 Anchor = Anchor.Centre,
214 Origin = Anchor.Centre,
215 RelativeSizeAxes = Axes.Both,
216 Colour = new Color4(100, 100, 100, 255),
217 Size = new Vector2(0.5f),
218 }
219 }
220 };
221
222 setupAction?.Invoke(blendedBox);
223 });
224
225 private class TestBox : Box
226 {
227 public bool CanDrawOpaqueInterior => currentDrawNode.CanDrawOpaqueInterior;
228
229 private DrawNode currentDrawNode;
230
231 protected override DrawNode CreateDrawNode() => new TestBoxDrawNode(this);
232
233 internal override DrawNode GenerateDrawNodeSubtree(ulong frame, int treeIndex, bool forceNewDrawNode)
234 => currentDrawNode = base.GenerateDrawNodeSubtree(frame, treeIndex, forceNewDrawNode);
235
236 private class TestBoxDrawNode : SpriteDrawNode
237 {
238 public TestBoxDrawNode(Box source)
239 : base(source)
240 {
241 }
242 }
243 }
244 }
245}