A game framework written with osu! in mind.
at master 88 lines 4.3 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 System.Linq; 7using osuTK; 8 9namespace osu.Framework.Graphics.Shaders 10{ 11 internal static class GlobalPropertyManager 12 { 13 private static readonly HashSet<Shader> all_shaders = new HashSet<Shader>(); 14 private static readonly IUniformMapping[] global_properties; 15 16 static GlobalPropertyManager() 17 { 18 var values = Enum.GetValues(typeof(GlobalProperty)).OfType<GlobalProperty>().ToArray(); 19 20 global_properties = new IUniformMapping[values.Length]; 21 22 global_properties[(int)GlobalProperty.ProjMatrix] = new UniformMapping<Matrix4>("g_ProjMatrix"); 23 global_properties[(int)GlobalProperty.MaskingRect] = new UniformMapping<Vector4>("g_MaskingRect"); 24 global_properties[(int)GlobalProperty.ToMaskingSpace] = new UniformMapping<Matrix3>("g_ToMaskingSpace"); 25 global_properties[(int)GlobalProperty.CornerRadius] = new UniformMapping<float>("g_CornerRadius"); 26 global_properties[(int)GlobalProperty.CornerExponent] = new UniformMapping<float>("g_CornerExponent"); 27 global_properties[(int)GlobalProperty.BorderThickness] = new UniformMapping<float>("g_BorderThickness"); 28 global_properties[(int)GlobalProperty.BorderColour] = new UniformMapping<Vector4>("g_BorderColour"); 29 global_properties[(int)GlobalProperty.MaskingBlendRange] = new UniformMapping<float>("g_MaskingBlendRange"); 30 global_properties[(int)GlobalProperty.AlphaExponent] = new UniformMapping<float>("g_AlphaExponent"); 31 global_properties[(int)GlobalProperty.EdgeOffset] = new UniformMapping<Vector2>("g_EdgeOffset"); 32 global_properties[(int)GlobalProperty.DiscardInner] = new UniformMapping<bool>("g_DiscardInner"); 33 global_properties[(int)GlobalProperty.InnerCornerRadius] = new UniformMapping<float>("g_InnerCornerRadius"); 34 global_properties[(int)GlobalProperty.GammaCorrection] = new UniformMapping<bool>("g_GammaCorrection"); 35 global_properties[(int)GlobalProperty.WrapModeS] = new UniformMapping<int>("g_WrapModeS"); 36 global_properties[(int)GlobalProperty.WrapModeT] = new UniformMapping<int>("g_WrapModeT"); 37 38 // Backbuffer internals 39 global_properties[(int)GlobalProperty.BackbufferDraw] = new UniformMapping<bool>("g_BackbufferDraw"); 40 } 41 42 /// <summary> 43 /// Sets a uniform for all shaders that contain this property. 44 /// <para>Any future-initialized shaders will also have this uniform set.</para> 45 /// </summary> 46 /// <param name="property">The uniform.</param> 47 /// <param name="value">The uniform value.</param> 48 public static void Set<T>(GlobalProperty property, T value) 49 where T : struct, IEquatable<T> 50 { 51 ((UniformMapping<T>)global_properties[(int)property]).UpdateValue(ref value); 52 } 53 54 public static void Register(Shader shader) 55 { 56 if (!all_shaders.Add(shader)) return; 57 58 // transfer all existing global properties across. 59 foreach (var global in global_properties) 60 { 61 if (!shader.Uniforms.TryGetValue(global.Name, out IUniform uniform)) 62 continue; 63 64 global.LinkShaderUniform(uniform); 65 } 66 } 67 68 public static void Unregister(Shader shader) 69 { 70 if (!all_shaders.Remove(shader)) return; 71 72 foreach (var global in global_properties) 73 { 74 if (!shader.Uniforms.TryGetValue(global.Name, out IUniform uniform)) 75 continue; 76 77 global.UnlinkShaderUniform(uniform); 78 } 79 } 80 81 /// <summary> 82 /// Check whether a global uniform exists with the specified name. 83 /// </summary> 84 /// <param name="name">The name to check</param> 85 /// <returns>Whether a global exists.</returns> 86 public static bool CheckGlobalExists(string name) => global_properties.Any(m => m.Name == name); 87 } 88}