Basic material serialisation

This commit is contained in:
Simon Lübeß
2023-03-05 16:38:50 +01:00
parent 2324ae852d
commit 2ce357cd12
13 changed files with 772 additions and 373 deletions
+284 -23
View File
@@ -7,11 +7,26 @@ using GlitchyEngine;
using GlitchyEngine.Renderer;
using ImGui;
using GlitchyEngine.Math;
using System.Diagnostics;
using Bon.Integrated;
namespace GlitchyEditor.Assets;
class MaterialAssetPropertiesEditor : AssetPropertiesEditor
{
public static bool TryGetValue(Dictionary<String, Variant> parameters, String name, out Variant value)
{
if (parameters.TryGetValue(name, let param))
{
value = param;
return true;
}
value = ?;
return false;
}
mixin DropAssetTarget<T>() where T : Asset
{
Asset asset = null;
@@ -83,18 +98,6 @@ class MaterialAssetPropertiesEditor : AssetPropertiesEditor
private void ShowVariables(Material material, Effect effect)
{
bool TryGetValue(Dictionary<String, Variant> parameters, String name, out Variant value)
{
if (parameters.TryGetValue(name, let param))
{
value = param;
return true;
}
value = ?;
return false;
}
for (let (name, arguments) in effect.[Friend]_variableDescriptions)
{
@@ -194,16 +197,123 @@ class MaterialAssetLoaderConfig : AssetLoaderConfig
}
[BonTarget]
public enum VariableValue
{
case Float(float Value);
case Float2(Vector2 Value);
case Float3(Vector3 Value);
case Float4(Vector4 Value);
case Int(int Value);
case Int2(Int2 Value);
case Int3(Int3 Value);
case Int4(Int4 Value);
case ColorRGB(ColorRGB Value);
case ColorRGBA(ColorRGBA Value);
case None;
/*static this()
{
gBonEnv.typeHandlers.Add(typeof(Self),
((.)new => VariableValueSerialize, (.)new => VariableValueDeserialize));
}
static void VariableValueSerialize(BonWriter writer, ValueView value, BonEnvironment env)
{
Log.EngineLogger.Assert(value.type == typeof(Self));
let variableValue = value.Get<Self>();
writer.Type(variableValue)
using (writer.ObjectBlock())
{
Serialize.Value(writer, nameof(MaterialFile.Effect), materialFile.Effect, env);
Serialize.Value(writer, nameof(MaterialFile.Textures), materialFile.Textures, env);
}
}
static Result<void> VariableValueDeserialize(BonReader reader, ValueView val, BonEnvironment env)
{
return .Ok;
}*/
}
[BonTarget]
class MaterialFile
{
public String Effect ~ delete _;
public Dictionary<String, String> Textures ~ DeleteDictionaryAndKeysAndValues!(_);
//public Dictionary<String, Object> Variables;
public Dictionary<String, VariableValue> Variables ~
{
if (_ != null)
{
for (var entry in _)
{
delete entry.key;
//delete entry.value;
/*if (entry.value.HasValue)
entry.value->Dispose();*/
}
delete _;
}
};
/*static this()
{
gBonEnv.typeHandlers.Add(typeof(Self),
((.)new => MaterialSerialize, (.)new => MaterialDeserialize));
}
static void MaterialSerialize(BonWriter writer, ValueView value, BonEnvironment env)
{
Log.EngineLogger.Assert(value.type == typeof(Self));
let materialFile = value.Get<Self>();
using (writer.ObjectBlock())
{
Serialize.Value(writer, nameof(MaterialFile.Effect), materialFile.Effect, env);
Serialize.Value(writer, nameof(MaterialFile.Textures), materialFile.Textures, env);
}
}
private static void SerializeVariablesDictionary(BonWriter writer, MaterialFile materialFile, BonEnvironment env)
{
using (writer.ArrayBlock())
{
for (let (name, value) in materialFile.Variables)
{
let keyVal = ValueView(typeof(String), name);
Serialize.Value(writer, keyVal, env);
writer.Pair();
ValueView valueVal;// = ValueView(, entriesPtr + (currentIndex * entryStride) + entryValueOffset);
switch(value.GetType())
{
case typeof(ColorRGBA):
writer.Identifier("ColorRGBA");
default:
}
Serialize.Value(writer, valueVal, env);
}
}
}
static Result<void> MaterialDeserialize(BonReader reader, ValueView val, BonEnvironment env)
{
return .Ok;
}*/
}
class MaterialAssetLoader : IAssetLoader //, IReloadingAssetLoader
class MaterialAssetLoader : IAssetLoader, IAssetSaver //, IReloadingAssetLoader
{
private static readonly List<StringView> _fileExtensions = new .(){".mat"} ~ delete _;
@@ -225,10 +335,11 @@ class MaterialAssetLoader : IAssetLoader //, IReloadingAssetLoader
MaterialFile materialFile = scope .();
var result = Bon.Deserialize<MaterialFile>(ref materialFile, text);
if (result case .Err)
{
Log.EngineLogger.Error("Failed to load material.");
Debug.SafeBreak();
return null;
// TODO: return error material
}
@@ -243,7 +354,7 @@ class MaterialAssetLoader : IAssetLoader //, IReloadingAssetLoader
{
if (texture == null)
{
Log.EngineLogger.Error("Failed to load texture.");
Log.EngineLogger.Error($"Failed to load texture \"{textureIdentifier}\".");
// TODO: LoadAsset should return an error texture.
}
@@ -253,17 +364,167 @@ class MaterialAssetLoader : IAssetLoader //, IReloadingAssetLoader
fx.ReleaseRef();
/*for (let (slotName, textureIdentifier) in materialFile.Variables)
for (let (slotName, variableValue) in materialFile.Variables)
{
if (texture == null)
switch (variableValue)
{
Log.EngineLogger.Error("Failed to load texture.");
// TODO: LoadAsset should return an error texture.
case .ColorRGBA(let value):
material.SetVariable(slotName, value);
case .ColorRGB(let value):
material.SetVariable(slotName, value);
case .Float(let value):
material.SetVariable(slotName, value);
case .Float2(let value):
material.SetVariable(slotName, value);
case .Float3(let value):
material.SetVariable(slotName, value);
case .Float4(let value):
material.SetVariable(slotName, value);
case .None:
default:
Log.EngineLogger.Error("Errorre");
}
material.SetVariable(slotName, );
}*/
}
return material; //ModelLoader.LoadMesh(file, subAsset.Value, 0);
return material;
}
public Result<void> EditorSaveAsset(Stream file, Asset asset, AssetLoaderConfig config, StringView assetIdentifier, StringView? subAsset, IContentManager contentManager)
{
Material material = asset as Material;
if (material == null)
{
Log.EngineLogger.Error("Asset must be a Material!");
return .Err;
}
MaterialFile materialFile = scope .();
materialFile.Effect = new String(material.Effect.Identifier);
materialFile.Textures = new .();
materialFile.Variables = new .();
//material.SetTexture();
for (let (slotName, textureViewBinding) in material.[Friend]_textures)
{
//materialFile.Textures.Add(slotName, textureViewBinding.)
}
Effect effect = material.Effect;
if (effect == null)
return .Ok;
for (let (name, arguments) in effect.[Friend]_variableDescriptions)
{
VariableValue variableValue = .None;
//Object variantValue = null;
let variable = effect.Variables[name];
bool hasPreviewType = MaterialAssetPropertiesEditor.TryGetValue(arguments, "Type", var previewType);
if (hasPreviewType && previewType.Get<String>() == "Color")
{
Log.EngineLogger.AssertDebug(variable.Type == .Float && variable.Rows == 1);
if (variable.Columns == 3)
{
material.GetVariable<ColorRGB>(variable.Name, var value);
value = ColorRGB.LinearToSRGB((ColorRGB)value);
//variantValue = new box value;
variableValue = .ColorRGB(value);
}
else if (variable.Columns == 4)
{
material.GetVariable<ColorRGBA>(variable.Name, var value);
value = ColorRGBA.LinearToSRGB((ColorRGBA)value);
variableValue = .ColorRGBA(value);
//variantValue = new box value;
}
}
else if (variable.Type == .Float && variable.Rows == 1)
{
switch (variable.Columns)
{
case 1:
material.GetVariable<float>(variable.Name, let value);
variableValue = .Float(value);
case 2:
material.GetVariable<Vector2>(variable.Name, let value);
variableValue = .Float2(value);
case 3:
material.GetVariable<Vector3>(variable.Name, let value);
variableValue = .Float3(value);
case 4:
material.GetVariable<Vector4>(variable.Name, let value);
variableValue = .Float4(value);
}
/*bool hasMin = TryGetValue(arguments, "Min", var min);
bool hasMax = TryGetValue(arguments, "Max", var max);
for (int r < variable.Rows)
{
switch (variable.Columns)
{
case 1:
material.GetVariable<float>(variable.Name, var value);
float[1] minV = hasMin ? min.Get<float[1]>() : .(float.MinValue);
float[1] maxV = hasMax ? max.Get<float[1]>() : .(float.MaxValue);
if (ImGui.EditVector<1>(displayName, ref *(float[1]*)&value, .(), 0.1f, 100.0f, minV, maxV))
material.SetVariable(variable.Name, value);
case 2:
material.GetVariable<Vector2>(variable.Name, var value);
Vector2 minV = hasMin ? min.Get<Vector2>() : .(float.MinValue);
Vector2 maxV = hasMax ? max.Get<Vector2>() : .(float.MaxValue);
if (ImGui.EditVector2(displayName, ref value, .Zero, 0.1f, 100.0f, minV, maxV))
material.SetVariable(variable.Name, value);
case 3:
material.GetVariable<Vector3>(variable.Name, var value);
Vector3 minV = hasMin ? min.Get<Vector3>() : .(float.MinValue);
Vector3 maxV = hasMax ? max.Get<Vector3>() : .(float.MaxValue);
if (ImGui.EditVector3(displayName, ref value, .Zero, 0.1f, 100.0f, minV, maxV))
material.SetVariable(variable.Name, value);
case 4:
material.GetVariable<Vector4>(variable.Name, var value);
Vector4 minV = hasMin ? min.Get<Vector4>() : .(float.MinValue);
Vector4 maxV = hasMax ? max.Get<Vector4>() : .(float.MaxValue);
if (ImGui.EditVector4(displayName, ref value, .Zero, 0.1f, 100.0f, minV, maxV))
material.SetVariable(variable.Name, value);
}
}*/
}
materialFile.Variables.Add(name, variableValue);
}
String text = scope .();
gBonEnv.serializeFlags |= .IncludeDefault | .Verbose;
Bon.Serialize<MaterialFile>(materialFile, text);
StreamWriter writer = scope .(file, .UTF8, 1024);
writer.Write(text);
return .Ok;
}
}