Handle EngineBuffers, Preview Names and variable editor types for materials

This commit is contained in:
Simon Lübeß
2025-03-22 23:40:43 +01:00
parent 77a7a04637
commit 5e50d75eb9
13 changed files with 696 additions and 431 deletions
@@ -9,12 +9,14 @@ namespace GlitchyEditor.Assets.Editors;
class MaterialEditor
{
public static void ShowEditor(AssetFile assetFile)
public static bool ShowEditor(AssetFile assetFile)
{
bool isDirty = false;
let material = assetFile.LoadedAsset as Material;
if (material == null)
return;
return isDirty;
ImGui.PropertyTableStartNewProperty("Base Material");
@@ -30,8 +32,15 @@ class MaterialEditor
ImGui.PropertyTableStartNewRow();
if (ImGui.CollapsingHeader("Parameters", .DefaultOpen | .AllowOverlap | .Framed | .SpanFullWidth | .SpanAllColumns))
{
String prettyVariableName = scope .();
for (let (variableName, bufferVariable) in material.Variables)
{
// Don't show engine buffer variables
if (!bufferVariable.ConstantBuffer.EngineBufferName.IsEmpty)
{
continue;
}
ImGui.PushID(variableName);
ImGui.PropertyTableStartNewRow();
@@ -47,47 +56,90 @@ class MaterialEditor
ImGui.SameLine();
StringView displayName = variableName;
StringView displayName = bufferVariable.PreviewName;
if (displayName.IsEmpty)
{
ToPrettyName(variableName, prettyVariableName);
displayName = prettyVariableName;
}
ImGui.PropertyTableName(displayName);
// TODO: Somehow pass display name and type from imported shader to here!
switch (bufferVariable.ElementType)
bool handled = false;
switch (bufferVariable.EditorTypeName)
{
case .Float:
// TODO: min and max values specified in shader
// TODO: support drag and enter number (specified in shader)
//for (int r < bufferVariable.Rows)
if (bufferVariable.Rows == 1)
case "Color", "ColorHDR":
if (bufferVariable.ElementType != .Float || bufferVariable.Rows != 1 ||
bufferVariable.Columns < 3)
{
switch (bufferVariable.Columns)
break;
}
ImGui.ColorEditFlags flags = .None;
if (_ == "ColorHDR")
{
flags |= .HDR | .Float;
}
if (bufferVariable.Columns == 3)
{
material.GetVariable<float3>(bufferVariable.Name, var value);
if (ImGui.ColorEdit3("", ref *(float[3]*)&value, flags))
material.SetVariable(bufferVariable.Name, value);
}
else if (bufferVariable.Columns == 4)
{
material.GetVariable<float4>(bufferVariable.Name, var value);
if (ImGui.ColorEdit4("", ref *(float[4]*)&value, flags))
material.SetVariable(bufferVariable.Name, value);
}
handled = true;
}
if (!handled)
{
switch (bufferVariable.ElementType)
{
case .Float:
// TODO: min and max values specified in shader
// TODO: support drag and enter number (specified in shader)
//for (int r < bufferVariable.Rows)
if (bufferVariable.Rows == 1)
{
case 1:
material.GetVariable<float>(bufferVariable.Name, var value);
//float[1] minV = hasMin ? min.Get<float[1]>() : .(float.MinValue);
//float[1] maxV = hasMax ? max.Get<float[1]>() : .(float.MaxValue);
switch (bufferVariable.Columns)
{
case 1:
material.GetVariable<float>(bufferVariable.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.VectorEditor<1>("", ref *(float[1]*)&value, .(), 0.1f /*, minV, maxV*/))
material.SetVariable(bufferVariable.Name, value);
case 2:
material.GetVariable<float2>(bufferVariable.Name, var value);
if (ImGui.Float2Editor("", ref value, .Zero, 0.1f, 100.0f))
material.SetVariable(bufferVariable.Name, value);
case 3:
material.GetVariable<float3>(bufferVariable.Name, var value);
if (ImGui.Float3Editor("", ref value, .Zero, 0.1f, 100.0f))
material.SetVariable(bufferVariable.Name, value);
case 4:
material.GetVariable<float4>(bufferVariable.Name, var value);
if (ImGui.Float4Editor("", ref value, .Zero, 0.1f, 100.0f))
material.SetVariable(bufferVariable.Name, value);
if (ImGui.VectorEditor<1>("", ref *(float[1]*)&value, .(), 0.1f /*, minV, maxV*/))
material.SetVariable(bufferVariable.Name, value);
case 2:
material.GetVariable<float2>(bufferVariable.Name, var value);
if (ImGui.Float2Editor("", ref value, .Zero, 0.1f, 100.0f))
material.SetVariable(bufferVariable.Name, value);
case 3:
material.GetVariable<float3>(bufferVariable.Name, var value);
if (ImGui.Float3Editor("", ref value, .Zero, 0.1f, 100.0f))
material.SetVariable(bufferVariable.Name, value);
case 4:
material.GetVariable<float4>(bufferVariable.Name, var value);
if (ImGui.Float4Editor("", ref value, .Zero, 0.1f, 100.0f))
material.SetVariable(bufferVariable.Name, value);
}
}
default:
ImGui.TextUnformatted(scope $"Element Type {_} not supported");
}
default:
ImGui.TextUnformatted(scope $"Element Type {_} not supported");
}
ImGui.EndDisabled();
@@ -99,6 +151,7 @@ class MaterialEditor
ImGui.PropertyTableStartNewRow();
if (ImGui.CollapsingHeader("Textures", .DefaultOpen | .AllowOverlap | .Framed | .SpanFullWidth | .SpanAllColumns))
{
String prettyVariableName = scope .();
for (var (textureName, texture) in ref material.Textures)
{
ImGui.PushID(textureName);
@@ -116,7 +169,17 @@ class MaterialEditor
ImGui.SameLine();
ImGui.PropertyTableName(textureName);
// TODO: Preview Name for textures
StringView displayName = "";//texture.PreviewName;
if (displayName.IsEmpty)
{
ToPrettyName(textureName, prettyVariableName);
displayName = prettyVariableName;
}
ImGui.PropertyTableName(displayName);
if (ComponentEditWindow.ShowAssetDropTarget<Texture>(ref texture.TextureHandle))
{
@@ -128,6 +191,8 @@ class MaterialEditor
ImGui.PopID();
}
}
return isDirty;
}
private static bool DrawLockButton(bool isLocked)
@@ -166,4 +231,70 @@ class MaterialEditor
return result;
}
/// <summary>
/// Converts a variable name to a pretty name as good as reasonably possible.
/// </summary>
/// <param name="uglyName">The name of a variable to prettify.</param>
/// <returns>The pretty string.</returns>
public static void ToPrettyName(StringView uglyName, String outPrettyName)
{
outPrettyName.PrepareBuffer(uglyName.Length);
outPrettyName.Clear();
bool wasUpper = false;
bool inWord = false;
bool inNumber = false;
for (char8 c in uglyName)
{
if (c.IsLetter)
{
if (inNumber)
{
outPrettyName.Append(' ');
inNumber = false;
}
bool newWord = !inWord;
if (c.IsUpper && !wasUpper)
{
newWord = true;
wasUpper = true;
if (inWord)
{
outPrettyName.Append(' ');
}
}
else if (c.IsLower)
{
wasUpper = false;
}
outPrettyName.Append(newWord ? c.ToUpper : c.ToLower);
inWord = true;
}
else if (c.IsDigit)
{
if (inWord)
{
outPrettyName.Append(' ');
inWord = false;
inNumber = true;
}
outPrettyName.Append(c);
}
else if (inWord || inNumber)
{
outPrettyName.Append(' ');
inWord = false;
inNumber = false;
wasUpper = false;
}
}
}
}