Redesign Shpk tab.

This commit is contained in:
Ottermandias 2023-03-01 18:03:59 +01:00
parent 7ae6d0a348
commit e62b0155d4
8 changed files with 792 additions and 569 deletions

View file

@ -160,7 +160,7 @@ public partial class ModEditWindow
{
tab.NewKeyDefault = key.DefaultValue;
tab.NewKeyId = key.Id;
ret = true;
ret = true;
tab.UpdateShaderKeyLabels();
}
}
@ -382,7 +382,9 @@ public partial class ModEditWindow
var (label, filename) = tab.Samplers[ idx ];
using var tree = ImRaii.TreeNode( label );
if( !tree )
{
return false;
}
ImRaii.TreeNode( filename, ImGuiTreeNodeFlags.Leaf ).Dispose();
var ret = false;
@ -398,7 +400,7 @@ public partial class ModEditWindow
}
ImGui.SetNextItemWidth( ImGuiHelpers.GlobalScale * 150.0f );
if( InputHexUInt16( "Texture Flags", ref tab.Mtrl.Textures[sampler.TextureIndex].Flags,
if( InputHexUInt16( "Texture Flags", ref tab.Mtrl.Textures[ sampler.TextureIndex ].Flags,
disabled ? ImGuiInputTextFlags.ReadOnly : ImGuiInputTextFlags.None ) )
{
ret = true;
@ -409,22 +411,22 @@ public partial class ModEditWindow
if( ImGui.InputInt( "Sampler Flags", ref samplerFlags, 0, 0,
ImGuiInputTextFlags.CharsHexadecimal | ( disabled ? ImGuiInputTextFlags.ReadOnly : ImGuiInputTextFlags.None ) ) )
{
tab.Mtrl.ShaderPackage.Samplers[idx].Flags = ( uint )samplerFlags;
ret = true;
tab.Mtrl.ShaderPackage.Samplers[ idx ].Flags = ( uint )samplerFlags;
ret = true;
}
if( !disabled
&& tab.OrphanedSamplers.Count == 0
&& tab.AliasedSamplerCount == 0
&& tab.AliasedSamplerCount == 0
&& ImGui.Button( "Remove Sampler" ) )
{
tab.Mtrl.Textures = tab.Mtrl.Textures.RemoveItems( sampler.TextureIndex );
tab.Mtrl.Textures = tab.Mtrl.Textures.RemoveItems( sampler.TextureIndex );
tab.Mtrl.ShaderPackage.Samplers = tab.Mtrl.ShaderPackage.Samplers.RemoveItems( idx-- );
for( var i = 0; i < tab.Mtrl.ShaderPackage.Samplers.Length; ++i )
{
if( tab.Mtrl.ShaderPackage.Samplers[i].TextureIndex >= sampler.TextureIndex )
if( tab.Mtrl.ShaderPackage.Samplers[ i ].TextureIndex >= sampler.TextureIndex )
{
--tab.Mtrl.ShaderPackage.Samplers[i].TextureIndex;
--tab.Mtrl.ShaderPackage.Samplers[ i ].TextureIndex;
}
}
@ -438,7 +440,7 @@ public partial class ModEditWindow
private static bool DrawMaterialNewSampler( MtrlTab tab )
{
var (name, id) = tab.MissingSamplers[tab.NewSamplerIdx];
var (name, id) = tab.MissingSamplers[ tab.NewSamplerIdx ];
ImGui.SetNextItemWidth( ImGuiHelpers.GlobalScale * 450.0f );
using( var c = ImRaii.Combo( "##NewSamplerId", $"{name} (ID: 0x{id:X8})" ) )
{
@ -475,14 +477,13 @@ public partial class ModEditWindow
tab.UpdateSamplers();
tab.UpdateTextureLabels();
return true;
}
private static bool DrawMaterialSamplers( MtrlTab tab, bool disabled )
{
if( tab.Mtrl.ShaderPackage.Samplers.Length == 0
&& tab.Mtrl.Textures.Length == 0
&& ( disabled || (tab.AssociatedShpk?.Samplers.All( sampler => sampler.Slot != 2 ) ?? false ) ))
&& ( disabled || ( tab.AssociatedShpk?.Samplers.All( sampler => sampler.Slot != 2 ) ?? false ) ) )
{
return false;
}
@ -493,7 +494,7 @@ public partial class ModEditWindow
return false;
}
var ret = false;
var ret = false;
for( var idx = 0; idx < tab.Mtrl.ShaderPackage.Samplers.Length; ++idx )
{
ret |= DrawMaterialSampler( tab, disabled, ref idx );
@ -511,7 +512,7 @@ public partial class ModEditWindow
}
}
}
else if( !disabled && tab.MissingSamplers.Count > 0 && tab.AliasedSamplerCount == 0 && tab.Mtrl.Textures.Length < 255 )
else if( !disabled && tab.MissingSamplers.Count > 0 && tab.AliasedSamplerCount == 0 && tab.Mtrl.Textures.Length < 255 )
{
ret |= DrawMaterialNewSampler( tab );
}
@ -592,7 +593,7 @@ public partial class ModEditWindow
}
var sb = new StringBuilder( 128 );
sb.Append( $"{prefix}[{firstVector}]{VectorSwizzle( firstComponent, 3 )}" );
sb.Append( $"{prefix}[{firstVector}]{VectorSwizzle( firstComponent, 3 ).TrimEnd()}" );
for( var i = firstVector + 1; i < lastVector; ++i )
{
sb.Append( $", [{i}]" );

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,188 @@
using System;
using System.Collections.Generic;
using Dalamud.Interface.ImGuiFileDialog;
using Dalamud.Utility;
using Lumina.Misc;
using OtterGui;
using Penumbra.GameData.Data;
using Penumbra.GameData.Files;
namespace Penumbra.UI.Classes;
public partial class ModEditWindow
{
private class ShpkTab : IWritable
{
public readonly ShpkFile Shpk;
public string NewMaterialParamName = string.Empty;
public uint NewMaterialParamId = Crc32.Get( string.Empty, 0xFFFFFFFFu );
public short NewMaterialParamStart;
public short NewMaterialParamEnd;
public readonly FileDialogManager FileDialog = ConfigWindow.SetupFileManager();
public readonly string Header;
public readonly string Extension;
public ShpkTab( byte[] bytes )
{
Shpk = new ShpkFile( bytes, true );
Header = $"Shader Package for DirectX {( int )Shpk.DirectXVersion}";
Extension = Shpk.DirectXVersion switch
{
ShpkFile.DxVersion.DirectX9 => ".cso",
ShpkFile.DxVersion.DirectX11 => ".dxbc",
_ => throw new NotImplementedException(),
};
Update();
}
[Flags]
public enum ColorType : byte
{
Unused = 0,
Used = 1,
Continuation = 2,
}
public (string Name, string Tooltip, short Index, ColorType Color)[,] Matrix = null!;
public readonly List< string > MalformedParameters = new();
public readonly HashSet< uint > UsedIds = new(16);
public readonly List< (string Name, short Index) > Orphans = new(16);
public void Update()
{
var materialParams = Shpk.GetConstantById( ShpkFile.MaterialParamsConstantId );
var numParameters = ( ( Shpk.MaterialParamsSize + 0xFu ) & ~0xFu ) >> 4;
Matrix = new (string Name, string Tooltip, short Index, ColorType Color)[numParameters, 4];
MalformedParameters.Clear();
UsedIds.Clear();
foreach( var (param, idx) in Shpk.MaterialParams.WithIndex() )
{
UsedIds.Add( param.Id );
var iStart = param.ByteOffset >> 4;
var jStart = ( param.ByteOffset >> 2 ) & 3;
var iEnd = ( param.ByteOffset + param.ByteSize - 1 ) >> 4;
var jEnd = ( ( param.ByteOffset + param.ByteSize - 1 ) >> 2 ) & 3;
if( ( param.ByteOffset & 0x3 ) != 0 || ( param.ByteSize & 0x3 ) != 0 )
{
MalformedParameters.Add( $"ID: 0x{param.Id:X8}, offset: 0x{param.ByteOffset:X4}, size: 0x{param.ByteSize:X4}" );
continue;
}
if( iEnd >= numParameters )
{
MalformedParameters.Add(
$"{MaterialParamRangeName( materialParams?.Name ?? string.Empty, param.ByteOffset >> 2, param.ByteSize >> 2 )} (ID: 0x{param.Id:X8})" );
continue;
}
for( var i = iStart; i <= iEnd; ++i )
{
var end = i == iEnd ? jEnd : 3;
for( var j = i == iStart ? jStart : 0; j <= end; ++j )
{
var tt = $"{MaterialParamRangeName( materialParams?.Name ?? string.Empty, param.ByteOffset >> 2, param.ByteSize >> 2 ).Item1} (ID: 0x{param.Id:X8})";
Matrix[ i, j ] = ( $"0x{param.Id:X8}", tt, ( short )idx, 0 );
}
}
}
UpdateOrphans( materialParams );
UpdateColors( materialParams );
}
public void UpdateOrphanStart( int orphanStart )
{
var oldEnd = Orphans.Count > 0 ? Orphans[ NewMaterialParamEnd ].Index : -1;
UpdateOrphanStart( orphanStart, oldEnd );
}
private void UpdateOrphanStart( int orphanStart, int oldEnd )
{
var count = Math.Min( NewMaterialParamEnd - NewMaterialParamStart + orphanStart + 1, Orphans.Count );
NewMaterialParamStart = ( short )orphanStart;
var current = Orphans[ NewMaterialParamStart ].Index;
for( var i = NewMaterialParamStart; i < count; ++i )
{
var next = Orphans[ i ].Index;
if( current++ != next )
{
NewMaterialParamEnd = ( short )( i - 1 );
return;
}
if( next == oldEnd )
{
NewMaterialParamEnd = i;
return;
}
}
NewMaterialParamEnd = ( short )( count - 1 );
}
private void UpdateOrphans( ShpkFile.Resource? materialParams )
{
var oldStart = Orphans.Count > 0 ? Orphans[ NewMaterialParamStart ].Index : -1;
var oldEnd = Orphans.Count > 0 ? Orphans[ NewMaterialParamEnd ].Index : -1;
Orphans.Clear();
short newMaterialParamStart = 0;
for( var i = 0; i < Matrix.GetLength( 0 ); ++i )
for( var j = 0; j < 4; ++j )
{
if( !Matrix[ i, j ].Name.IsNullOrEmpty() )
{
continue;
}
Matrix[ i, j ] = ( "(none)", string.Empty, -1, 0 );
var linear = ( short )( 4 * i + j );
if( oldStart == linear )
{
newMaterialParamStart = ( short )Orphans.Count;
}
Orphans.Add( ( $"{materialParams?.Name ?? string.Empty}{MaterialParamName( false, linear )}", linear ) );
}
if( Orphans.Count == 0 )
{
return;
}
UpdateOrphanStart( newMaterialParamStart, oldEnd );
}
private void UpdateColors( ShpkFile.Resource? materialParams )
{
var lastIndex = -1;
for( var i = 0; i < Matrix.GetLength( 0 ); ++i )
{
var usedComponents = ( materialParams?.Used?[ i ] ?? DisassembledShader.VectorComponents.All ) | ( materialParams?.UsedDynamically ?? 0 );
for( var j = 0; j < 4; ++j )
{
var color = ( ( byte )usedComponents & ( 1 << j ) ) != 0
? ColorType.Used
: 0;
if( Matrix[ i, j ].Index == lastIndex || Matrix[ i, j ].Index < 0 )
{
color |= ColorType.Continuation;
}
lastIndex = Matrix[ i, j ].Index;
Matrix[ i, j ].Color = color;
}
}
}
public bool Valid
=> Shpk.Valid;
public byte[] Write()
=> Shpk.Write();
}
}

View file

@ -580,11 +580,11 @@ public partial class ModEditWindow : Window, IDisposable
DrawModelPanel,
() => _mod?.ModPath.FullName ?? string.Empty,
null );
_shaderPackageTab = new FileEditor< ShpkFile >( "Shader Packages", ".shpk",
_shaderPackageTab = new FileEditor< ShpkTab >( "Shader Packages", ".shpk",
() => _editor?.ShpkFiles ?? Array.Empty< Editor.FileRegistry >(),
DrawShaderPackagePanel,
() => _mod?.ModPath.FullName ?? string.Empty,
bytes => new ShpkFile( bytes, true ) );
bytes => new ShpkTab( bytes ) );
_center = new CombinedTexture( _left, _right );
}