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); }
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 }); } }
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); }
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); }
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); }
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)); } }
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() }); }
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; } } } } }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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)); }
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)); }
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); }
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)); }
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)); }
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)); }