private static string GetEffectParameterInfo(EffectParameterDescription description) { var parameter = description.Parameter; return(string.Format( CultureInfo.InvariantCulture, "EffectParameter (XNA):\n" + " Name = {0}\n" + " Semantic = {1}\n" + " ParameterClass = {2}\n" + " ParameterType = {3}\n" + " RowCount = {4}\n" + " ColumnCount = {5}\n" + " Elements.Count = {6}\n" + "\n" + "EffectParameterDescription (DigitalRune Graphics):\n" + " Semantic = {7}\n" + " Index = {8}\n" + " Hint = {9}", parameter.Name, parameter.Semantic, parameter.ParameterClass, parameter.ParameterType, parameter.RowCount, parameter.ColumnCount, parameter.Elements.Count, description.Semantic, description.Index, description.Hint)); }
/// <summary> /// Initializes a new instance of the <see cref="EffectParameterBinding"/> class. /// </summary> /// <param name="effect">The effect.</param> /// <param name="parameter">The effect parameter.</param> /// <exception cref="ArgumentNullException"> /// <paramref name="effect"/> or <paramref name="parameter"/> is <see langword="null"/>. /// </exception> protected EffectParameterBinding(Effect effect, EffectParameter parameter) { if (effect == null) { throw new ArgumentNullException("effect"); } if (parameter == null) { throw new ArgumentNullException("parameter"); } try { Description = effect.GetParameterDescriptions()[parameter]; } catch (KeyNotFoundException) { throw new GraphicsException("Missing effect parameter description.\n\n" + "Cause:\nThis can happen if an effect parameter uses a struct type, " + "and the parameter name or semantic is known by an effect interpreter, but " + "no binding is provided by any effect binder.\n\n" + "Solution:\nAn effect binder must create a binding for this parameter."); } if ((GlobalSettings.ValidationLevelInternal & GlobalSettings.ValidationLevelDevBasic) != 0) { VerifyEffectParameter(effect); } }
/// <inheritdoc/> public virtual EffectParameterDescription GetDescription(Effect effect, EffectParameter parameter) { if (parameter == null) { throw new ArgumentNullException("parameter"); } EffectParameterDescription description = null; // First, try to get usage from annotation string. #if !MONOGAME var annotation = parameter.Annotations["Semantic"]; if (annotation != null && annotation.ParameterType == EffectParameterType.String) { description = GetDescriptionFromString(parameter, annotation.GetValueString()); } #endif if (description == null) { // No annotation. // --> Try to get usage from semantic. description = GetDescriptionFromString(parameter, parameter.Semantic); } if (description == null) { // No annotation, no semantic. // --> Try to get usage from parameter name. // Check whether string matches entry in dictionary. description = GetDescriptionFromString(parameter, parameter.Name); } if (description == null) { // Too bad, better luck next time. return(null); } // Get the effect parameter hint from annotations. var hint = EffectHelper.GetHintFromAnnotations(parameter); if (hint.HasValue) { // User-defined hint found in effect file. // --> Override default. description.Hint = hint.Value; } return(description); }
internal static void ThrowIfNotArray(Effect effect, EffectParameterDescription description) { if (description.Parameter.Elements.Count == 0) { string message = string.Format( CultureInfo.InvariantCulture, "Effect parameter \"{0}\" is not an array of elements. " + "Use EffectParameterBinding<T> instead of EffectParameterArrayBinding<T>!\n\n{1}", description.Parameter.Name, GetEffectParameterInfo(description)); throw new EffectBindingException(message, effect, description.Parameter); } }
/// <summary> /// Throws the type of if invalid. /// </summary> /// <typeparam name="T">The value type of the effect parameter binding.</typeparam> /// <param name="effect">The effect.</param> /// <param name="description">The effect parameter description.</param> /// <param name="validateType">Type of the validate.</param> /// <param name="numberOfElements">The number of elements.</param> /// <exception cref="DigitalRune.Graphics.Effects.EffectBindingException"> /// </exception> internal static void ThrowIfInvalidType <T>(Effect effect, EffectParameterDescription description, Func <EffectParameter, bool> validateType, int numberOfElements) { var parameter = description.Parameter; if (!validateType(parameter)) { var message = new StringBuilder(); message.AppendFormat( CultureInfo.InvariantCulture, "Binding for effect parameter \"{0}\" has wrong type.\n" + "Type of effect parameter binding: {1}", parameter.Name, typeof(T).Name); string allowedTypes = GetEffectParameterType(parameter); if (allowedTypes != null) { message.AppendLine(); message.AppendFormat( CultureInfo.InvariantCulture, "Allowed types: {0}\n\n", allowedTypes); } string parameterInfo = GetEffectParameterInfo(description); message.Append(parameterInfo); throw new EffectBindingException(message.ToString(), effect, parameter); } // Smaller arrays are ok, for example: Setting 58 skinning matrices out of max 72. // Bigger arrays are not allowed. if (numberOfElements > parameter.Elements.Count) { string message = String.Format( CultureInfo.InvariantCulture, "Length of the array ({0}) is greater than the number of elements of the effect parameter \"{1}\".\n\n{2}", numberOfElements, parameter.Name, GetEffectParameterInfo(description)); throw new EffectBindingException(message, effect, parameter); } }
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); } }
protected virtual void CloneCore(EffectParameterBinding source) { Description = source.Description; }