Exemple #1
0
        private static bool ShaderVarMatches(ref ShaderFieldInfo varInfo, VertexElementType type, int count)
        {
            //if (varInfo.Scope != ShaderFieldScope.Attribute) return false;

            Type elementPrimitive  = varInfo.Type.GetElementPrimitive();
            Type requiredPrimitive = null;

            switch (type)
            {
            case VertexElementType.Byte:
                requiredPrimitive = typeof(byte);
                break;

            case VertexElementType.Float:
                requiredPrimitive = typeof(float);
                break;
            }
            // ToDo: Bugfix to allow Color (byte to float) conversion
            if (elementPrimitive != requiredPrimitive && !(elementPrimitive == typeof(float) && requiredPrimitive == typeof(byte)))
            {
                return(false);
            }

            int elementCount = varInfo.Type.GetElementCount();

            if (count != elementCount * varInfo.ArrayLength)
            {
                return(false);
            }

            return(true);
        }
Exemple #2
0
        MergeResult PackFields(ShaderFieldInfo info, ref ShaderFieldInfo merged)
        {
            if (merged.elementCount % 4 == 0)
            {
                return(MergeResult.Full);
            }

            if (info.type != merged.type)
            {
                Error("can't merge '" + merged.DeclString() + "' and '" + info.DeclString() + "' into the same register because they have incompatible types.  Consider reordering the fields so that adjacent fields have the same primitive type.");
                return(MergeResult.Failed);  // incompatible types
            }

            if (info.cols > 1 || merged.cols > 1)
            {
                Error("merging matrix types not yet supported ('" + merged.DeclString() + "' and '" + info.DeclString() + "').  Consider reordering the fields to place matrix-typed variables on four-component vector boundaries.");
                return(MergeResult.Failed);  // don't merge matrix types
            }

            if (info.rows + merged.rows > 4)
            {
                // @TODO:  lift the restriction
                Error("can't merge '" + merged.DeclString() + "' and '" + info.DeclString() + "' because then " + info.name + " would cross register boundary.  Consider reordering the fields so that none of them cross four-component vector boundaries when packed.");
                return(MergeResult.Failed);  // out of space
            }

            merged.rows += info.rows;
            merged.name += "_" + info.name;
            return(MergeResult.Merged);
        }
Exemple #3
0
        private static bool ShaderVarMatches(ref ShaderFieldInfo varInfo, VertexElementType type, int count)
        {
            if (varInfo.Scope != ShaderFieldScope.Attribute)
            {
                return(false);
            }

            Type elementPrimitive  = varInfo.Type.GetElementPrimitive();
            Type requiredPrimitive = null;

            switch (type)
            {
            case VertexElementType.Byte:
                requiredPrimitive = typeof(byte);
                break;

            case VertexElementType.Float:
                requiredPrimitive = typeof(float);
                break;
            }
            if (elementPrimitive != requiredPrimitive)
            {
                return(false);
            }

            int elementCount = varInfo.Type.GetElementCount();

            if (count != elementCount * varInfo.ArrayLength)
            {
                return(false);
            }

            return(true);
        }
Exemple #4
0
            public object Clone()
            {
                ShaderFieldInfo info = new ShaderFieldInfo(type, name, rows, cols, comment);

                info.swizzleOffset = swizzleOffset;
                info.packed        = packed;
                info.accessor      = accessor;
                return(info);
            }
        /// <summary>
        /// Applies the specified parameter values to all currently active shaders.
        /// </summary>
        /// <param name="sharedParams"></param>
        /// <seealso cref="RetrieveActiveShaders"/>
        private void SetupSharedParameters(ShaderParameterCollection sharedParams)
        {
            this.sharedSamplerBindings = 0;
            this.sharedShaderParameters.Clear();
            if (sharedParams == null)
            {
                return;
            }

            foreach (NativeShaderProgram shader in this.activeShaders)
            {
                NativeShaderProgram.Bind(shader);

                ShaderFieldInfo[] varInfo   = shader.Fields;
                int[]             locations = shader.FieldLocations;

                // Setup shared sampler bindings and uniform data
                for (int i = 0; i < varInfo.Length; i++)
                {
                    ShaderFieldInfo field    = varInfo[i];
                    int             location = locations[i];

                    if (field.Scope == ShaderFieldScope.Attribute)
                    {
                        continue;
                    }
                    if (field.Type == ShaderFieldType.Sampler2D)
                    {
                        ContentRef <Texture> texRef;
                        if (!sharedParams.TryGetInternal(field.Name, out texRef))
                        {
                            continue;
                        }

                        NativeTexture.Bind(texRef, this.sharedSamplerBindings);
                        GL.Uniform1(location, this.sharedSamplerBindings);

                        this.sharedSamplerBindings++;
                    }
                    else
                    {
                        float[] data;
                        if (!sharedParams.TryGetInternal(field.Name, out data))
                        {
                            continue;
                        }

                        NativeShaderProgram.SetUniform(field, location, data);
                    }

                    this.sharedShaderParameters.Add(field.Name);
                }
            }

            NativeShaderProgram.Bind(null);
        }
Exemple #6
0
 private void PrepareEditorConfigData(ShaderFieldInfo field, List <EditorHintAttribute> configData)
 {
     if (field.Type != ShaderFieldType.Int)
     {
         configData.Add(new EditorHintIncrementAttribute(0.1f));
     }
     if (field.MinValue != float.MinValue || field.MaxValue != float.MaxValue)
     {
         configData.Add(new EditorHintRangeAttribute(
                            field.MinValue,
                            field.MaxValue));
     }
 }
Exemple #7
0
        protected PropertyEditor CreateTextureEditor(ShaderFieldInfo field)
        {
            PropertyEditor editor = null;

            editor        = this.ParentGrid.CreateEditor(typeof(ContentRef <Texture>), this);
            editor.Getter = this.CreateTextureValueGetter(field.Name);
            editor.Setter = !this.ReadOnly ? this.CreateTextureValueSetter(field.Name) : null;

            editor.PropertyName = field.Name;
            editor.PropertyDesc = field.Description;
            this.ParentGrid.ConfigureEditor(editor);
            return(editor);
        }
Exemple #8
0
        List <ShaderFieldInfo> Pack(List <ShaderFieldInfo> shaderFields)
        {
            List <ShaderFieldInfo> mergedFields = new List <ShaderFieldInfo>();

            using (var e = shaderFields.GetEnumerator())
            {
                if (!e.MoveNext())
                {
                    // Empty shader struct definition.
                    return(shaderFields);
                }

                ShaderFieldInfo current = e.Current.Clone() as ShaderFieldInfo;

                while (e.MoveNext())
                {
                    while (true)
                    {
                        int offset = current.elementCount;
                        var result = PackFields(e.Current, ref current);

                        if (result == MergeResult.Failed)
                        {
                            return(null);
                        }
                        else if (result == MergeResult.Full)
                        {
                            break;
                        }

                        // merge accessors
                        var acc = current.accessor;

                        acc.name                 = current.name;
                        e.Current.accessor       = acc;
                        e.Current.swizzleOffset += offset;

                        current.packed = e.Current.packed = true;

                        if (!e.MoveNext())
                        {
                            mergedFields.Add(current);
                            return(mergedFields);
                        }
                    }
                    mergedFields.Add(current);
                    current = e.Current.Clone() as ShaderFieldInfo;
                }
            }
            return(mergedFields);
        }
        public static void SetUniform(ShaderFieldInfo field, int location, float[] data)
        {
            if (field.Scope != ShaderFieldScope.Uniform)
            {
                return;
            }
            if (location == -1)
            {
                return;
            }
            switch (field.Type)
            {
            case ShaderFieldType.Bool:
            case ShaderFieldType.Int:
                int[] arrI = new int[field.ArrayLength];
                for (int j = 0; j < arrI.Length; j++)
                {
                    arrI[j] = (int)data[j];
                }
                GL.Uniform1(location, arrI.Length, arrI);
                break;

            case ShaderFieldType.Float:
                GL.Uniform1(location, data.Length, data);
                break;

            case ShaderFieldType.Vec2:
                GL.Uniform2(location, data.Length / 2, data);
                break;

            case ShaderFieldType.Vec3:
                GL.Uniform3(location, data.Length / 3, data);
                break;

            case ShaderFieldType.Vec4:
                GL.Uniform4(location, data.Length / 4, data);
                break;

            case ShaderFieldType.Mat2:
                GL.UniformMatrix2(location, data.Length / 4, false, data);
                break;

            case ShaderFieldType.Mat3:
                GL.UniformMatrix3(location, data.Length / 9, false, data);
                break;

            case ShaderFieldType.Mat4:
                GL.UniformMatrix4(location, data.Length / 16, false, data);
                break;
            }
        }
        public static void SetUniform(ref ShaderFieldInfo field, WebGLUniformLocation location, params float[] data)
        {
            if (field.Scope != ShaderFieldScope.Uniform)
            {
                return;
            }
            if (location == null)
            {
                return;
            }
            switch (field.Type)
            {
            case ShaderFieldType.Bool:
            case ShaderFieldType.Int:
                int[] arrI = new int[field.ArrayLength];
                for (int j = 0; j < arrI.Length; j++)
                {
                    arrI[j] = (int)data[j];
                }
                GraphicsBackend.GL.Uniform1iv(location, new Span <int>(arrI));
                break;

            case ShaderFieldType.Float:
                GraphicsBackend.GL.Uniform1fv(location, new Span <float>(data));
                break;

            case ShaderFieldType.Vec2:
                GraphicsBackend.GL.Uniform2fv(location, new Span <float>(data));
                break;

            case ShaderFieldType.Vec3:
                GraphicsBackend.GL.Uniform3fv(location, new Span <float>(data));
                break;

            case ShaderFieldType.Vec4:
                GraphicsBackend.GL.Uniform4fv(location, new Span <float>(data));
                break;

            case ShaderFieldType.Mat2:
                GraphicsBackend.GL.UniformMatrix2fv(location, false, new Span <float>(data));
                break;

            case ShaderFieldType.Mat3:
                GraphicsBackend.GL.UniformMatrix3fv(location, false, new Span <float>(data));
                break;

            case ShaderFieldType.Mat4:
                GraphicsBackend.GL.UniformMatrix4fv(location, false, new Span <float>(data));
                break;
            }
        }
Exemple #11
0
        protected override void OnUpdateFromObjects(object[] values)
        {
            base.OnUpdateFromObjects(values);

            if (values.Any(o => o != null))
            {
                IEnumerable <BatchInfo> batchInfos = values.Cast <BatchInfo>();
                DrawTechnique           refTech    = batchInfos.NotNull().First().Technique.Res;

                // Retrieve a list of shader variables to edit
                IReadOnlyList <ShaderFieldInfo> shaderFields = null;
                if (refTech != null)
                {
                    shaderFields = refTech.DeclaredFields;
                }
                else
                {
                    shaderFields = EmptyShaderFields;
                }

                // Remove editors that are no longer needed or no longer match their shader field
                List <string> removeEditors = null;
                foreach (var pair in this.fieldEditors)
                {
                    bool isMatchingEditor =
                        shaderFields.Contains(pair.Value.Field) &&
                        pair.Value.Field.Name == pair.Key;
                    if (!isMatchingEditor)
                    {
                        if (removeEditors == null)
                        {
                            removeEditors = new List <string>();
                        }
                        removeEditors.Add(pair.Key);
                    }
                }
                if (removeEditors != null)
                {
                    foreach (string fieldName in removeEditors)
                    {
                        this.RemovePropertyEditor(this.fieldEditors[fieldName].Editor);
                        this.fieldEditors.Remove(fieldName);
                    }
                }

                // Create editors for fields that do not yet have a matching editor, or which
                // were removed because they did no longer match.
                int autoCreateEditorCount = 1;
                int displayedFieldIndex   = -1;
                for (int i = 0; i < shaderFields.Count; i++)
                {
                    ShaderFieldInfo field = shaderFields[i];

                    // Skip fields that shouldn't be displayed
                    if (field.IsPrivate)
                    {
                        continue;
                    }
                    if (field.Scope != ShaderFieldScope.Uniform)
                    {
                        continue;
                    }

                    displayedFieldIndex++;

                    // Skip fields that already have a matching editor
                    if (this.fieldEditors.ContainsKey(field.Name))
                    {
                        continue;
                    }

                    // Create a new editor for this field
                    PropertyEditor editor;
                    if (field.Type == ShaderFieldType.Sampler2D)
                    {
                        editor = this.CreateTextureEditor(field);
                    }
                    else
                    {
                        editor = this.CreateUniformEditor(field);
                    }

                    // Add and register this editor
                    this.fieldEditors[field.Name] = new FieldEditorItem
                    {
                        Editor = editor,
                        Field  = field
                    };
                    if (autoCreateEditorCount + displayedFieldIndex <= this.ChildEditors.Count)
                    {
                        this.AddPropertyEditor(editor, autoCreateEditorCount + displayedFieldIndex);
                    }
                    else
                    {
                        this.AddPropertyEditor(editor);
                    }
                }
            }
        }
Exemple #12
0
        protected PropertyEditor CreateUniformEditor(ShaderFieldInfo field)
        {
            PropertyEditor editor            = null;
            bool           mainEditorIsArray = false;

            if (field.ArrayLength == 1)
            {
                if (field.EditorTypeTag == "ColorRgba")
                {
                    editor        = this.ParentGrid.CreateEditor(typeof(ColorRgba), this);
                    editor.Getter = this.CreateUniformValueGetter <ColorRgba>(field.Name);
                    editor.Setter = !this.ReadOnly ? this.CreateUniformValueSetter <ColorRgba>(field.Name) : null;
                }
                else if (field.EditorTypeTag == "ColorHsva")
                {
                    editor        = this.ParentGrid.CreateEditor(typeof(ColorHsva), this);
                    editor.Getter = this.CreateUniformValueGetter <ColorHsva>(field.Name);
                    editor.Setter = !this.ReadOnly ? this.CreateUniformValueSetter <ColorHsva>(field.Name) : null;
                }
                else if (field.Type == ShaderFieldType.Float || field.Type == ShaderFieldType.Int)
                {
                    Type editType = typeof(float);
                    if (field.Type == ShaderFieldType.Int)
                    {
                        editType = typeof(int);
                    }

                    editor = this.ParentGrid.CreateEditor(editType, this);
                    if (field.Type == ShaderFieldType.Int)
                    {
                        editor.Getter = this.CreateUniformValueGetter <int>(field.Name);
                        editor.Setter = !this.ReadOnly ? this.CreateUniformValueSetter <int>(field.Name) : null;
                    }
                    else
                    {
                        editor.Getter = this.CreateUniformValueGetter <float>(field.Name);
                        editor.Setter = !this.ReadOnly ? this.CreateUniformValueSetter <float>(field.Name) : null;
                    }
                }
                else if (field.Type == ShaderFieldType.Vec2)
                {
                    editor        = this.ParentGrid.CreateEditor(typeof(Vector2), this);
                    editor.Getter = this.CreateUniformValueGetter <Vector2>(field.Name);
                    editor.Setter = !this.ReadOnly ? this.CreateUniformValueSetter <Vector2>(field.Name) : null;
                }
                else if (field.Type == ShaderFieldType.Vec3)
                {
                    editor        = this.ParentGrid.CreateEditor(typeof(Vector3), this);
                    editor.Getter = this.CreateUniformValueGetter <Vector3>(field.Name);
                    editor.Setter = !this.ReadOnly ? this.CreateUniformValueSetter <Vector3>(field.Name) : null;
                }
                else if (field.Type == ShaderFieldType.Vec4)
                {
                    editor        = this.ParentGrid.CreateEditor(typeof(Vector4), this);
                    editor.Getter = this.CreateUniformValueGetter <Vector4>(field.Name);
                    editor.Setter = !this.ReadOnly ? this.CreateUniformValueSetter <Vector4>(field.Name) : null;
                }
                else
                {
                    editor            = this.ParentGrid.CreateEditor(typeof(float[]), this);
                    editor.Getter     = this.CreateUniformArrayValueGetter <float>(field.Name);
                    editor.Setter     = !this.ReadOnly ? this.CreateUniformArrayValueSetter <float>(field.Name) : null;
                    mainEditorIsArray = true;
                }
            }
            else
            {
                mainEditorIsArray = true;
                if (field.EditorTypeTag == "ColorRgba")
                {
                    editor                = this.ParentGrid.CreateEditor(typeof(ColorRgba[]), this);
                    editor.Getter         = this.CreateUniformArrayValueGetter <ColorRgba>(field.Name);
                    editor.Setter         = !this.ReadOnly ? this.CreateUniformArrayValueSetter <ColorRgba>(field.Name) : null;
                    editor.ForceWriteBack = true;
                }
                else if (field.EditorTypeTag == "ColorHsva")
                {
                    editor                = this.ParentGrid.CreateEditor(typeof(ColorHsva[]), this);
                    editor.Getter         = this.CreateUniformArrayValueGetter <ColorHsva>(field.Name);
                    editor.Setter         = !this.ReadOnly ? this.CreateUniformArrayValueSetter <ColorHsva>(field.Name) : null;
                    editor.ForceWriteBack = true;
                }
                else if (field.Type == ShaderFieldType.Float || field.Type == ShaderFieldType.Int)
                {
                    Type editType = typeof(float);
                    if (field.Type == ShaderFieldType.Int)
                    {
                        editType = typeof(int);
                    }

                    editor                = this.ParentGrid.CreateEditor(editType.MakeArrayType(), this);
                    editor.Getter         = this.CreateUniformArrayValueGetter <float>(field.Name);
                    editor.Setter         = !this.ReadOnly ? this.CreateUniformArrayValueSetter <float>(field.Name) : null;
                    editor.ForceWriteBack = true;
                }
                else if (field.Type == ShaderFieldType.Vec2)
                {
                    editor                = this.ParentGrid.CreateEditor(typeof(Vector2[]), this);
                    editor.Getter         = this.CreateUniformArrayValueGetter <Vector2>(field.Name);
                    editor.Setter         = !this.ReadOnly ? this.CreateUniformArrayValueSetter <Vector2>(field.Name) : null;
                    editor.ForceWriteBack = true;
                }
                else if (field.Type == ShaderFieldType.Vec3)
                {
                    editor                = this.ParentGrid.CreateEditor(typeof(Vector3[]), this);
                    editor.Getter         = this.CreateUniformArrayValueGetter <Vector3>(field.Name);
                    editor.Setter         = !this.ReadOnly ? this.CreateUniformArrayValueSetter <Vector3>(field.Name) : null;
                    editor.ForceWriteBack = true;
                }
                else if (field.Type == ShaderFieldType.Vec4)
                {
                    editor                = this.ParentGrid.CreateEditor(typeof(Vector4[]), this);
                    editor.Getter         = this.CreateUniformArrayValueGetter <Vector4>(field.Name);
                    editor.Setter         = !this.ReadOnly ? this.CreateUniformArrayValueSetter <Vector4>(field.Name) : null;
                    editor.ForceWriteBack = true;
                }
                else
                {
                    editor        = this.ParentGrid.CreateEditor(typeof(float[]), this);
                    editor.Getter = this.CreateUniformArrayValueGetter <float>(field.Name);
                    editor.Setter = !this.ReadOnly ? this.CreateUniformArrayValueSetter <float>(field.Name) : null;
                }
            }

            List <EditorHintAttribute> configData = new List <EditorHintAttribute>();

            if (mainEditorIsArray)
            {
                GroupedPropertyEditor groupedMainEditor = editor as GroupedPropertyEditor;
                if (groupedMainEditor != null)
                {
                    groupedMainEditor.EditorAdded += this.UniformList_EditorAdded;
                }
            }
            else
            {
                this.PrepareEditorConfigData(field, configData);
            }

            editor.PropertyName = field.Name;
            editor.PropertyDesc = field.Description;
            this.ParentGrid.ConfigureEditor(editor, configData);
            return(editor);
        }
Exemple #13
0
        protected override void OnUpdateFromObjects(object[] values)
        {
            base.OnUpdateFromObjects(values);

            if (values.Any(o => o != null))
            {
                bool invokeSetter = false;
                IEnumerable <BatchInfo> batchInfos = null;
                DrawTechnique           refTech    = null;
                batchInfos = values.Cast <BatchInfo>();
                refTech    = batchInfos.NotNull().First().Technique.Res;

                // Retrieve data about shader variables
                ShaderFieldInfo[] varInfoArray = null;
                if (refTech != null && refTech.Shader.IsAvailable)
                {
                    if (!refTech.Shader.Res.Compiled)
                    {
                        refTech.Shader.Res.Compile();
                    }
                    varInfoArray = refTech.Shader.Res.Fields;
                }
                else
                {
                    varInfoArray = new ShaderFieldInfo[] { new ShaderFieldInfo(
                                                               ShaderFieldInfo.DefaultNameMainTex,
                                                               ShaderFieldType.Sampler2D,
                                                               ShaderFieldScope.Uniform) };
                }

                // Get rid of unused variables (This changes actual Resource data!)
                if (!this.ReadOnly)
                {
                    foreach (BatchInfo info in batchInfos.NotNull())
                    {
                        List <string> texRemoveSched = null;
                        List <string> uniRemoveSched = null;
                        if (info.Textures != null)
                        {
                            foreach (var pair in info.Textures)
                            {
                                if (!varInfoArray.Any(v => v.Scope == ShaderFieldScope.Uniform && v.Type == ShaderFieldType.Sampler2D && v.Name == pair.Key))
                                {
                                    if (texRemoveSched == null)
                                    {
                                        texRemoveSched = new List <string>();
                                    }
                                    texRemoveSched.Add(pair.Key);
                                }
                            }
                        }
                        if (info.Uniforms != null)
                        {
                            foreach (var pair in info.Uniforms)
                            {
                                if (!varInfoArray.Any(v => v.Scope == ShaderFieldScope.Uniform && v.Type != ShaderFieldType.Sampler2D && v.Name == pair.Key))
                                {
                                    if (uniRemoveSched == null)
                                    {
                                        uniRemoveSched = new List <string>();
                                    }
                                    uniRemoveSched.Add(pair.Key);
                                }
                            }
                        }
                        if (texRemoveSched != null)
                        {
                            foreach (string name in texRemoveSched)
                            {
                                info.SetTexture(name, null);
                            }
                            invokeSetter = true;
                        }
                        if (uniRemoveSched != null)
                        {
                            foreach (string name in uniRemoveSched)
                            {
                                info.SetUniform(name, null);
                            }
                            invokeSetter = true;
                        }
                    }
                }

                // Create BatchInfo variables according to Shader uniforms, if not existing yet
                if (!this.ReadOnly)
                {
                    foreach (ShaderFieldInfo varInfo in varInfoArray)
                    {
                        if (varInfo.Scope != ShaderFieldScope.Uniform)
                        {
                            continue;
                        }

                        // Set Texture variables
                        if (varInfo.Type == ShaderFieldType.Sampler2D)
                        {
                            foreach (BatchInfo info in batchInfos.NotNull())
                            {
                                if (info.GetTexture(varInfo.Name).IsExplicitNull)
                                {
                                    info.SetTexture(varInfo.Name, Texture.White);
                                    invokeSetter = true;
                                }
                            }
                        }
                        // Set other uniform variables
                        else
                        {
                            float[] uniformVal = new float[varInfo.ArrayLength * varInfo.Type.GetElementCount()];
                            if (uniformVal != null)
                            {
                                foreach (BatchInfo info in batchInfos.NotNull())
                                {
                                    float[] oldVal = info.GetUniform(varInfo.Name);
                                    if (oldVal == null)
                                    {
                                        info.SetUniform(varInfo.Name, uniformVal);
                                        invokeSetter = true;
                                    }
                                    else if (oldVal.Length != uniformVal.Length)
                                    {
                                        for (int i = 0; i < Math.Min(oldVal.Length, uniformVal.Length); i++)
                                        {
                                            uniformVal[i] = oldVal[i];
                                        }
                                        info.SetUniform(varInfo.Name, uniformVal);
                                        invokeSetter = true;
                                    }
                                }
                            }
                        }
                    }
                }

                // Create editors according to existing variables
                var texDict     = batchInfos.NotNull().First().Textures;
                var uniformDict = batchInfos.NotNull().First().Uniforms;
                Dictionary <string, PropertyEditor> oldEditors = new Dictionary <string, PropertyEditor>(this.shaderVarEditors);
                if (texDict != null)
                {
                    foreach (var tex in texDict)
                    {
                        ShaderFieldInfo varInfo = varInfoArray.FirstOrDefault(v => v.Scope == ShaderFieldScope.Uniform && v.Name == tex.Key);
                        if (varInfo.IsPrivate)
                        {
                            continue;
                        }

                        string texName = varInfo.Name;
                        if (oldEditors.ContainsKey(texName))
                        {
                            oldEditors.Remove(texName);
                        }
                        else
                        {
                            PropertyEditor e = this.ParentGrid.CreateEditor(typeof(ContentRef <Texture>), this);
                            e.Getter       = this.CreateTextureValueGetter(texName);
                            e.Setter       = !this.ReadOnly ? this.CreateTextureValueSetter(texName) : null;
                            e.PropertyName = texName;
                            this.shaderVarEditors[texName] = e;
                            this.ParentGrid.ConfigureEditor(e);
                            this.AddPropertyEditor(e);
                        }
                    }
                }
                if (uniformDict != null)
                {
                    foreach (var uniform in uniformDict)
                    {
                        ShaderFieldInfo varInfo = varInfoArray.FirstOrDefault(v => v.Scope == ShaderFieldScope.Uniform && v.Name == uniform.Key);
                        if (varInfo.IsPrivate)
                        {
                            continue;
                        }

                        PropertyEditor e = this.CreateUniformEditor(varInfo);
                        if (e != null)
                        {
                            if (oldEditors.ContainsValue(e))
                            {
                                oldEditors.Remove(varInfo.Name);
                            }
                            else
                            {
                                e.PropertyName = uniform.Key;
                                this.shaderVarEditors[uniform.Key] = e;
                                this.AddPropertyEditor(e);
                            }
                        }
                    }
                }

                // Remove old editors that aren't needed anymore
                foreach (var pair in oldEditors)
                {
                    if (this.shaderVarEditors[pair.Key] == pair.Value)
                    {
                        this.shaderVarEditors.Remove(pair.Key);
                    }
                    this.RemovePropertyEditor(pair.Value);
                }

                // If we actually changed (updated) data here, invoke the setter
                if (invokeSetter)
                {
                    this.SetValues(batchInfos);
                    if (!this.IsUpdating)
                    {
                        this.PerformGetValue();
                    }
                }
            }
        }
Exemple #14
0
        protected PropertyEditor CreateUniformEditor(ShaderFieldInfo varInfo)
        {
            PropertyEditor oldEditor;

            this.shaderVarEditors.TryGetValue(varInfo.Name, out oldEditor);
            List <EditorHintAttribute> configData = new List <EditorHintAttribute>();

            if (varInfo.ArrayLength == 1)
            {
                if (varInfo.Type == ShaderFieldType.Float || varInfo.Type == ShaderFieldType.Int)
                {
                    Type editType = typeof(float);
                    if (varInfo.Type == ShaderFieldType.Int)
                    {
                        editType = typeof(int);
                    }

                    if (oldEditor != null && oldEditor.EditedType == editType)
                    {
                        return(oldEditor);
                    }
                    else
                    {
                        PropertyEditor e = this.ParentGrid.CreateEditor(editType, this);
                        if (varInfo.Type == ShaderFieldType.Int)
                        {
                            e.Getter = this.CreateUniformIntValueGetter(varInfo.Name);
                            e.Setter = !this.ReadOnly ? this.CreateUniformIntValueSetter(varInfo.Name) : null;
                        }
                        else
                        {
                            e.Getter = this.CreateUniformFloatValueGetter(varInfo.Name);
                            e.Setter = !this.ReadOnly ? this.CreateUniformFloatValueSetter(varInfo.Name) : null;
                            configData.Add(new EditorHintIncrementAttribute(0.1f));
                        }
                        this.ParentGrid.ConfigureEditor(e, configData);
                        return(e);
                    }
                }
                else if (varInfo.Type == ShaderFieldType.Vec2)
                {
                    if (oldEditor != null && oldEditor.EditedType == typeof(Vector2))
                    {
                        return(oldEditor);
                    }
                    else
                    {
                        PropertyEditor e = this.ParentGrid.CreateEditor(typeof(Vector2), this);
                        e.Getter = this.CreateUniformVec2ValueGetter(varInfo.Name);
                        e.Setter = !this.ReadOnly ? this.CreateUniformVec2ValueSetter(varInfo.Name) : null;
                        configData.Add(new EditorHintIncrementAttribute(0.1f));
                        this.ParentGrid.ConfigureEditor(e, configData);
                        return(e);
                    }
                }
                else if (varInfo.Type == ShaderFieldType.Vec3)
                {
                    if (oldEditor != null && oldEditor.EditedType == typeof(Vector3))
                    {
                        return(oldEditor);
                    }
                    else
                    {
                        PropertyEditor e = this.ParentGrid.CreateEditor(typeof(Vector3), this);
                        e.Getter = this.CreateUniformVec3ValueGetter(varInfo.Name);
                        e.Setter = !this.ReadOnly ? this.CreateUniformVec3ValueSetter(varInfo.Name) : null;
                        configData.Add(new EditorHintIncrementAttribute(0.1f));
                        this.ParentGrid.ConfigureEditor(e, configData);
                        return(e);
                    }
                }
                else
                {
                    if (oldEditor != null && oldEditor.EditedType == typeof(float[]))
                    {
                        return(oldEditor);
                    }
                    else
                    {
                        PropertyEditor e = this.ParentGrid.CreateEditor(typeof(float[]), this);
                        e.Getter = this.CreateUniformValueGetter(varInfo.Name);
                        e.Setter = !this.ReadOnly ? this.CreateUniformValueSetter(varInfo.Name) : null;
                        if (e is GroupedPropertyEditor)
                        {
                            (e as GroupedPropertyEditor).EditorAdded += this.UniformList_EditorAdded;
                        }
                        this.ParentGrid.ConfigureEditor(e, configData);
                        return(e);
                    }
                }
            }
            else
            {
                Array oldValue       = oldEditor != null ? (oldEditor as IListPropertyEditor).DisplayedValue as Array : null;
                Type  oldElementType = oldValue != null?oldValue.GetType().GetElementType() : null;

                int oldLen = oldValue != null ? oldValue.Length : -1;

                if (varInfo.Type == ShaderFieldType.Float || varInfo.Type == ShaderFieldType.Int)
                {
                    Type editType = typeof(float);
                    if (varInfo.Type == ShaderFieldType.Int)
                    {
                        editType = typeof(int);
                    }

                    if (oldLen == varInfo.ArrayLength && oldElementType == editType)
                    {
                        return(oldEditor);
                    }
                    else
                    {
                        PropertyEditor e = this.ParentGrid.CreateEditor(editType.MakeArrayType(), this);
                        e.Getter         = this.CreateUniformValueGetter(varInfo.Name);
                        e.Setter         = !this.ReadOnly ? this.CreateUniformValueSetter(varInfo.Name) : null;
                        e.ForceWriteBack = true;
                        if (e is GroupedPropertyEditor)
                        {
                            if (varInfo.Type == ShaderFieldType.Float)
                            {
                                (e as GroupedPropertyEditor).EditorAdded += this.UniformList_EditorAdded;
                            }
                        }
                        this.ParentGrid.ConfigureEditor(e, configData);
                        return(e);
                    }
                }
                else if (varInfo.Type == ShaderFieldType.Vec2)
                {
                    if (oldLen == varInfo.ArrayLength && oldElementType == typeof(Vector2))
                    {
                        return(oldEditor);
                    }
                    else
                    {
                        PropertyEditor e = this.ParentGrid.CreateEditor(typeof(Vector2[]), this);
                        e.Getter         = this.CreateUniformVec2ArrayValueGetter(varInfo.Name);
                        e.Setter         = !this.ReadOnly ? this.CreateUniformVec2ArrayValueSetter(varInfo.Name) : null;
                        e.ForceWriteBack = true;
                        if (e is GroupedPropertyEditor)
                        {
                            (e as GroupedPropertyEditor).EditorAdded += this.UniformList_EditorAdded;
                        }
                        this.ParentGrid.ConfigureEditor(e, configData);
                        return(e);
                    }
                }
                else if (varInfo.Type == ShaderFieldType.Vec3)
                {
                    if (oldLen == varInfo.ArrayLength && oldElementType == typeof(Vector3))
                    {
                        return(oldEditor);
                    }
                    else
                    {
                        PropertyEditor e = this.ParentGrid.CreateEditor(typeof(Vector3[]), this);
                        e.Getter         = this.CreateUniformVec3ArrayValueGetter(varInfo.Name);
                        e.Setter         = !this.ReadOnly ? this.CreateUniformVec3ArrayValueSetter(varInfo.Name) : null;
                        e.ForceWriteBack = true;
                        if (e is GroupedPropertyEditor)
                        {
                            (e as GroupedPropertyEditor).EditorAdded += this.UniformList_EditorAdded;
                        }
                        this.ParentGrid.ConfigureEditor(e, configData);
                        return(e);
                    }
                }
                else
                {
                    if (oldLen == varInfo.ArrayLength)
                    {
                        return(oldEditor);
                    }
                    else
                    {
                        PropertyEditor e = this.ParentGrid.CreateEditor(typeof(float[][]), this);
                        e.Getter         = this.CreateUniformArrayValueGetter(varInfo.Name, varInfo.ArrayLength);
                        e.Setter         = !this.ReadOnly ? this.CreateUniformArrayValueSetter(varInfo.Name) : null;
                        e.ForceWriteBack = true;
                        if (e is GroupedPropertyEditor)
                        {
                            (e as GroupedPropertyEditor).EditorAdded += this.UniformList_EditorAdded;
                        }
                        this.ParentGrid.ConfigureEditor(e, configData);
                        return(e);
                    }
                }
            }
        }
Exemple #15
0
        private void SetupMaterial(BatchInfo material, BatchInfo lastMaterial)
        {
            DrawTechnique tech     = material.Technique.Res ?? DrawTechnique.Solid.Res;
            DrawTechnique lastTech = lastMaterial != null ? lastMaterial.Technique.Res : null;

            // Setup BlendType
            if (lastTech == null || tech.Blending != lastTech.Blending)
            {
                this.SetupBlendState(tech.Blending);
            }

            // Bind Shader
            NativeShaderProgram nativeShader = tech.NativeShader as NativeShaderProgram;

            NativeShaderProgram.Bind(nativeShader);

            // Setup shader data
            ShaderFieldInfo[] varInfo   = nativeShader.Fields;
            int[]             locations = nativeShader.FieldLocations;

            // Setup sampler bindings and uniform data
            int curSamplerIndex = this.sharedSamplerBindings;

            for (int i = 0; i < varInfo.Length; i++)
            {
                ShaderFieldInfo field    = varInfo[i];
                int             location = locations[i];

                if (field.Scope == ShaderFieldScope.Attribute)
                {
                    continue;
                }
                if (this.sharedShaderParameters.Contains(field.Name))
                {
                    continue;
                }

                if (field.Type == ShaderFieldType.Sampler2D)
                {
                    ContentRef <Texture> texRef = material.GetInternalTexture(field.Name);
                    if (texRef == null)
                    {
                        this.internalShaderState.TryGetInternal(field.Name, out texRef);
                    }

                    NativeTexture.Bind(texRef, curSamplerIndex);
                    GL.Uniform1(location, curSamplerIndex);

                    curSamplerIndex++;
                }
                else
                {
                    float[] data = material.GetInternalData(field.Name);
                    if (data == null && !this.internalShaderState.TryGetInternal(field.Name, out data))
                    {
                        continue;
                    }

                    NativeShaderProgram.SetUniform(field, location, data);
                }
            }
            NativeTexture.ResetBinding(curSamplerIndex);
        }
Exemple #16
0
        [Test] public void FieldParsingBasics()
        {
            ShaderSourceBuilder builder = new ShaderSourceBuilder();
            string mainShader           = new StringBuilder()
                                          .AppendLine("#pragma duality editorType ColorRgba")
                                          .AppendLine("#pragma duality description \"Test firstUniform Desc\"")
                                          .AppendLine("uniform vec4 firstUniform;")
                                          .AppendLine()
                                          .AppendLine("#pragma duality editorType Single")
                                          .AppendLine("#pragma duality description \"Test secondUniform Desc\"")
                                          .AppendLine("// Some comment")
                                          .AppendLine("uniform float secondUniform;")
                                          .AppendLine()
                                          .AppendLine("#pragma duality editorType ColorRgba")
                                          .AppendLine()
                                          .AppendLine("#pragma duality description \"Test firstAttribute Desc\"")
                                          .AppendLine()
                                          .AppendLine("in vec4 firstAttribute;")
                                          .AppendLine()
                                          .AppendLine("#pragma duality editorType Single")
                                          .AppendLine("#pragma duality description \"Test secondAttribute Desc\"")
                                          .AppendLine()
                                          .AppendLine("in vec4 secondAttribute;")
                                          .AppendLine()
                                          .AppendLine("void main()")
                                          .AppendLine("{")
                                          .AppendLine("  gl_Position = vec4(0.0, 0.0, 0.0, 1.0);")
                                          .AppendLine("}")
                                          .ToString();

            builder.SetMainChunk(mainShader);

            string resultShader = builder.Build();

            Assert.AreEqual(4, builder.Fields.Count);

            ShaderFieldInfo firstUniform    = builder.Fields[0];
            ShaderFieldInfo secondUniform   = builder.Fields[1];
            ShaderFieldInfo firstAttribute  = builder.Fields[2];
            ShaderFieldInfo secondAttribute = builder.Fields[3];

            Assert.AreEqual("firstUniform", firstUniform.Name);
            Assert.AreEqual(ShaderFieldScope.Uniform, firstUniform.Scope);
            Assert.AreEqual(ShaderFieldType.Vec4, firstUniform.Type);
            Assert.AreEqual("ColorRgba", firstUniform.EditorTypeTag);
            Assert.AreEqual("Test firstUniform Desc", firstUniform.Description);
            Assert.AreEqual(1, firstUniform.ArrayLength);
            Assert.AreEqual(false, firstUniform.IsPrivate);

            Assert.AreEqual("secondUniform", secondUniform.Name);
            Assert.AreEqual(ShaderFieldScope.Uniform, secondUniform.Scope);
            Assert.AreEqual(ShaderFieldType.Float, secondUniform.Type);
            Assert.AreEqual("Single", secondUniform.EditorTypeTag);
            Assert.AreEqual("Test secondUniform Desc", secondUniform.Description);
            Assert.AreEqual(1, secondUniform.ArrayLength);
            Assert.AreEqual(false, secondUniform.IsPrivate);

            Assert.AreEqual("firstAttribute", firstAttribute.Name);
            Assert.AreEqual(ShaderFieldScope.Attribute, firstAttribute.Scope);
            Assert.AreEqual(ShaderFieldType.Vec4, firstAttribute.Type);
            Assert.AreEqual("ColorRgba", firstAttribute.EditorTypeTag);
            Assert.AreEqual("Test firstAttribute Desc", firstAttribute.Description);
            Assert.AreEqual(1, firstAttribute.ArrayLength);
            Assert.AreEqual(false, firstAttribute.IsPrivate);

            Assert.AreEqual("secondAttribute", secondAttribute.Name);
            Assert.AreEqual(ShaderFieldScope.Attribute, secondAttribute.Scope);
            Assert.AreEqual(ShaderFieldType.Vec4, secondAttribute.Type);
            Assert.AreEqual("Single", secondAttribute.EditorTypeTag);
            Assert.AreEqual("Test secondAttribute Desc", secondAttribute.Description);
            Assert.AreEqual(1, secondAttribute.ArrayLength);
            Assert.AreEqual(false, secondAttribute.IsPrivate);
        }