This commit is contained in:
Ottermandias 2022-09-01 17:05:20 +02:00
parent 6b76337ec4
commit 8aec63d0be

View file

@ -22,7 +22,7 @@ using Image = SixLabors.ImageSharp.Image;
namespace Penumbra.UI.Classes; namespace Penumbra.UI.Classes;
public struct Texture : IDisposable public class Texture : IDisposable
{ {
// Path to the file we tried to load. // Path to the file we tried to load.
public string Path = string.Empty; public string Path = string.Empty;
@ -44,6 +44,28 @@ public struct Texture : IDisposable
public Texture() public Texture()
{ } { }
public void Draw( Vector2 size )
{
if( TextureWrap != null )
{
ImGui.TextUnformatted( $"Image Dimensions: {TextureWrap.Width} x {TextureWrap.Height}" );
size = size.X < TextureWrap.Width
? size with { Y = TextureWrap.Height * size.X / TextureWrap.Width }
: new Vector2( TextureWrap.Width, TextureWrap.Height );
ImGui.Image( TextureWrap.ImGuiHandle, size );
}
else if( LoadError != null )
{
ImGui.TextUnformatted( "Could not load file:" );
ImGuiUtil.TextColored( Colors.RegexWarningBorder, LoadError.ToString() );
}
else
{
ImGui.Dummy( size );
}
}
private void Clean() private void Clean()
{ {
RGBAPixels = Array.Empty< byte >(); RGBAPixels = Array.Empty< byte >();
@ -51,47 +73,88 @@ public struct Texture : IDisposable
TextureWrap = null; TextureWrap = null;
( BaseImage as IDisposable )?.Dispose(); ( BaseImage as IDisposable )?.Dispose();
BaseImage = null; BaseImage = null;
Loaded?.Invoke( false );
} }
public void Dispose() public void Dispose()
=> Clean(); => Clean();
public bool Load( string path ) public event Action< bool >? Loaded;
private void Load( string path )
{ {
_tmpPath = null;
if( path == Path ) if( path == Path )
{ {
return false; return;
} }
Path = path; Path = path;
Clean(); Clean();
return System.IO.Path.GetExtension( Path ) switch try
{ {
".dds" => LoadDds(), var _ = System.IO.Path.GetExtension( Path ) switch
".png" => LoadPng(), {
".tex" => LoadTex(), ".dds" => LoadDds(),
_ => true, ".png" => LoadPng(),
}; ".tex" => LoadTex(),
_ => true,
};
Loaded?.Invoke( true );
}
catch( Exception e )
{
LoadError = e;
Clean();
}
} }
private bool LoadDds() private bool LoadDds()
=> true; {
var scratch = ScratchImage.LoadDDS( Path );
BaseImage = scratch;
var rgba = scratch.GetRGBA( out var f ).ThrowIfError( f );
RGBAPixels = rgba.Pixels[ ..( f.Meta.Width * f.Meta.Height * f.Meta.Format.BitsPerPixel() / 8 ) ].ToArray();
CreateTextureWrap( f.Meta.Width, f.Meta.Height );
return true;
}
private bool LoadPng() private bool LoadPng()
=> true; {
BaseImage = null;
using var stream = File.OpenRead( Path );
using var png = Image.Load< Rgba32 >( stream );
RGBAPixels = new byte[png.Height * png.Width * 4];
png.CopyPixelDataTo( RGBAPixels );
CreateTextureWrap( png.Width, png.Height );
return true;
}
private bool LoadTex() private bool LoadTex()
=> true; {
var tex = System.IO.Path.IsPathRooted( Path )
? Dalamud.GameData.GameData.GetFileFromDisk< TexFile >( Path )
: Dalamud.GameData.GetFile< TexFile >( Path );
BaseImage = tex ?? throw new Exception( "Could not read .tex file." );
RGBAPixels = tex.GetRgbaImageData();
CreateTextureWrap( tex.Header.Width, tex.Header.Height );
return true;
}
private void CreateTextureWrap( int width, int height )
=> TextureWrap = Dalamud.PluginInterface.UiBuilder.LoadImageRaw( RGBAPixels, width, height, 4 );
private string? _tmpPath;
public void PathInputBox( string label, string hint, string tooltip, string startPath, FileDialogManager manager ) public void PathInputBox( string label, string hint, string tooltip, string startPath, FileDialogManager manager )
{ {
var tmp = Path; _tmpPath ??= Path;
using var spacing = ImRaii.PushStyle( ImGuiStyleVar.ItemSpacing, new Vector2( 3 * ImGuiHelpers.GlobalScale, 0 ) ); using var spacing = ImRaii.PushStyle( ImGuiStyleVar.ItemSpacing, new Vector2( 3 * ImGuiHelpers.GlobalScale, 0 ) );
ImGui.SetNextItemWidth( -ImGui.GetFrameHeight() - 3 * ImGuiHelpers.GlobalScale ); ImGui.SetNextItemWidth( -ImGui.GetFrameHeight() - 3 * ImGuiHelpers.GlobalScale );
ImGui.InputTextWithHint( label, hint, ref tmp, Utf8GamePath.MaxGamePathLength ); ImGui.InputTextWithHint( label, hint, ref _tmpPath, Utf8GamePath.MaxGamePathLength );
if( ImGui.IsItemDeactivatedAfterEdit() ) if( ImGui.IsItemDeactivatedAfterEdit() )
{ {
Load( tmp ); Load( _tmpPath );
} }
ImGuiUtil.HoverTooltip( tooltip ); ImGuiUtil.HoverTooltip( tooltip );
@ -119,7 +182,7 @@ public struct Texture : IDisposable
} }
public static Texture Combined( Texture left, Texture right, InputManipulations leftManips, InputManipulations rightManips ) public static Texture Combined( Texture left, Texture right, InputManipulations leftManips, InputManipulations rightManips )
=> new Texture(); => new();
} }
public struct InputManipulations public struct InputManipulations
@ -352,13 +415,17 @@ public partial class ModEditWindow
{ {
try try
{ {
if (!ScratchImage.LoadDDS( path, out var f )) if( !ScratchImage.LoadDDS( path, out var f ) )
{
return ( null, 0, 0 ); return ( null, 0, 0 );
}
if(!f.GetRGBA( out f )) if( !f.GetRGBA( out f ) )
{
return ( null, 0, 0 ); return ( null, 0, 0 );
}
return ( f.Pixels[ ..(f.Meta.Width * f.Meta.Height * 4) ].ToArray(), f.Meta.Width, f.Meta.Height ); return ( f.Pixels[ ..( f.Meta.Width * f.Meta.Height * 4 ) ].ToArray(), f.Meta.Width, f.Meta.Height );
} }
catch( Exception e ) catch( Exception e )
{ {
@ -715,4 +782,4 @@ public partial class ModEditWindow
} }
} }
} }
} }