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;
public struct Texture : IDisposable
public class Texture : IDisposable
{
// Path to the file we tried to load.
public string Path = string.Empty;
@ -44,6 +44,28 @@ public struct Texture : IDisposable
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()
{
RGBAPixels = Array.Empty< byte >();
@ -51,47 +73,88 @@ public struct Texture : IDisposable
TextureWrap = null;
( BaseImage as IDisposable )?.Dispose();
BaseImage = null;
Loaded?.Invoke( false );
}
public void Dispose()
=> Clean();
public bool Load( string path )
public event Action< bool >? Loaded;
private void Load( string path )
{
_tmpPath = null;
if( path == Path )
{
return false;
return;
}
Path = path;
Clean();
return System.IO.Path.GetExtension( Path ) switch
try
{
".dds" => LoadDds(),
".png" => LoadPng(),
".tex" => LoadTex(),
_ => true,
};
var _ = System.IO.Path.GetExtension( Path ) switch
{
".dds" => LoadDds(),
".png" => LoadPng(),
".tex" => LoadTex(),
_ => true,
};
Loaded?.Invoke( true );
}
catch( Exception e )
{
LoadError = e;
Clean();
}
}
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()
=> 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()
=> 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 )
{
var tmp = Path;
_tmpPath ??= Path;
using var spacing = ImRaii.PushStyle( ImGuiStyleVar.ItemSpacing, new Vector2( 3 * ImGuiHelpers.GlobalScale, 0 ) );
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() )
{
Load( tmp );
Load( _tmpPath );
}
ImGuiUtil.HoverTooltip( tooltip );
@ -119,7 +182,7 @@ public struct Texture : IDisposable
}
public static Texture Combined( Texture left, Texture right, InputManipulations leftManips, InputManipulations rightManips )
=> new Texture();
=> new();
}
public struct InputManipulations
@ -352,13 +415,17 @@ public partial class ModEditWindow
{
try
{
if (!ScratchImage.LoadDDS( path, out var f ))
if( !ScratchImage.LoadDDS( path, out var f ) )
{
return ( null, 0, 0 );
}
if(!f.GetRGBA( out f ))
if( !f.GetRGBA( out f ) )
{
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 )
{
@ -715,4 +782,4 @@ public partial class ModEditWindow
}
}
}
}
}