/// <summary> /// Utility routine for detecting fields and properties which value is bound to a shader program uniform /// state. /// </summary> /// <param name="shaderUniformStateType"> /// The <see cref="Type"/> that is defining the fields and properties to be linked with the uniform state. /// </param> /// <returns> /// It returns a <see cref="Dictionary{String, UniformStateMember}"/> that associate uniform variable names with /// the relative <see cref="UniformStateMember"/>, which define access to backing properties for getting uniform /// variable values. /// </returns> protected static Dictionary <string, UniformStateMember> DetectUniformProperties(Type shaderUniformStateType) { if (shaderUniformStateType == null) { throw new ArgumentNullException("shaderUniformStateType"); } Dictionary <string, UniformStateMember> uniformMembers = new Dictionary <string, UniformStateMember>(); // Fields FieldInfo[] uniformFields = shaderUniformStateType.GetFields(BindingFlags.Public | BindingFlags.Instance); foreach (FieldInfo uniformField in uniformFields) { ShaderUniformStateAttribute attribute = (ShaderUniformStateAttribute)Attribute.GetCustomAttribute(uniformField, typeof(ShaderUniformStateAttribute)); if (attribute == null) { continue; } uniformMembers.Add("hal_" + uniformField.Name, new UniformStateMember(uniformField, GetFieldUniformValue)); } // Properties PropertyInfo[] uniformProperties = shaderUniformStateType.GetProperties(BindingFlags.Public | BindingFlags.Instance); foreach (PropertyInfo uniformProperty in uniformProperties) { if (uniformProperty.CanRead == false) { continue; } if (uniformProperty.GetIndexParameters().Length > 0) { continue; } ShaderUniformStateAttribute attribute = (ShaderUniformStateAttribute)Attribute.GetCustomAttribute(uniformProperty, typeof(ShaderUniformStateAttribute)); if (attribute == null) { continue; } uniformMembers.Add("hal_" + uniformProperty.Name, new UniformStateMember(uniformProperty, GetPropertyUniformValue)); } return(uniformMembers); }
private static void CheckUniformType(Type uniformType) { if (uniformType == null) { throw new ArgumentNullException("uniformType"); } if (uniformType.IsAbstract) { return; } if (uniformType.IsArray) { uniformType = uniformType.GetElementType(); } ShaderUniformStateAttribute typeAttribute = (ShaderUniformStateAttribute)Attribute.GetCustomAttribute(uniformType, typeof(ShaderUniformStateAttribute)); if (typeAttribute != null) { DetectTypeUniformProperties(uniformType); } }
private static void DetectTypeUniformProperties(Type shaderUniformStateType) { if (shaderUniformStateType == null) { throw new ArgumentNullException("shaderUniformStateType"); } if (_TypeUniformState.ContainsKey(shaderUniformStateType)) { return; } List <UniformStateMember> typeMembers = new List <UniformStateMember>(); // Fields FieldInfo[] uniformFields = shaderUniformStateType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); foreach (FieldInfo uniformField in uniformFields) { ShaderUniformStateAttribute attribute = (ShaderUniformStateAttribute)Attribute.GetCustomAttribute(uniformField, typeof(ShaderUniformStateAttribute)); if (attribute == null) { continue; } // If the uniform name is unspecified, it's implictly defined with the "glo_" 'namespace' string uniformName = attribute.UniformName != null ? attribute.UniformName : "glo_" + uniformField.Name; typeMembers.Add(new UniformStateMember(uniformName, uniformField, GetFieldUniformValue)); // Recurse on uniform type CheckUniformType(uniformField.FieldType); } // Properties PropertyInfo[] uniformProperties = shaderUniformStateType.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); foreach (PropertyInfo uniformProperty in uniformProperties) { if (uniformProperty.CanRead == false) { continue; } if (uniformProperty.GetIndexParameters().Length > 0) { continue; } ShaderUniformStateAttribute attribute = (ShaderUniformStateAttribute)Attribute.GetCustomAttribute(uniformProperty, typeof(ShaderUniformStateAttribute)); if (attribute == null) { continue; } // If the uniform name is unspecified, it's implictly defined with the "glo_" 'namespace' string uniformName = attribute.UniformName != null ? attribute.UniformName : "glo_" + uniformProperty.Name; typeMembers.Add(new UniformStateMember(uniformName, uniformProperty, GetPropertyUniformValue)); // Recurse on uniform type CheckUniformType(uniformProperty.PropertyType); } // Nested types (and because this it's not possible to support public ShaderUniformStateAttribute) foreach (Type nestedType in shaderUniformStateType.GetNestedTypes(BindingFlags.Public)) { CheckUniformType(nestedType); } _TypeUniformState.Add(shaderUniformStateType, typeMembers); }