A game framework written with osu! in mind.
at master 6.8 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 osu.Framework.Allocation; 6using osu.Framework.Configuration; 7using osu.Framework.Graphics; 8using osu.Framework.Graphics.Containers; 9using osu.Framework.Graphics.OpenGL; 10using osu.Framework.Graphics.OpenGL.Vertices; 11using osu.Framework.Graphics.Shapes; 12using osu.Framework.Graphics.Sprites; 13using osu.Framework.Utils; 14using osu.Framework.Testing; 15using osuTK; 16using osuTK.Graphics; 17using osuTK.Graphics.ES30; 18using osu.Framework.Graphics.Textures; 19using osu.Framework.Graphics.Primitives; 20using osu.Framework.Graphics.OpenGL.Textures; 21 22namespace osu.Framework.Tests.Visual.Containers 23{ 24 public class TestSceneFrontToBack : GridTestScene 25 { 26 private SpriteText labelDrawables; 27 private QueryingCompositeDrawableDrawNode drawNode; 28 private SpriteText labelFrag; 29 private SpriteText labelFrag2; 30 private float currentScale = 1; 31 32 private const int cell_count = 4; 33 34 protected override DrawNode CreateDrawNode() => drawNode = new QueryingCompositeDrawableDrawNode(this); 35 36 public TestSceneFrontToBack() 37 : base(cell_count / 2, cell_count / 2) 38 { 39 } 40 41 [BackgroundDependencyLoader] 42 private void load(FrameworkDebugConfigManager debugConfig, TextureStore store) 43 { 44 var texture = store.Get(@"sample-texture"); 45 var repeatedTexture = store.Get(@"sample-texture", WrapMode.Repeat, WrapMode.Repeat); 46 var edgeClampedTexture = store.Get(@"sample-texture", WrapMode.ClampToEdge, WrapMode.ClampToEdge); 47 var borderClampedTexture = store.Get(@"sample-texture", WrapMode.ClampToBorder, WrapMode.ClampToBorder); 48 49 AddStep("add sprites", () => addMoreDrawables(texture, new RectangleF(0, 0, 1, 1))); 50 AddStep("add sprites with shrink", () => addMoreDrawables(texture, new RectangleF(0.25f, 0.25f, 0.5f, 0.5f))); 51 AddStep("add sprites with repeat", () => addMoreDrawables(repeatedTexture, new RectangleF(0.25f, 0.25f, 0.5f, 0.5f))); 52 AddStep("add sprites with edge clamp", () => addMoreDrawables(edgeClampedTexture, new RectangleF(0.25f, 0.25f, 0.5f, 0.5f))); 53 AddStep("add sprites with border clamp", () => addMoreDrawables(borderClampedTexture, new RectangleF(0.25f, 0.25f, 0.5f, 0.5f))); 54 AddStep("add boxes", () => addMoreDrawables(Texture.WhitePixel, new RectangleF(0, 0, 1, 1))); 55 AddToggleStep("disable front to back", val => 56 { 57 debugConfig.SetValue(DebugSetting.BypassFrontToBackPass, val); 58 Invalidate(Invalidation.DrawNode); // reset counts 59 }); 60 61 Add(new Container 62 { 63 AutoSizeAxes = Axes.Both, 64 Depth = float.NegativeInfinity, 65 Anchor = Anchor.Centre, 66 Origin = Anchor.Centre, 67 68 Children = new Drawable[] 69 { 70 new Box 71 { 72 Colour = Color4.Black, 73 RelativeSizeAxes = Axes.Both, 74 Alpha = 0.8f, 75 }, 76 new FillFlowContainer 77 { 78 AutoSizeAxes = Axes.Both, 79 Padding = new MarginPadding(10), 80 Direction = FillDirection.Vertical, 81 Children = new Drawable[] 82 { 83 labelDrawables = new SpriteText { Font = FrameworkFont.Condensed }, 84 labelFrag = new SpriteText { Font = FrameworkFont.Condensed }, 85 labelFrag2 = new SpriteText { Font = FrameworkFont.Condensed }, 86 } 87 }, 88 } 89 }); 90 } 91 92 protected override void Update() 93 { 94 base.Update(); 95 96 if (drawNode != null) 97 { 98 labelDrawables.Text = $"boxes: {Cell(1).Children.Count * cell_count:N0}"; 99 labelFrag.Text = $"samples ({nameof(DrawNode.Draw)}): {drawNode.DrawSamples:N0}"; 100 labelFrag2.Text = $"samples ({nameof(DrawNode.DrawOpaqueInteriorSubTree)}): {drawNode.DrawOpaqueInteriorSubTreeSamples:N0}"; 101 } 102 } 103 104 private void addMoreDrawables(Texture texture, RectangleF textureRect) 105 { 106 for (int i = 0; i < 100; i++) 107 { 108 Cell(i % cell_count).Add(new Sprite 109 { 110 Anchor = Anchor.Centre, 111 Origin = Anchor.Centre, 112 Colour = new Color4(RNG.NextSingle(1), RNG.NextSingle(1), RNG.NextSingle(1), 1), 113 RelativeSizeAxes = Axes.Both, 114 Scale = new Vector2(currentScale), 115 Texture = texture, 116 TextureRectangle = textureRect, 117 }); 118 119 currentScale -= 0.001f; 120 if (currentScale < 0) 121 currentScale = 1; 122 } 123 } 124 125 private class QueryingCompositeDrawableDrawNode : CompositeDrawableDrawNode 126 { 127 private int queryObject = -1; 128 129 public int DrawSamples { get; private set; } 130 public int DrawOpaqueInteriorSubTreeSamples { get; private set; } 131 132 public QueryingCompositeDrawableDrawNode(CompositeDrawable source) 133 : base(source) 134 { 135 } 136 137 internal override void DrawOpaqueInteriorSubTree(DepthValue depthValue, Action<TexturedVertex2D> vertexAction) 138 { 139 startQuery(); 140 base.DrawOpaqueInteriorSubTree(depthValue, vertexAction); 141 DrawOpaqueInteriorSubTreeSamples = endQuery(); 142 } 143 144 public override void ApplyState() 145 { 146 DrawSamples = 0; 147 DrawOpaqueInteriorSubTreeSamples = 0; 148 base.ApplyState(); 149 } 150 151 public override void Draw(Action<TexturedVertex2D> vertexAction) 152 { 153 startQuery(); 154 base.Draw(vertexAction); 155 DrawSamples = endQuery(); 156 } 157 158 private int endQuery() 159 { 160 GL.EndQuery(QueryTarget.SamplesPassed); 161 GL.GetQueryObject(queryObject, GetQueryObjectParam.QueryResult, out int result); 162 163 return result; 164 } 165 166 private void startQuery() 167 { 168 if (queryObject == -1) 169 queryObject = GL.GenQuery(); 170 171 GL.BeginQuery(QueryTarget.SamplesPassed, queryObject); 172 } 173 } 174 } 175}