/// <summary> /// Set a single uniform, optionally structured. /// </summary> /// <param name="ctx"> /// A <see cref="GraphicsContext"/> used to share common state between shaders. /// </param> /// <param name="uniformContainer"> /// A <see cref="IShaderUniformContainer"/> that specify this uniform state. /// </param> /// <param name="uniformPattern"></param> /// <param name="uniformValue"></param> private void ApplyUniform(GraphicsContext ctx, IShaderUniformContainer uniformContainer, string uniformPattern, object uniformValue) { List <UniformStateMember> structuredTypeMembers; if (_TypeUniformState.TryGetValue(uniformValue.GetType(), out structuredTypeMembers)) { // Recurse over structure fields ApplyState(ctx, uniformContainer, uniformPattern, structuredTypeMembers, uniformValue); } else { uniformContainer.SetUniform(ctx, uniformPattern, uniformValue); } }
/// <summary> /// Apply this state to a shader program. /// </summary> /// <param name="ctx"> /// A <see cref="GraphicsContext"/> used to share common state between shaders. /// </param> /// <param name="uniformContainer"> /// A <see cref="IShaderUniformContainer"/> that specify this uniform state. /// </param> /// <param name="uniformScope"> /// A <see cref="String"/> that specify the scope the uniform variable. /// </param> private void ApplyState(GraphicsContext ctx, IShaderUniformContainer uniformContainer, string uniformScope, IEnumerable <UniformStateMember> uniforms, object instance) { if (uniformContainer == null) { throw new ArgumentNullException("shaderProgram"); } if (uniforms == null) { throw new ArgumentNullException("uniforms"); } if (instance == null) { throw new ArgumentNullException("instance"); } foreach (UniformStateMember uniform in uniforms) { // Set the program uniform string uniformPattern = uniformScope != null?String.Format("{0}.{1}", uniformScope, uniform.UniformName) : uniform.UniformName; // Matches also partial uniform variables (i.e. glo_Struct[0] or glo_Struct while glo_Struct[0].Member is active) // Indeed quite efficient when structures are not active (skip all members) if (uniformContainer.IsActiveUniform(uniformPattern) == false) { continue; } object uniformValue = uniform.GetUniformValue(instance); // Silently skip null references if (uniformValue == null) { continue; } Type uniformValueType = uniformValue.GetType(); if (uniformValueType.IsArray) { Array uniformArray = (Array)uniformValue; for (int i = 0; i < uniformArray.Length; i++) { string uniformArrayPattern = String.Format("{0}[{1}]", uniformPattern, i); if (uniformContainer.IsActiveUniform(uniformArrayPattern) == false) { continue; } object uniformArrayValue = uniformArray.GetValue(i); // Silently skip null references if (uniformArrayValue == null) { continue; } ApplyUniform(ctx, uniformContainer, uniformArrayPattern, uniformArrayValue); } } else { ApplyUniform(ctx, uniformContainer, uniformPattern, uniformValue); } } }