A game framework written with osu! in mind.
at master 307 lines 13 kB view raw
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 System.Collections.Generic; 6using osu.Framework.Graphics; 7using osu.Framework.Graphics.Colour; 8using osu.Framework.Graphics.Containers; 9using osu.Framework.Graphics.Shapes; 10using osu.Framework.Graphics.Sprites; 11using osu.Framework.Graphics.UserInterface; 12using osu.Framework.Logging; 13using osuTK; 14using osuTK.Graphics; 15 16namespace osu.Framework.Tests.Visual.Drawables 17{ 18 public class TestSceneComplexBlending : FrameworkTestScene 19 { 20 private readonly Dropdown<string> colourModeDropdown; 21 private readonly Dropdown<BlendingEquation> colourEquation; 22 private readonly Dropdown<BlendingEquation> alphaEquation; 23 private readonly BufferedContainer foregroundContainer; 24 25 private readonly FillFlowContainer blendingSrcContainer; 26 private readonly FillFlowContainer blendingDestContainer; 27 private readonly FillFlowContainer blendingAlphaSrcContainer; 28 private readonly FillFlowContainer blendingAlphaDestContainer; 29 30 private readonly Dropdown<BlendingType> blendingSrcDropdown; 31 private readonly Dropdown<BlendingType> blendingDestDropdown; 32 private readonly Dropdown<BlendingType> blendingAlphaSrcDropdown; 33 private readonly Dropdown<BlendingType> blendingAlphaDestDropdown; 34 35 private readonly FillFlowContainer settingsBox; 36 37 private readonly Dictionary<string, BlendingParameters> blendingModes = new Dictionary<string, BlendingParameters> 38 { 39 { "Inherit", BlendingParameters.Inherit }, 40 { "Additive", BlendingParameters.Additive }, 41 { "Mixture", BlendingParameters.Mixture }, 42 { "Custom", BlendingParameters.Mixture }, 43 }; 44 45 private bool inCustomMode; 46 47 public TestSceneComplexBlending() 48 { 49 Children = new Drawable[] 50 { 51 settingsBox = new FillFlowContainer 52 { 53 Name = "Settings", 54 AutoSizeAxes = Axes.Both, 55 Y = 50, 56 Direction = FillDirection.Vertical, 57 Spacing = new Vector2(0, 20), 58 Children = new Drawable[] 59 { 60 new FillFlowContainer 61 { 62 AutoSizeAxes = Axes.Both, 63 Direction = FillDirection.Vertical, 64 Spacing = new Vector2(0, 5), 65 Children = new Drawable[] 66 { 67 new SpriteText { Text = "Blending mode" }, 68 colourModeDropdown = new BasicDropdown<string> { Width = 200 } 69 } 70 }, 71 new FillFlowContainer 72 { 73 AutoSizeAxes = Axes.Both, 74 Direction = FillDirection.Vertical, 75 Spacing = new Vector2(0, 5), 76 Children = new Drawable[] 77 { 78 new SpriteText { Text = "Blending equation (colour)" }, 79 colourEquation = new BasicDropdown<BlendingEquation> { Width = 200 } 80 } 81 }, 82 new FillFlowContainer 83 { 84 AutoSizeAxes = Axes.Both, 85 Direction = FillDirection.Vertical, 86 Spacing = new Vector2(0, 5), 87 Children = new Drawable[] 88 { 89 new SpriteText { Text = "Blending equation (alpha)" }, 90 alphaEquation = new BasicDropdown<BlendingEquation> { Width = 200 } 91 } 92 } 93 } 94 }, 95 new SpriteText 96 { 97 Anchor = Anchor.Centre, 98 Origin = Anchor.Centre, 99 Text = "Behind background" 100 }, 101 new BufferedContainer 102 { 103 Name = "Background", 104 Anchor = Anchor.Centre, 105 Origin = Anchor.Centre, 106 RelativeSizeAxes = Axes.Both, 107 FillMode = FillMode.Fit, 108 Size = new Vector2(0.85f), 109 Masking = true, 110 Children = new Drawable[] 111 { 112 new GradientPart(0, Color4.Orange, Color4.Yellow), 113 new GradientPart(1, Color4.Yellow, Color4.Green), 114 new GradientPart(2, Color4.Green, Color4.Cyan), 115 new GradientPart(3, Color4.Cyan, Color4.Blue), 116 new GradientPart(4, Color4.Blue, Color4.Violet), 117 foregroundContainer = new BufferedContainer 118 { 119 Name = "Foreground", 120 Anchor = Anchor.Centre, 121 Origin = Anchor.Centre, 122 RelativeSizeAxes = Axes.Both, 123 Alpha = 0.8f, 124 Children = new[] 125 { 126 new Circle 127 { 128 Anchor = Anchor.Centre, 129 Origin = Anchor.Centre, 130 RelativePositionAxes = Axes.Both, 131 RelativeSizeAxes = Axes.Both, 132 Size = new Vector2(0.45f), 133 Y = -0.15f, 134 Colour = Color4.Cyan 135 }, 136 new Circle 137 { 138 Anchor = Anchor.Centre, 139 Origin = Anchor.Centre, 140 RelativePositionAxes = Axes.Both, 141 RelativeSizeAxes = Axes.Both, 142 Size = new Vector2(0.45f), 143 X = -0.15f, 144 Colour = Color4.Magenta 145 }, 146 new Circle 147 { 148 Anchor = Anchor.Centre, 149 Origin = Anchor.Centre, 150 RelativePositionAxes = Axes.Both, 151 RelativeSizeAxes = Axes.Both, 152 Size = new Vector2(0.45f), 153 X = 0.15f, 154 Colour = Color4.Yellow 155 }, 156 } 157 }, 158 } 159 }, 160 }; 161 162 blendingSrcContainer = new FillFlowContainer 163 { 164 AutoSizeAxes = Axes.Both, 165 Direction = FillDirection.Vertical, 166 Spacing = new Vector2(0, 5), 167 Children = new Drawable[] 168 { 169 new SpriteText { Text = "Custom: Source" }, 170 blendingSrcDropdown = new BasicDropdown<BlendingType> { Width = 200 } 171 }, 172 }; 173 174 blendingDestContainer = new FillFlowContainer 175 { 176 AutoSizeAxes = Axes.Both, 177 Direction = FillDirection.Vertical, 178 Spacing = new Vector2(0, 5), 179 Children = new Drawable[] 180 { 181 new SpriteText { Text = "Custom: Destination" }, 182 blendingDestDropdown = new BasicDropdown<BlendingType> { Width = 200 } 183 }, 184 }; 185 186 blendingAlphaSrcContainer = new FillFlowContainer 187 { 188 AutoSizeAxes = Axes.Both, 189 Direction = FillDirection.Vertical, 190 Spacing = new Vector2(0, 5), 191 Children = new Drawable[] 192 { 193 new SpriteText { Text = "Custom: Alpha Source" }, 194 blendingAlphaSrcDropdown = new BasicDropdown<BlendingType> { Width = 200 } 195 }, 196 }; 197 198 blendingAlphaDestContainer = new FillFlowContainer 199 { 200 AutoSizeAxes = Axes.Both, 201 Direction = FillDirection.Vertical, 202 Spacing = new Vector2(0, 5), 203 Children = new Drawable[] 204 { 205 new SpriteText { Text = "Custom: Alpha Destination" }, 206 blendingAlphaDestDropdown = new BasicDropdown<BlendingType> { Width = 200 } 207 }, 208 }; 209 210 colourModeDropdown.Items = blendingModes.Keys; 211 colourEquation.Items = (BlendingEquation[])Enum.GetValues(typeof(BlendingEquation)); 212 alphaEquation.Items = (BlendingEquation[])Enum.GetValues(typeof(BlendingEquation)); 213 214 blendingSrcDropdown.Items = (BlendingType[])Enum.GetValues(typeof(BlendingType)); 215 blendingDestDropdown.Items = (BlendingType[])Enum.GetValues(typeof(BlendingType)); 216 blendingAlphaSrcDropdown.Items = (BlendingType[])Enum.GetValues(typeof(BlendingType)); 217 blendingAlphaDestDropdown.Items = (BlendingType[])Enum.GetValues(typeof(BlendingType)); 218 219 colourModeDropdown.Current.Value = "Mixture"; 220 colourEquation.Current.Value = foregroundContainer.Blending.RGBEquation; 221 alphaEquation.Current.Value = foregroundContainer.Blending.AlphaEquation; 222 223 blendingSrcDropdown.Current.Value = BlendingType.SrcAlpha; 224 blendingDestDropdown.Current.Value = BlendingType.OneMinusSrcAlpha; 225 blendingAlphaSrcDropdown.Current.Value = BlendingType.One; 226 blendingAlphaDestDropdown.Current.Value = BlendingType.One; 227 228 colourModeDropdown.Current.ValueChanged += v => updateBlending(); 229 colourEquation.Current.ValueChanged += v => updateBlending(); 230 alphaEquation.Current.ValueChanged += v => updateBlending(); 231 blendingSrcDropdown.Current.ValueChanged += v => updateBlending(); 232 blendingDestDropdown.Current.ValueChanged += v => updateBlending(); 233 blendingAlphaSrcDropdown.Current.ValueChanged += v => updateBlending(); 234 blendingAlphaDestDropdown.Current.ValueChanged += v => updateBlending(); 235 } 236 237 private void switchToCustomBlending() 238 { 239 settingsBox.Add(blendingSrcContainer); 240 settingsBox.Add(blendingDestContainer); 241 settingsBox.Add(blendingAlphaSrcContainer); 242 settingsBox.Add(blendingAlphaDestContainer); 243 } 244 245 private void switchOffCustomBlending() 246 { 247 settingsBox.Remove(blendingSrcContainer); 248 settingsBox.Remove(blendingDestContainer); 249 settingsBox.Remove(blendingAlphaSrcContainer); 250 settingsBox.Remove(blendingAlphaDestContainer); 251 } 252 253 private void updateBlending() 254 { 255 if (colourModeDropdown.Current.Value == "Custom") 256 { 257 if (!inCustomMode) 258 switchToCustomBlending(); 259 260 var blending = new BlendingParameters 261 { 262 Source = blendingSrcDropdown.Current.Value, 263 Destination = blendingDestDropdown.Current.Value, 264 SourceAlpha = blendingAlphaSrcDropdown.Current.Value, 265 DestinationAlpha = blendingAlphaDestDropdown.Current.Value, 266 RGBEquation = colourEquation.Current.Value, 267 AlphaEquation = alphaEquation.Current.Value 268 }; 269 270 Logger.Log("Changed blending mode to: " + blending, LoggingTarget.Runtime, LogLevel.Debug); 271 272 foregroundContainer.Blending = blending; 273 274 inCustomMode = true; 275 } 276 else 277 { 278 if (inCustomMode) 279 switchOffCustomBlending(); 280 281 var blending = blendingModes[colourModeDropdown.Current.Value]; 282 283 blending.RGBEquation = colourEquation.Current.Value; 284 blending.AlphaEquation = alphaEquation.Current.Value; 285 286 Logger.Log("Changed blending mode to: " + blending, LoggingTarget.Runtime, LogLevel.Debug); 287 288 foregroundContainer.Blending = blending; 289 290 inCustomMode = false; 291 } 292 } 293 294 private class GradientPart : Box 295 { 296 public GradientPart(int index, Color4 start, Color4 end) 297 { 298 RelativeSizeAxes = Axes.Both; 299 RelativePositionAxes = Axes.Both; 300 Width = 1 / 5f; // Assume 5 gradients 301 X = 1 / 5f * index; 302 303 Colour = ColourInfo.GradientHorizontal(start, end); 304 } 305 } 306 } 307}