A game framework written with osu! in mind.
at master 104 lines 3.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 System.Collections.Generic; 6using osu.Framework.Graphics.Colour; 7using osu.Framework.Graphics.OpenGL.Vertices; 8using osu.Framework.Graphics.Primitives; 9using osu.Framework.Graphics.Textures; 10using osuTK; 11using osuTK.Graphics; 12 13namespace osu.Framework.Graphics.Sprites 14{ 15 public partial class SpriteText 16 { 17 internal class SpriteTextDrawNode : TexturedShaderDrawNode 18 { 19 protected new SpriteText Source => (SpriteText)base.Source; 20 21 private bool shadow; 22 private ColourInfo shadowColour; 23 private Vector2 shadowOffset; 24 25 private readonly List<ScreenSpaceCharacterPart> parts = new List<ScreenSpaceCharacterPart>(); 26 27 public SpriteTextDrawNode(SpriteText source) 28 : base(source) 29 { 30 } 31 32 public override void ApplyState() 33 { 34 base.ApplyState(); 35 36 parts.Clear(); 37 parts.AddRange(Source.screenSpaceCharacters); 38 shadow = Source.Shadow; 39 40 if (shadow) 41 { 42 shadowColour = Source.ShadowColour; 43 shadowOffset = Source.premultipliedShadowOffset; 44 } 45 } 46 47 public override void Draw(Action<TexturedVertex2D> vertexAction) 48 { 49 base.Draw(vertexAction); 50 51 Shader.Bind(); 52 53 var avgColour = (Color4)DrawColourInfo.Colour.AverageColour; 54 float shadowAlpha = MathF.Pow(Math.Max(Math.Max(avgColour.R, avgColour.G), avgColour.B), 2); 55 56 //adjust shadow alpha based on highest component intensity to avoid muddy display of darker text. 57 //squared result for quadratic fall-off seems to give the best result. 58 var finalShadowColour = DrawColourInfo.Colour; 59 finalShadowColour.ApplyChild(shadowColour.MultiplyAlpha(shadowAlpha)); 60 61 for (int i = 0; i < parts.Count; i++) 62 { 63 if (shadow) 64 { 65 var shadowQuad = parts[i].DrawQuad; 66 67 DrawQuad(parts[i].Texture, 68 new Quad( 69 shadowQuad.TopLeft + shadowOffset, 70 shadowQuad.TopRight + shadowOffset, 71 shadowQuad.BottomLeft + shadowOffset, 72 shadowQuad.BottomRight + shadowOffset), 73 finalShadowColour, vertexAction: vertexAction, inflationPercentage: parts[i].InflationPercentage); 74 } 75 76 DrawQuad(parts[i].Texture, parts[i].DrawQuad, DrawColourInfo.Colour, vertexAction: vertexAction, inflationPercentage: parts[i].InflationPercentage); 77 } 78 79 Shader.Unbind(); 80 } 81 } 82 83 /// <summary> 84 /// A character of a <see cref="SpriteText"/> provided with screen space draw coordinates. 85 /// </summary> 86 internal struct ScreenSpaceCharacterPart 87 { 88 /// <summary> 89 /// The screen-space quad for the character to be drawn in. 90 /// </summary> 91 public Quad DrawQuad; 92 93 /// <summary> 94 /// Extra padding for the character's texture. 95 /// </summary> 96 public Vector2 InflationPercentage; 97 98 /// <summary> 99 /// The texture to draw the character with. 100 /// </summary> 101 public Texture Texture; 102 } 103 } 104}