mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 10:17:22 +01:00
Fix material editor and improve pinning logic
This commit is contained in:
parent
6959789aa7
commit
f13fa3e589
6 changed files with 110 additions and 71 deletions
|
|
@ -1 +1 @@
|
|||
Subproject commit e717a66f33b0656a7c5c971ffa2f63fd96477d94
|
||||
Subproject commit b6b91f846096d15276b728ba2078f27b95317d15
|
||||
|
|
@ -288,7 +288,7 @@ public class MaterialExporter
|
|||
const uint valueFace = 0x6E5B8F10;
|
||||
|
||||
var isFace = material.Mtrl.ShaderPackage.ShaderKeys
|
||||
.Any(key => key is { Category: categoryHairType, Value: valueFace });
|
||||
.Any(key => key is { Key: categoryHairType, Value: valueFace });
|
||||
|
||||
var normal = material.Textures[TextureUsage.SamplerNormal];
|
||||
var mask = material.Textures[TextureUsage.SamplerMask];
|
||||
|
|
@ -363,7 +363,7 @@ public class MaterialExporter
|
|||
|
||||
// Face is the default for the skin shader, so a lack of skin type category is also correct.
|
||||
var isFace = !material.Mtrl.ShaderPackage.ShaderKeys
|
||||
.Any(key => key.Category == categorySkinType && key.Value != valueFace);
|
||||
.Any(key => key.Key == categorySkinType && key.Value != valueFace);
|
||||
|
||||
// TODO: There's more nuance to skin than this, but this should be enough for a baseline reference.
|
||||
// TODO: Specular?
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ public partial class MtrlTab
|
|||
|
||||
private bool DrawColorTableSection(bool disabled)
|
||||
{
|
||||
if (!_shpkLoading && !SamplerIds.Contains(ShpkFile.TableSamplerId) || Mtrl.Table == null)
|
||||
if (!_shpkLoading && !TextureIds.Contains(ShpkFile.TableSamplerId) || Mtrl.Table == null)
|
||||
return false;
|
||||
|
||||
ImGui.Dummy(new Vector2(ImGui.GetTextLineHeight() / 2));
|
||||
|
|
|
|||
|
|
@ -216,7 +216,7 @@ public partial class MtrlTab
|
|||
else
|
||||
foreach (var (key, index) in Mtrl.ShaderPackage.ShaderKeys.WithIndex())
|
||||
{
|
||||
var keyName = Names.KnownNames.TryResolve(key.Category);
|
||||
var keyName = Names.KnownNames.TryResolve(key.Key);
|
||||
var valueName = keyName.WithKnownSuffixes().TryResolve(Names.KnownNames, key.Value);
|
||||
_shaderKeys.Add((keyName.ToString(), index, string.Empty, true, [(valueName.ToString(), key.Value, string.Empty)]));
|
||||
}
|
||||
|
|
@ -366,6 +366,7 @@ public partial class MtrlTab
|
|||
ret = true;
|
||||
_associatedShpk = null;
|
||||
_loadedShpkPath = FullPath.Empty;
|
||||
UnpinResources(true);
|
||||
LoadShpk(FindAssociatedShpk(out _, out _));
|
||||
}
|
||||
|
||||
|
|
@ -442,8 +443,8 @@ public partial class MtrlTab
|
|||
{
|
||||
using var font = ImRaii.PushFont(UiBuilder.MonoFont, monoFont);
|
||||
ref var key = ref Mtrl.ShaderPackage.ShaderKeys[index];
|
||||
using var id = ImUtf8.PushId((int)key.Category);
|
||||
var shpkKey = _associatedShpk?.GetMaterialKeyById(key.Category);
|
||||
using var id = ImUtf8.PushId((int)key.Key);
|
||||
var shpkKey = _associatedShpk?.GetMaterialKeyById(key.Key);
|
||||
var currentValue = key.Value;
|
||||
var (currentLabel, _, currentDescription) =
|
||||
values.FirstOrNull(v => v.Value == currentValue) ?? ($"0x{currentValue:X8}", currentValue, string.Empty);
|
||||
|
|
@ -459,6 +460,7 @@ public partial class MtrlTab
|
|||
{
|
||||
key.Value = value;
|
||||
ret = true;
|
||||
UnpinResources(false);
|
||||
Update();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ using ImGuiNET;
|
|||
using OtterGui;
|
||||
using OtterGui.Raii;
|
||||
using OtterGui.Text;
|
||||
using Penumbra.GameData;
|
||||
using Penumbra.GameData.Files.MaterialStructs;
|
||||
using Penumbra.String.Classes;
|
||||
using static Penumbra.GameData.Files.MaterialStructs.SamplerFlags;
|
||||
|
|
@ -16,18 +15,22 @@ public partial class MtrlTab
|
|||
public readonly List<(string Label, int TextureIndex, int SamplerIndex, string Description, bool MonoFont)> Textures = new(4);
|
||||
|
||||
public readonly HashSet<int> UnfoldedTextures = new(4);
|
||||
public readonly HashSet<uint> TextureIds = new(16);
|
||||
public readonly HashSet<uint> SamplerIds = new(16);
|
||||
public float TextureLabelWidth;
|
||||
private bool _samplersPinned;
|
||||
|
||||
private void UpdateTextures()
|
||||
{
|
||||
Textures.Clear();
|
||||
TextureIds.Clear();
|
||||
SamplerIds.Clear();
|
||||
if (_associatedShpk == null)
|
||||
{
|
||||
TextureIds.UnionWith(Mtrl.ShaderPackage.Samplers.Select(sampler => sampler.SamplerId));
|
||||
SamplerIds.UnionWith(Mtrl.ShaderPackage.Samplers.Select(sampler => sampler.SamplerId));
|
||||
if (Mtrl.Table != null)
|
||||
SamplerIds.Add(TableSamplerId);
|
||||
TextureIds.Add(TableSamplerId);
|
||||
|
||||
foreach (var (sampler, index) in Mtrl.ShaderPackage.Samplers.WithIndex())
|
||||
Textures.Add(($"0x{sampler.SamplerId:X8}", sampler.TextureIndex, index, string.Empty, true));
|
||||
|
|
@ -35,31 +38,39 @@ public partial class MtrlTab
|
|||
else
|
||||
{
|
||||
foreach (var index in _vertexShaders)
|
||||
SamplerIds.UnionWith(_associatedShpk.VertexShaders[index].Samplers.Select(sampler => sampler.Id));
|
||||
foreach (var index in _pixelShaders)
|
||||
SamplerIds.UnionWith(_associatedShpk.PixelShaders[index].Samplers.Select(sampler => sampler.Id));
|
||||
if (!_shadersKnown)
|
||||
{
|
||||
SamplerIds.UnionWith(Mtrl.ShaderPackage.Samplers.Select(sampler => sampler.SamplerId));
|
||||
if (Mtrl.Table != null)
|
||||
SamplerIds.Add(TableSamplerId);
|
||||
TextureIds.UnionWith(_associatedShpk.VertexShaders[index].Textures.Select(texture => texture.Id));
|
||||
SamplerIds.UnionWith(_associatedShpk.VertexShaders[index].Samplers.Select(sampler => sampler.Id));
|
||||
}
|
||||
|
||||
foreach (var samplerId in SamplerIds)
|
||||
foreach (var index in _pixelShaders)
|
||||
{
|
||||
var shpkSampler = _associatedShpk.GetSamplerById(samplerId);
|
||||
if (shpkSampler is not { Slot: 2 })
|
||||
TextureIds.UnionWith(_associatedShpk.PixelShaders[index].Textures.Select(texture => texture.Id));
|
||||
SamplerIds.UnionWith(_associatedShpk.PixelShaders[index].Samplers.Select(sampler => sampler.Id));
|
||||
}
|
||||
|
||||
if (_samplersPinned || !_shadersKnown)
|
||||
{
|
||||
TextureIds.UnionWith(Mtrl.ShaderPackage.Samplers.Select(sampler => sampler.SamplerId));
|
||||
if (Mtrl.Table != null)
|
||||
TextureIds.Add(TableSamplerId);
|
||||
}
|
||||
|
||||
foreach (var textureId in TextureIds)
|
||||
{
|
||||
var shpkTexture = _associatedShpk.GetTextureById(textureId);
|
||||
if (shpkTexture is not { Slot: 2 })
|
||||
continue;
|
||||
|
||||
var dkData = TryGetShpkDevkitData<DevkitSampler>("Samplers", samplerId, true);
|
||||
var dkData = TryGetShpkDevkitData<DevkitSampler>("Samplers", textureId, true);
|
||||
var hasDkLabel = !string.IsNullOrEmpty(dkData?.Label);
|
||||
|
||||
var sampler = Mtrl.GetOrAddSampler(samplerId, dkData?.DefaultTexture ?? string.Empty, out var samplerIndex);
|
||||
Textures.Add((hasDkLabel ? dkData!.Label : shpkSampler.Value.Name, sampler.TextureIndex, samplerIndex,
|
||||
var sampler = Mtrl.GetOrAddSampler(textureId, dkData?.DefaultTexture ?? string.Empty, out var samplerIndex);
|
||||
Textures.Add((hasDkLabel ? dkData!.Label : shpkTexture.Value.Name, sampler.TextureIndex, samplerIndex,
|
||||
dkData?.Description ?? string.Empty, !hasDkLabel));
|
||||
}
|
||||
|
||||
if (SamplerIds.Contains(TableSamplerId))
|
||||
if (TextureIds.Contains(TableSamplerId))
|
||||
Mtrl.Table ??= new ColorTable();
|
||||
}
|
||||
|
||||
|
|
@ -205,6 +216,8 @@ public partial class MtrlTab
|
|||
ret = true;
|
||||
}
|
||||
|
||||
if (SamplerIds.Contains(sampler.SamplerId))
|
||||
{
|
||||
ref var samplerFlags = ref Wrap(ref sampler.Flags);
|
||||
|
||||
ImGui.SetNextItemWidth(UiHelpers.Scale * 100.0f);
|
||||
|
|
@ -217,7 +230,8 @@ public partial class MtrlTab
|
|||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
ImUtf8.LabeledHelpMarker("U Address Mode"u8, "Method to use for resolving a U texture coordinate that is outside the 0 to 1 range.");
|
||||
ImUtf8.LabeledHelpMarker("U Address Mode"u8,
|
||||
"Method to use for resolving a U texture coordinate that is outside the 0 to 1 range.");
|
||||
|
||||
ImGui.SetNextItemWidth(UiHelpers.Scale * 100.0f);
|
||||
addressMode = samplerFlags.VAddressMode;
|
||||
|
|
@ -229,7 +243,8 @@ public partial class MtrlTab
|
|||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
ImUtf8.LabeledHelpMarker("V Address Mode"u8, "Method to use for resolving a V texture coordinate that is outside the 0 to 1 range.");
|
||||
ImUtf8.LabeledHelpMarker("V Address Mode"u8,
|
||||
"Method to use for resolving a V texture coordinate that is outside the 0 to 1 range.");
|
||||
|
||||
var lodBias = samplerFlags.LodBias;
|
||||
ImGui.SetNextItemWidth(UiHelpers.Scale * 100.0f);
|
||||
|
|
@ -256,6 +271,11 @@ public partial class MtrlTab
|
|||
ImGui.SameLine();
|
||||
ImUtf8.LabeledHelpMarker("Minimum Level of Detail"u8,
|
||||
"Most detailed mipmap level to use.\n\n0 is the full-sized texture, 1 is the half-sized texture, 2 is the quarter-sized texture, and so on.\n15 will forcibly reduce the texture to its smallest mipmap.");
|
||||
}
|
||||
else
|
||||
{
|
||||
ImUtf8.Text("This texture does not have a dedicated sampler."u8);
|
||||
}
|
||||
|
||||
using var t = ImUtf8.TreeNode("Advanced Settings"u8);
|
||||
if (!t)
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ public sealed partial class MtrlTab : IWritable, IDisposable
|
|||
Mtrl = file;
|
||||
FilePath = filePath;
|
||||
Writable = writable;
|
||||
_samplersPinned = true;
|
||||
_associatedBaseDevkit = TryLoadShpkDevkit("_base", out _loadedBaseDevkitPathName);
|
||||
Update();
|
||||
LoadShpk(FindAssociatedShpk(out _, out _));
|
||||
|
|
@ -172,6 +173,22 @@ public sealed partial class MtrlTab : IWritable, IDisposable
|
|||
Widget.DrawHexViewer(Mtrl.AdditionalData);
|
||||
}
|
||||
|
||||
private void UnpinResources(bool all)
|
||||
{
|
||||
_samplersPinned = false;
|
||||
|
||||
if (!all)
|
||||
return;
|
||||
|
||||
var keys = Mtrl.ShaderPackage.ShaderKeys;
|
||||
for (var i = 0; i < keys.Length; i++)
|
||||
keys[i].Pinned = false;
|
||||
|
||||
var constants = Mtrl.ShaderPackage.Constants;
|
||||
for (var i = 0; i < constants.Length; i++)
|
||||
constants[i].Pinned = false;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
UpdateShaders();
|
||||
|
|
@ -192,7 +209,7 @@ public sealed partial class MtrlTab : IWritable, IDisposable
|
|||
public byte[] Write()
|
||||
{
|
||||
var output = Mtrl.Clone();
|
||||
output.GarbageCollect(_associatedShpk, SamplerIds);
|
||||
output.GarbageCollect(_associatedShpk, TextureIds);
|
||||
|
||||
return output.Write();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue