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));
        }
Example #2
0
        /// <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);
            }
        }
Example #6
0
        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);
            }
        }
Example #7
0
 protected virtual void CloneCore(EffectParameterBinding source)
 {
     Description = source.Description;
 }