Пример #1
0
        private static void AddAttributesToMaterial(MatlEntry source, Material destination)
        {
            // There should only be a single rasterizer state in each material.
            if (source.GetRasterizerStates().TryGetValue(MatlEnums.ParamId.RasterizerState0, out MatlAttribute.MatlRasterizerState? rasterizerState))
            {
                destination.RasterizerState0 = new RasterizerStateParam(rasterizerState);
            }

            // There should only be a single blend state in each material.
            if (source.GetBlendStates().TryGetValue(MatlEnums.ParamId.BlendState0, out MatlAttribute.MatlBlendState? blendState))
            {
                destination.BlendState0 = new BlendStateParam(blendState);
            }

            destination.FloatParams.AddRange(source.Attributes
                                             .Where(a => a.DataType == MatlEnums.ParamDataType.Float)
                                             .Select(a => new FloatParam(a)));

            destination.BooleanParams.AddRange(source.Attributes
                                               .Where(a => a.DataType == MatlEnums.ParamDataType.Boolean)
                                               .Select(a => new BooleanParam(a)));

            destination.Vec4Params.AddRange(source.Attributes
                                            .Where(a => a.DataType == MatlEnums.ParamDataType.Vector4)
                                            .Select(a => new Vec4Param(a)));

            AddTextures(source, destination);
        }
Пример #2
0
        private static List <MatlAttribute> GetAttributeList(MatlEntry currentEntry, MatlEntry newEntry, bool preserveTextureNames)
        {
            var attributes = new List <MatlAttribute>();

            if (newEntry.Attributes != null)
            {
                foreach (var newAttribute in newEntry.Attributes)
                {
                    if (newAttribute.DataObject is MatlAttribute.MatlString newTexture && preserveTextureNames)
                    {
                        var currentValue = currentEntry.Attributes.FirstOrDefault(a => a.ParamId == newAttribute.ParamId)?.DataObject as MatlAttribute.MatlString;

                        // Use an appropriate default texture if not found.
                        // This preserves the current appearance when applying a preset (ex: black for an emissive map).
                        var textureName = currentValue?.Text ?? GetDefaultTexture(newAttribute.ParamId);

                        attributes.Add(new MatlAttribute
                        {
                            ParamId    = newAttribute.ParamId,
                            DataType   = newAttribute.DataType,
                            DataObject = new MatlAttribute.MatlString {
                                Text = textureName
                            }
                        });
                    }
                    else
                    {
                        attributes.Add(new MatlAttribute
                        {
                            ParamId    = newAttribute.ParamId,
                            DataType   = newAttribute.DataType,
                            DataObject = newAttribute.DataObject
                        });
                    }
                }
Пример #3
0
        public static Matl LibraryToMATL(MaterialLibrary library)
        {
            Matl matl = new Matl
            {
                Entries = new MatlEntry[library.material.Length]
            };

            for (int i = 0; i < library.material.Length; i++)
            {
                MatlEntry entry = new MatlEntry
                {
                    MaterialLabel = library.material[i].label,
                    MaterialName  = library.material[i].name,
                    Attributes    = new MatlAttribute[library.material[i].param.Length]
                };

                for (int j = 0; j < library.material[i].param.Length; j++)
                {
                    entry.Attributes[j] = new MatlAttribute
                    {
                        ParamId = library.material[i].param[j].name,

                        DataObject = library.material[i].param[j].value
                    };
                }

                matl.Entries[i] = entry;
            }

            return(matl);
        }
Пример #4
0
        private Material CreateMaterial(MatlEntry entry, int index, RMaterial?rMaterial)
        {
            var material = CreateMaterial(entry, index);

            // Enable real time viewport updates.
            if (rMaterial != null)
            {
                SyncViewModelToRMaterial(rMaterial, material);
            }

            return(material);
        }
Пример #5
0
        public static MatlEntry FromShaderAndAttributes(MatlEntry currentEntry, MatlEntry newEntry, bool preserveTextureNames)
        {
            // TODO: Avoid conversion to array?
            var entry = new MatlEntry
            {
                MaterialLabel = currentEntry.MaterialLabel,
                ShaderLabel   = newEntry.ShaderLabel,
                Attributes    = GetAttributeList(currentEntry, newEntry, preserveTextureNames).ToArray()
            };

            return(entry);
        }
Пример #6
0
        private static void AddTextures(MatlEntry source, Material destination)
        {
            // TODO: Are texture names case sensitive?
            foreach (var texture in source.Attributes.Where(a => a.DataType == MatlEnums.ParamDataType.String))
            {
                // TODO: Handle the case where samplers are missing?
                var sampler = source.Attributes.SingleOrDefault(a => a.ParamId == ParamIdExtensions.GetSampler(texture.ParamId));
                if (sampler == null)
                {
                    continue;
                }

                destination.TextureParams.Add(new TextureSamplerParam(texture, sampler));
            }
        }
Пример #7
0
 private static Material CreateMaterial(MatlEntry entry)
 {
     return(new Material
     {
         shaderLabel = entry.ShaderLabel,
         materialLabel = entry.MaterialLabel,
         parameters = entry.Attributes
                      .Select(a =>
                              new MatlXmlAttribute
         {
             name = a.ParamId,
             value = a.DataObject
         })
                      .ToArray()
     });
 }
Пример #8
0
        public void UpdateMaterial()
        {
            foreach (ModlEntry e in MODL.ModelEntries)
            {
                MatlEntry currentEntry = null;
                foreach (MatlEntry entry in Material.Entries)
                {
                    if (entry.MaterialLabel.Equals(e.MaterialName))
                    {
                        currentEntry = entry;
                        break;
                    }
                }
                if (currentEntry == null)
                {
                    continue;
                }

                System.Diagnostics.Debug.WriteLine(e.MeshName);
                Material meshMaterial = GetMaterial(currentEntry);
                System.Diagnostics.Debug.WriteLine("");

                int    subIndex = 0;
                string prevMesh = "";

                if (Model != null)
                {
                    foreach (RMesh mesh in Model.subMeshes)
                    {
                        if (prevMesh.Equals(mesh.Name))
                        {
                            subIndex++;
                        }
                        else
                        {
                            subIndex = 0;
                        }
                        prevMesh = mesh.Name;
                        if (subIndex == e.SubIndex && mesh.Name.Equals(e.MeshName))
                        {
                            mesh.Material = meshMaterial;
                            break;
                        }
                    }
                }
            }
        }
Пример #9
0
        public static RMaterial CreateMaterial(MatlEntry currentEntry, int index, Dictionary <string, RTexture> textureByName)
        {
            RMaterial meshMaterial = new RMaterial(currentEntry.MaterialLabel, currentEntry.ShaderLabel, index)
            {
                TextureByName = textureByName
            };

            foreach (var pair in currentEntry.GetTextures())
            {
                // Don't make texture names case sensitive.
                meshMaterial.UpdateTexture(pair.Key, pair.Value.ToLower());
            }

            foreach (var pair in currentEntry.GetFloats())
            {
                meshMaterial.UpdateFloat(pair.Key, pair.Value);
            }

            foreach (var pair in currentEntry.GetVectors())
            {
                meshMaterial.UpdateVec4(pair.Key, pair.Value.ToOpenTk());
            }

            foreach (var pair in currentEntry.GetBools())
            {
                meshMaterial.UpdateBoolean(pair.Key, pair.Value);
            }

            foreach (var pair in currentEntry.GetSamplers())
            {
                meshMaterial.UpdateSampler(pair.Key, pair.Value.ToSamplerData());
            }

            foreach (var pair in currentEntry.GetRasterizerStates())
            {
                SetRasterizerState(meshMaterial, pair.Value);
            }

            foreach (var pair in currentEntry.GetBlendStates())
            {
                SetBlendState(meshMaterial, pair.Value);
            }

            return(meshMaterial);
        }
Пример #10
0
        private static Material CreateMaterial(MatlEntry entry, int index)
        {
            var idColor = UniqueColors.IndexToColor(index);

            var material = new Material(entry)
            {
                MaterialIdColor = new SolidColorBrush(Color.FromArgb(255,
                                                                     (byte)idColor.X,
                                                                     (byte)idColor.Y,
                                                                     (byte)idColor.Z)),
                ShaderAttributeNames = string.Join(", ", ShaderValidation.GetAttributes(entry.ShaderLabel)),
                ShaderParameterNames = string.Join(", ", ShaderValidation.GetParameters(entry.ShaderLabel).Select(p => p.ToString()).ToList()),
                RenderPasses         = ShaderValidation.GetRenderPasses(entry.ShaderLabel)
            };

            AddAttributesToMaterial(entry, material);
            return(material);
        }
Пример #11
0
        private static MatlEntry CreateEntry(Material material)
        {
            var entry = new MatlEntry
            {
                MaterialLabel = material.materialLabel,
                ShaderLabel   = material.shaderLabel,
                Attributes    = material.parameters
                                .Select(p =>
                                        new MatlAttribute
                {
                    ParamId    = p.name,
                    DataObject = p.value
                })
                                .ToArray()
            };

            return(entry);
        }
Пример #12
0
        public void PreserveLabels()
        {
            var currentEntry = new MatlEntry
            {
                ShaderLabel   = "currentShader",
                MaterialLabel = "currentMaterial"
            };

            var newEntry = new MatlEntry
            {
                ShaderLabel   = "newShader",
                MaterialLabel = "newMaterial"
            };

            var result = MatlTools.FromShaderAndAttributes(currentEntry, newEntry, false);

            // Make sure existing material assignments to meshes aren't effected.
            Assert.AreEqual("newShader", result.ShaderLabel);
            Assert.AreEqual("currentMaterial", result.MaterialLabel);
        }
Пример #13
0
        public void DoNotPreserveTextures()
        {
            var currentEntry = new MatlEntry
            {
                ShaderLabel   = "currentShader",
                MaterialLabel = "currentMaterial",
                Attributes    = new MatlAttribute[]
                {
                    CreateTexture(MatlEnums.ParamId.Texture0, "texture0_current"),
                    CreateTexture(MatlEnums.ParamId.Texture1, "texture1_current"),
                    CreateTexture(MatlEnums.ParamId.Texture2, "texture2_current"),
                    CreateFloat(MatlEnums.ParamId.CustomFloat0, 0.1f)
                }
            };

            var newEntry = new MatlEntry
            {
                ShaderLabel   = "newShader",
                MaterialLabel = "newMaterial",
                Attributes    = new MatlAttribute[]
                {
                    CreateTexture(MatlEnums.ParamId.Texture0, "texture0_new"),
                    CreateTexture(MatlEnums.ParamId.Texture1, "texture1_new"),
                    CreateTexture(MatlEnums.ParamId.Texture2, "texture2_new"),
                    CreateTexture(MatlEnums.ParamId.Texture3, "texture3_new"),
                    CreateFloat(MatlEnums.ParamId.CustomFloat0, 0.3f)
                }
            };

            var result = MatlTools.FromShaderAndAttributes(currentEntry, newEntry, false);

            // Don't preserve any material values.
            Assert.AreEqual("texture0_new", ((MatlAttribute.MatlString)result.Attributes[0].DataObject).Text);
            Assert.AreEqual("texture1_new", ((MatlAttribute.MatlString)result.Attributes[1].DataObject).Text);
            Assert.AreEqual("texture2_new", ((MatlAttribute.MatlString)result.Attributes[2].DataObject).Text);
            Assert.AreEqual("texture3_new", ((MatlAttribute.MatlString)result.Attributes[3].DataObject).Text);
            Assert.AreEqual(0.3f, (float)result.Attributes[4].DataObject);
        }
Пример #14
0
        public void DefaultTextures()
        {
            var currentEntry = new MatlEntry
            {
                ShaderLabel   = "currentShader",
                MaterialLabel = "currentMaterial",
                Attributes    = new MatlAttribute[0]
            };

            var newEntry = new MatlEntry
            {
                ShaderLabel   = "newShader",
                MaterialLabel = "newMaterial",
                Attributes    = new MatlAttribute[]
                {
                    CreateTexture(MatlEnums.ParamId.Texture0, "texture"),
                    CreateTexture(MatlEnums.ParamId.Texture1, "texture"),
                    CreateTexture(MatlEnums.ParamId.Texture2, "texture"),
                    CreateTexture(MatlEnums.ParamId.Texture3, "texture"),
                    CreateTexture(MatlEnums.ParamId.Texture4, "texture"),
                    CreateTexture(MatlEnums.ParamId.Texture5, "texture"),
                    CreateTexture(MatlEnums.ParamId.Texture6, "texture"),
                    CreateTexture(MatlEnums.ParamId.Texture7, "texture"),
                    CreateTexture(MatlEnums.ParamId.Texture8, "texture"),
                    CreateTexture(MatlEnums.ParamId.Texture9, "texture"),
                    CreateTexture(MatlEnums.ParamId.Texture10, "texture"),
                    CreateTexture(MatlEnums.ParamId.Texture11, "texture"),
                    CreateTexture(MatlEnums.ParamId.Texture12, "texture"),
                    CreateTexture(MatlEnums.ParamId.Texture13, "texture"),
                    CreateTexture(MatlEnums.ParamId.Texture14, "texture"),
                    CreateTexture(MatlEnums.ParamId.Texture15, "texture"),
                    CreateTexture(MatlEnums.ParamId.Texture16, "texture"),
                    CreateTexture(MatlEnums.ParamId.Texture17, "texture"),
                    CreateTexture(MatlEnums.ParamId.Texture18, "texture"),
                    CreateTexture(MatlEnums.ParamId.Texture19, "texture"),
                }
            };


            var result = MatlTools.FromShaderAndAttributes(currentEntry, newEntry, true);

            // Missing textures should use a default value.
            Assert.AreEqual("/common/shader/sfxPBS/default_Gray", ((MatlAttribute.MatlString)result.Attributes[0].DataObject).Text);
            Assert.AreEqual("/common/shader/sfxPBS/default_Gray", ((MatlAttribute.MatlString)result.Attributes[1].DataObject).Text);
            Assert.AreEqual("#replace_cubemap", ((MatlAttribute.MatlString)result.Attributes[2].DataObject).Text);
            Assert.AreEqual("/common/shader/sfxPBS/default_White", ((MatlAttribute.MatlString)result.Attributes[3].DataObject).Text);
            Assert.AreEqual("/common/shader/sfxPBS/default_Normal", ((MatlAttribute.MatlString)result.Attributes[4].DataObject).Text);
            Assert.AreEqual("/common/shader/sfxPBS/default_Black", ((MatlAttribute.MatlString)result.Attributes[5].DataObject).Text);
            Assert.AreEqual("/common/shader/sfxPBS/default_Params", ((MatlAttribute.MatlString)result.Attributes[6].DataObject).Text);
            Assert.AreEqual("#replace_cubemap", ((MatlAttribute.MatlString)result.Attributes[7].DataObject).Text);
            Assert.AreEqual("#replace_cubemap", ((MatlAttribute.MatlString)result.Attributes[8].DataObject).Text);
            Assert.AreEqual("/common/shader/sfxPBS/default_Black", ((MatlAttribute.MatlString)result.Attributes[9].DataObject).Text);
            Assert.AreEqual("/common/shader/sfxPBS/default_Gray", ((MatlAttribute.MatlString)result.Attributes[10].DataObject).Text);
            Assert.AreEqual("/common/shader/sfxPBS/default_Gray", ((MatlAttribute.MatlString)result.Attributes[11].DataObject).Text);
            Assert.AreEqual("/common/shader/sfxPBS/default_Gray", ((MatlAttribute.MatlString)result.Attributes[12].DataObject).Text);
            Assert.AreEqual("/common/shader/sfxPBS/default_Black", ((MatlAttribute.MatlString)result.Attributes[13].DataObject).Text);
            Assert.AreEqual("/common/shader/sfxPBS/default_Black", ((MatlAttribute.MatlString)result.Attributes[14].DataObject).Text);
            Assert.AreEqual("/common/shader/sfxPBS/default_Black", ((MatlAttribute.MatlString)result.Attributes[15].DataObject).Text);
            Assert.AreEqual("/common/shader/sfxPBS/default_Normal", ((MatlAttribute.MatlString)result.Attributes[16].DataObject).Text);
            Assert.AreEqual("/common/shader/sfxPBS/default_Black", ((MatlAttribute.MatlString)result.Attributes[17].DataObject).Text);
            Assert.AreEqual("/common/shader/sfxPBS/default_Black", ((MatlAttribute.MatlString)result.Attributes[18].DataObject).Text);
            Assert.AreEqual("/common/shader/sfxPBS/default_Black", ((MatlAttribute.MatlString)result.Attributes[19].DataObject).Text);
        }
Пример #15
0
        private Material GetMaterial(MatlEntry currentEntry)
        {
            // HACK: This is pretty gross.
            // I need to rework the entire texture loading system.
            if (RMesh.defaultTextures == null)
            {
                RMesh.defaultTextures = new Resources.DefaultTextures();
            }

            Material meshMaterial = new Material(RMesh.defaultTextures);

            meshMaterial.Name = currentEntry.MaterialLabel;

            System.Diagnostics.Debug.WriteLine("Material Attributes:");
            foreach (MatlAttribute a in currentEntry.Attributes)
            {
                if (a.DataObject == null)
                {
                    continue;
                }

                System.Diagnostics.Debug.WriteLine($"{(MatlEnums.ParamDataType) a.DataType} {a.ParamID} {a.DataObject}");

                switch (a.DataType)
                {
                case MatlEnums.ParamDataType.String:
                    SetTextureParameter(meshMaterial, a);
                    // HACK: Just render as white if texture is present.
                    meshMaterial.floatByParamId[(long)a.ParamID] = 1;
                    break;

                case MatlEnums.ParamDataType.Vector4:
                    var vec4 = (MatlAttribute.MatlVector4)a.DataObject;
                    meshMaterial.vec4ByParamId[(long)a.ParamID] = new OpenTK.Vector4(vec4.X, vec4.Y, vec4.Z, vec4.W);
                    break;

                case MatlEnums.ParamDataType.Boolean:
                    // Convert to vec4 to use with rendering.
                    // Use cyan to differentiate with no value (blue).
                    bool boolValue = (bool)a.DataObject;
                    meshMaterial.boolByParamId[(long)a.ParamID] = boolValue;
                    break;

                case MatlEnums.ParamDataType.Float:
                    float floatValue = (float)a.DataObject;
                    meshMaterial.floatByParamId[(long)a.ParamID] = floatValue;
                    break;
                }
            }

            // HACK: Textures need to be initialized first before we can modify their state.
            foreach (MatlAttribute a in currentEntry.Attributes)
            {
                if (a.DataObject == null || a.DataType != MatlEnums.ParamDataType.Sampler)
                {
                    continue;
                }

                SetSamplerInformation(meshMaterial, a);
            }

            return(meshMaterial);
        }
Пример #16
0
 public static Dictionary <MatlEnums.ParamId, bool> GetBools(this MatlEntry entry)
 {
     return(entry.Attributes
            .Where(a => a.DataType == MatlEnums.ParamDataType.Boolean)
            .ToDictionary(a => a.ParamId, a => (bool)a.DataObject));
 }
Пример #17
0
 public static Dictionary <MatlEnums.ParamId, string> GetTextures(this MatlEntry entry)
 {
     return(entry.Attributes
            .Where(a => a.DataType == MatlEnums.ParamDataType.String)
            .ToDictionary(a => a.ParamId, a => ((MatlAttribute.MatlString)a.DataObject).Text));
 }
Пример #18
0
        public static RMaterial CreateMaterial(MatlEntry currentEntry, int index, Dictionary <string, RTexture> textureByName)
        {
            RMaterial meshMaterial = new RMaterial()
            {
                MaterialLabel = currentEntry.MaterialLabel,
                ShaderLabel   = currentEntry.ShaderLabel,
                Index         = index,
                TextureByName = textureByName
            };

            foreach (MatlAttribute attribute in currentEntry.Attributes)
            {
                if (attribute.DataObject == null)
                {
                    continue;
                }

                switch (attribute.DataType)
                {
                case MatlEnums.ParamDataType.String:
                    SetTextureParameter(meshMaterial, attribute);
                    break;

                case MatlEnums.ParamDataType.Vector4:
                    var vec4 = (MatlAttribute.MatlVector4)attribute.DataObject;
                    meshMaterial.vec4ByParamId[attribute.ParamId] = new Vector4(vec4.X, vec4.Y, vec4.Z, vec4.W);
                    break;

                case MatlEnums.ParamDataType.Boolean:
                    // Convert to vec4 to use with rendering.
                    // Use cyan to differentiate with no value (blue).
                    bool boolValue = (bool)attribute.DataObject;
                    meshMaterial.boolByParamId[attribute.ParamId] = boolValue;
                    break;

                case MatlEnums.ParamDataType.Float:
                    float floatValue = (float)attribute.DataObject;
                    meshMaterial.floatByParamId[attribute.ParamId] = floatValue;
                    break;

                case MatlEnums.ParamDataType.BlendState:
                    SetBlendState(meshMaterial, attribute);
                    break;

                case MatlEnums.ParamDataType.RasterizerState:
                    SetRasterizerState(meshMaterial, attribute);
                    break;
                }
            }

            foreach (MatlAttribute a in currentEntry.Attributes)
            {
                if (a.DataObject == null || a.DataType != MatlEnums.ParamDataType.Sampler)
                {
                    continue;
                }

                SetSamplerInformation(meshMaterial, a);
            }

            return(meshMaterial);
        }
Пример #19
0
 public static Dictionary <MatlEnums.ParamId, MatlAttribute.MatlSampler> GetSamplers(this MatlEntry entry)
 {
     return(entry.Attributes
            .Where(a => a.DataType == MatlEnums.ParamDataType.Sampler)
            .ToDictionary(a => a.ParamId, a => (MatlAttribute.MatlSampler)a.DataObject));
 }
Пример #20
0
 public static Dictionary <MatlEnums.ParamId, MatlAttribute.MatlBlendState> GetBlendStates(this MatlEntry entry)
 {
     return(entry.Attributes
            .Where(a => a.DataType == MatlEnums.ParamDataType.BlendState)
            .ToDictionary(a => a.ParamId, a => (MatlAttribute.MatlBlendState)a.DataObject));
 }
Пример #21
0
 public static Dictionary <MatlEnums.ParamId, float> GetFloats(this MatlEntry entry)
 {
     return(entry.Attributes
            .Where(a => a.DataType == MatlEnums.ParamDataType.Float)
            .ToDictionary(a => a.ParamId, a => (float)a.DataObject));
 }