/// <summary> /// Sets a <see cref="ConstParameterArrayBinding{T}"/> for the specified effect parameter. /// </summary> /// <typeparam name="T"> /// The value type. See <see cref="EffectParameterArrayBinding{T}"/>. /// </typeparam> /// <param name="parameter"> /// The effect parameter to which the binding is applied. /// </param> /// <param name="values">The array of values.</param> /// <returns>The <see cref="ConstParameterArrayBinding{T}"/> that has been set.</returns> /// <remarks> /// If an appropriate effect parameter binding for <paramref name="parameter"/> already exists, /// then the existing binding is updated. /// </remarks> /// <exception cref="ArgumentNullException"> /// <paramref name="parameter"/> is <see langword="null"/>. /// </exception> /// <exception cref="EffectBindingException"> /// The value type <typeparamref name="T"/> is not supported. /// </exception> public ConstParameterArrayBinding <T> Set <T>(EffectParameter parameter, T[] values) { ConstParameterArrayBinding <T> binding; int index = ParameterBindings.IndexOf(parameter); if (index >= 0) { // An effect parameter binding already exists. binding = ParameterBindings[index] as ConstParameterArrayBinding <T>; if (binding != null) { // Update existing binding. binding.Values = values; } else { // Replace existing binding. binding = new ConstParameterArrayBinding <T>(Effect, parameter, values); ParameterBindings[index] = binding; } } else { // Create a new binding. binding = new ConstParameterArrayBinding <T>(Effect, parameter, values); CheckHint(binding); ParameterBindings.Add(binding); } return(binding); }
private static void SetDefaultBinding(IGraphicsService graphicsService, EffectEx effectEx, EffectParameter parameter, EffectParameterDescription usage, EffectParameterBindingCollection bindings) { Debug.Assert(!bindings.Contains(parameter), "Effect binding already contains a binding for the given effect parameter."); if (parameter.ParameterClass == EffectParameterClass.Struct) { if (parameter.Elements.Count > 0) { // ----- Effect parameter is an array of structs. --> Recursively process elements of array. foreach (EffectParameter element in parameter.Elements) SetDefaultBinding(graphicsService, effectEx, element, usage, bindings); } else { // ----- Effect parameter is a struct. --> Recursively process members of struct. foreach (EffectParameter member in parameter.StructureMembers) SetDefaultBinding(graphicsService, effectEx, member, usage, bindings); } return; } // Set ConstParameterBinding using the default value stored in .fx file. var effect = effectEx.Resource; object originalValue; effectEx.OriginalParameterValues.TryGetValue(parameter, out originalValue); EffectParameterBinding binding = null; if (parameter.Elements.Count == 0) { // ----- Parameter is not an array. if (parameter.ParameterClass == EffectParameterClass.Scalar) { // Scalar values. if (parameter.ParameterType == EffectParameterType.Bool) binding = new ConstParameterBinding<bool>(effect, parameter, (bool)originalValue); else if (parameter.ParameterType == EffectParameterType.Int32) binding = new ConstParameterBinding<int>(effect, parameter, (int)originalValue); else if (parameter.ParameterType == EffectParameterType.Single) binding = new ConstParameterBinding<float>(effect, parameter, (float)originalValue); } else if (parameter.ParameterClass == EffectParameterClass.Vector && parameter.ParameterType == EffectParameterType.Single) { // Vector values. if (parameter.ColumnCount == 2 || parameter.RowCount == 2) binding = new ConstParameterBinding<Vector2>(effect, parameter, (Vector2)originalValue); else if (parameter.ColumnCount == 3 || parameter.RowCount == 3) binding = new ConstParameterBinding<Vector3>(effect, parameter, (Vector3)originalValue); else if (parameter.ColumnCount == 4 || parameter.RowCount == 4) binding = new ConstParameterBinding<Vector4>(effect, parameter, (Vector4)originalValue); } else if (parameter.ParameterClass == EffectParameterClass.Matrix && parameter.ParameterType == EffectParameterType.Single) { // Matrix value. binding = new ConstParameterBinding<Matrix>(effect, parameter, (Matrix)originalValue); } else if (parameter.ParameterClass == EffectParameterClass.Object) { // Object values. if (parameter.ParameterType == EffectParameterType.String) { binding = new ConstParameterBinding<string>(effect, parameter, (string)originalValue); } else if (parameter.ParameterType == EffectParameterType.Texture) { // A texture type but we are not sure which exact type. --> Try different types. try { binding = new ConstParameterBinding<Texture2D>(effect, parameter, graphicsService.GetDefaultTexture2DWhite()); } catch (Exception) { try { binding = new ConstParameterBinding<Texture3D>(effect, parameter, graphicsService.GetDefaultTexture3DWhite()); } catch (Exception) { try { binding = new ConstParameterBinding<TextureCube>(effect, parameter, graphicsService.GetDefaultTextureCubeWhite()); } catch (Exception) { // Default value for a parameter of type Texture could not be read from Effect. } } } } else if (parameter.ParameterType == EffectParameterType.Texture1D) { // NOTE: 1D textures are not supported in XNA. } else if (parameter.ParameterType == EffectParameterType.Texture2D) { binding = new ConstParameterBinding<Texture2D>(effect, parameter, graphicsService.GetDefaultTexture2DWhite()); } else if (parameter.ParameterType == EffectParameterType.Texture3D) { binding = new ConstParameterBinding<Texture3D>(effect, parameter, graphicsService.GetDefaultTexture3DWhite()); } else if (parameter.ParameterType == EffectParameterType.TextureCube) { binding = new ConstParameterBinding<TextureCube>(effect, parameter, graphicsService.GetDefaultTextureCubeWhite()); } } } else { // ----- Parameter is array. int length = parameter.Elements.Count; Debug.Assert(length > 0, "Effect parameter should be an array."); // Note: In XNA originalValue is valid. In MonoGame originalValue is null and we have to // create a new array! if (parameter.ParameterClass == EffectParameterClass.Scalar) { // Scalar value bindings. if (parameter.ParameterType == EffectParameterType.Bool) binding = new ConstParameterArrayBinding<bool>(effect, parameter, (bool[])originalValue ?? new bool[parameter.Elements.Count]); else if (parameter.ParameterType == EffectParameterType.Int32) binding = new ConstParameterArrayBinding<int>(effect, parameter, (int[])originalValue ?? new int[parameter.Elements.Count]); else if (parameter.ParameterType == EffectParameterType.Single) binding = new ConstParameterArrayBinding<float>(effect, parameter, (float[])originalValue ?? new float[parameter.Elements.Count]); } else if (parameter.ParameterClass == EffectParameterClass.Vector && parameter.ParameterType == EffectParameterType.Single) { if (parameter.ColumnCount == 2 || parameter.RowCount == 2) binding = new ConstParameterArrayBinding<Vector2>(effect, parameter, (Vector2[])originalValue ?? new Vector2[parameter.Elements.Count]); else if (parameter.ColumnCount == 3 || parameter.RowCount == 3) binding = new ConstParameterArrayBinding<Vector3>(effect, parameter, (Vector3[])originalValue ?? new Vector3[parameter.Elements.Count]); else if (parameter.ColumnCount == 4 || parameter.RowCount == 4) binding = new ConstParameterArrayBinding<Vector4>(effect, parameter, (Vector4[])originalValue ?? new Vector4[parameter.Elements.Count]); } else if (parameter.ParameterClass == EffectParameterClass.Matrix && parameter.ParameterType == EffectParameterType.Single) { binding = new ConstParameterArrayBinding<Matrix>(effect, parameter, (Matrix[])originalValue ?? new Matrix[parameter.Elements.Count]); } else if (parameter.ParameterClass == EffectParameterClass.Object) { // Note: Arrays of strings or textures are not supported in XNA. } } if (binding != null) bindings.Add(binding); }
private static bool SetOpaqueDataBinding(Effect effect, EffectParameter parameter, IDictionary<string, object> opaqueData, EffectParameterBindingCollection bindings) { Debug.Assert(!bindings.Contains(parameter), "Effect binding already contains a binding for the given effect parameter."); if (opaqueData == null || opaqueData.Count == 0) { // No opaque data. return false; } if (parameter.ParameterClass == EffectParameterClass.Struct) { // Structs cannot be set from opaque data. return false; } // Get value from opaque data. object value; bool valueFound = opaqueData.TryGetValue(parameter.Name, out value); if (!valueFound) return false; EffectParameterBinding binding = null; if (parameter.Elements.Count == 0) { // ----- Parameter is not an array. if (parameter.ParameterClass == EffectParameterClass.Scalar) { // Scalar value bindings. if (parameter.ParameterType == EffectParameterType.Bool && ObjectHelper.IsConvertible(value)) binding = new ConstParameterBinding<bool>(effect, parameter, ObjectHelper.ConvertTo<bool>(value, CultureInfo.InvariantCulture)); else if (parameter.ParameterType == EffectParameterType.Int32 && ObjectHelper.IsConvertible(value)) binding = new ConstParameterBinding<int>(effect, parameter, ObjectHelper.ConvertTo<int>(value, CultureInfo.InvariantCulture)); else if (parameter.ParameterType == EffectParameterType.Single && ObjectHelper.IsConvertible(value)) binding = new ConstParameterBinding<float>(effect, parameter, ObjectHelper.ConvertTo<float>(value, CultureInfo.InvariantCulture)); } else if (parameter.ParameterClass == EffectParameterClass.Vector && parameter.ParameterType == EffectParameterType.Single) { if (parameter.ColumnCount == 2 || parameter.RowCount == 2) { if (value is Vector2) binding = new ConstParameterBinding<Vector2>(effect, parameter, (Vector2)value); else if (value is Vector2F) binding = new ConstParameterBinding<Vector2F>(effect, parameter, (Vector2F)value); } else if (parameter.ColumnCount == 3 || parameter.RowCount == 3) { if (value is Vector3) binding = new ConstParameterBinding<Vector3>(effect, parameter, (Vector3)value); else if (value is Vector3) binding = new ConstParameterBinding<Vector3>(effect, parameter, (Vector3)value); } else if (parameter.ColumnCount == 4 || parameter.RowCount == 4) { if (value is Vector4) binding = new ConstParameterBinding<Vector4>(effect, parameter, (Vector4)value); else if (value is Vector4) binding = new ConstParameterBinding<Vector4>(effect, parameter, (Vector4)value); } } else if (parameter.ParameterClass == EffectParameterClass.Matrix && parameter.ParameterType == EffectParameterType.Single) { if (parameter.ColumnCount == 2 && parameter.RowCount == 2) { if (value is Matrix22F) binding = new ConstParameterBinding<Matrix22F>(effect, parameter, (Matrix22F)value); } else if (parameter.ColumnCount == 3 && parameter.RowCount == 3) { if (value is Matrix) binding = new ConstParameterBinding<Matrix>(effect, parameter, (Matrix)value); } else if (parameter.ColumnCount == 4 || parameter.RowCount == 4) { if (value is Matrix) binding = new ConstParameterBinding<Matrix>(effect, parameter, (Matrix)value); else if (value is Matrix) binding = new ConstParameterBinding<Matrix>(effect, parameter, (Matrix)value); } } else if (parameter.ParameterClass == EffectParameterClass.Object) { if (parameter.ParameterType == EffectParameterType.String && value is string) binding = new ConstParameterBinding<string>(effect, parameter, (string)value); else if (parameter.ParameterType == EffectParameterType.Texture && value is Texture) binding = new ConstParameterBinding<Texture>(effect, parameter, (Texture)value); else if (parameter.ParameterType == EffectParameterType.Texture1D && value is Texture) binding = null; // 1D textures are not supported in XNA. else if (parameter.ParameterType == EffectParameterType.Texture2D && value is Texture2D) binding = new ConstParameterBinding<Texture2D>(effect, parameter, (Texture2D)value); else if (parameter.ParameterType == EffectParameterType.Texture3D && value is Texture3D) binding = new ConstParameterBinding<Texture3D>(effect, parameter, (Texture3D)value); else if (parameter.ParameterType == EffectParameterType.TextureCube && value is TextureCube) binding = new ConstParameterBinding<TextureCube>(effect, parameter, (TextureCube)value); } } else { // ----- Parameter is array. // TODO: We could also check whether the length of the arrays match. if (parameter.ParameterClass == EffectParameterClass.Scalar) { // Scalar value bindings. if (parameter.ParameterType == EffectParameterType.Bool && IsArray<bool>(value)) binding = new ConstParameterArrayBinding<bool>(effect, parameter, ToBooleanArray(value)); else if (parameter.ParameterType == EffectParameterType.Int32 && IsArray<int>(value)) binding = new ConstParameterArrayBinding<int>(effect, parameter, ToInt32Array(value)); else if (parameter.ParameterType == EffectParameterType.Single && IsArray<float>(value)) binding = new ConstParameterArrayBinding<float>(effect, parameter, ToSingleArray(value)); } else if (parameter.ParameterClass == EffectParameterClass.Vector && parameter.ParameterType == EffectParameterType.Single) { if (parameter.ColumnCount == 2 || parameter.RowCount == 2) { if (value is Vector2[]) binding = new ConstParameterArrayBinding<Vector2>(effect, parameter, (Vector2[])value); else if (value is Vector2F[]) binding = new ConstParameterArrayBinding<Vector2F>(effect, parameter, (Vector2F[])value); } else if (parameter.ColumnCount == 3 || parameter.RowCount == 3) { if (value is Vector3[]) binding = new ConstParameterArrayBinding<Vector3>(effect, parameter, (Vector3[])value); else if (value is Vector3[]) binding = new ConstParameterArrayBinding<Vector3>(effect, parameter, (Vector3[])value); } else if (parameter.ColumnCount == 4 || parameter.RowCount == 4) { if (value is Vector4[]) binding = new ConstParameterArrayBinding<Vector4>(effect, parameter, (Vector4[])value); else if (value is Vector4[]) binding = new ConstParameterArrayBinding<Vector4>(effect, parameter, (Vector4[])value); } } else if (parameter.ParameterClass == EffectParameterClass.Matrix && parameter.ParameterType == EffectParameterType.Single) { //#if !XBOX // The type Matrix22F[], Matrix[], Matrix[] caused a MissingMethodException at runtime on Xbox 360 in XNA 3.1. // See also: EffectParameterBinding<T>.SetValueMethods! if (parameter.ColumnCount == 2 && parameter.RowCount == 2) { if (value is Matrix22F[]) binding = new ConstParameterArrayBinding<Matrix22F>(effect, parameter, (Matrix22F[])value); } else if (parameter.ColumnCount == 3 && parameter.RowCount == 3) { if (value is Matrix[]) binding = new ConstParameterArrayBinding<Matrix>(effect, parameter, (Matrix[])value); } else //#endif if (parameter.ColumnCount == 4 || parameter.RowCount == 4) { if (value is Matrix[]) binding = new ConstParameterArrayBinding<Matrix>(effect, parameter, (Matrix[])value); //#if !XBOX else if (value is Matrix[]) binding = new ConstParameterArrayBinding<Matrix>(effect, parameter, (Matrix[])value); //#endif } } else if (parameter.ParameterClass == EffectParameterClass.Object) { if (parameter.ParameterType == EffectParameterType.String && value is string[]) binding = new ConstParameterArrayBinding<string>(effect, parameter, (string[])value); // Note: Arrays of textures are not supported in DirectX 9. } } if (binding != null) { bindings.Add(binding); return true; } return false; }