Skip to content

Commit

Permalink
Add Texture Conversion IPC and use texture tasks.
Browse files Browse the repository at this point in the history
  • Loading branch information
Ottermandias committed Aug 10, 2023
1 parent af93c2a commit 6e11b36
Show file tree
Hide file tree
Showing 9 changed files with 305 additions and 109 deletions.
2 changes: 1 addition & 1 deletion OtterGui
2 changes: 1 addition & 1 deletion Penumbra.Api
76 changes: 73 additions & 3 deletions Penumbra/Api/IpcTester.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
using System.Globalization;
using System.Linq;
using System.Numerics;
using System.Reflection.Metadata.Ecma335;
using System.Threading.Tasks;
using Dalamud.Utility;
using Penumbra.Api.Enums;
using Penumbra.Api.Helpers;
Expand All @@ -19,7 +21,6 @@
using Penumbra.Services;
using Penumbra.UI;
using Penumbra.Collections.Manager;
using Penumbra.Util;

namespace Penumbra.Api;

Expand All @@ -38,6 +39,7 @@ public class IpcTester : IDisposable
private readonly Meta _meta;
private readonly Mods _mods;
private readonly ModSettings _modSettings;
private readonly Editing _editing;
private readonly Temporary _temporary;

public IpcTester(Configuration config, DalamudServices dalamud, PenumbraIpcProviders ipcProviders, ModManager modManager,
Expand All @@ -54,6 +56,7 @@ public IpcTester(Configuration config, DalamudServices dalamud, PenumbraIpcProvi
_meta = new Meta(dalamud.PluginInterface);
_mods = new Mods(dalamud.PluginInterface);
_modSettings = new ModSettings(dalamud.PluginInterface);
_editing = new Editing(dalamud.PluginInterface);
_temporary = new Temporary(dalamud.PluginInterface, modManager, collections, tempMods, tempCollections, saveService, config);
UnsubscribeEvents();
}
Expand All @@ -74,6 +77,7 @@ public void Draw()
_meta.Draw();
_mods.Draw();
_modSettings.Draw();
_editing.Draw();
_temporary.Draw();
_temporary.DrawCollections();
_temporary.DrawMods();
Expand Down Expand Up @@ -402,9 +406,9 @@ private class Redrawing
private string _lastRedrawnString = "None";

public Redrawing(DalamudServices dalamud)
{
{
_dalamud = dalamud;
Redrawn = Ipc.GameObjectRedrawn.Subscriber(_dalamud.PluginInterface, SetLastRedrawn);
Redrawn = Ipc.GameObjectRedrawn.Subscriber(_dalamud.PluginInterface, SetLastRedrawn);
}

public void Draw()
Expand Down Expand Up @@ -1149,6 +1153,72 @@ private void UpdateLastModSetting(ModSettingChange type, string collection, stri
}
}

private class Editing
{
private readonly DalamudPluginInterface _pi;

private string _inputPath = string.Empty;
private string _inputPath2 = string.Empty;
private string _outputPath = string.Empty;
private string _outputPath2 = string.Empty;

private TextureType _typeSelector;
private bool _mipMaps = true;

private Task? _task1;
private Task? _task2;

public Editing(DalamudPluginInterface pi)
=> _pi = pi;

public void Draw()
{
using var _ = ImRaii.TreeNode("Editing");
if (!_)
return;

ImGui.InputTextWithHint("##inputPath", "Input Texture Path...", ref _inputPath, 256);
ImGui.InputTextWithHint("##outputPath", "Output Texture Path...", ref _outputPath, 256);
ImGui.InputTextWithHint("##inputPath2", "Input Texture Path 2...", ref _inputPath2, 256);
ImGui.InputTextWithHint("##outputPath2", "Output Texture Path 2...", ref _outputPath2, 256);
TypeCombo();
ImGui.Checkbox("Add MipMaps", ref _mipMaps);

using var table = ImRaii.Table("...", 3, ImGuiTableFlags.SizingFixedFit);
if (!table)
return;

DrawIntro(Ipc.ConvertTextureFile.Label, "Convert Texture 1");
if (ImGuiUtil.DrawDisabledButton("Save 1", Vector2.Zero, string.Empty, _task1 is { IsCompleted: false }))
_task1 = Ipc.ConvertTextureFile.Subscriber(_pi).Invoke(_inputPath, _outputPath, _typeSelector, _mipMaps);
ImGui.SameLine();
ImGui.TextUnformatted(_task1 == null ? "Not Initiated" : _task1.Status.ToString());
if (ImGui.IsItemHovered() && _task1?.Status == TaskStatus.Faulted)
ImGui.SetTooltip(_task1.Exception?.ToString());

DrawIntro(Ipc.ConvertTextureFile.Label, "Convert Texture 2");
if (ImGuiUtil.DrawDisabledButton("Save 2", Vector2.Zero, string.Empty, _task2 is { IsCompleted: false }))
_task2 = Ipc.ConvertTextureFile.Subscriber(_pi).Invoke(_inputPath2, _outputPath2, _typeSelector, _mipMaps);
ImGui.SameLine();
ImGui.TextUnformatted(_task2 == null ? "Not Initiated" : _task2.Status.ToString());
if (ImGui.IsItemHovered() && _task2?.Status == TaskStatus.Faulted)
ImGui.SetTooltip(_task2.Exception?.ToString());
}

private void TypeCombo()
{
using var combo = ImRaii.Combo("Convert To", _typeSelector.ToString());
if (!combo)
return;

foreach (var value in Enum.GetValues<TextureType>())
{
if (ImGui.Selectable(value.ToString(), _typeSelector == value))
_typeSelector = value;
}
}
}

private class Temporary
{
private readonly DalamudPluginInterface _pi;
Expand Down
44 changes: 42 additions & 2 deletions Penumbra/Api/PenumbraApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@
using Penumbra.Meta.Manipulations;
using Penumbra.Mods;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
using Penumbra.Api.Enums;
using Penumbra.GameData.Actors;
Expand All @@ -23,15 +25,17 @@
using Penumbra.Services;
using Penumbra.Collections.Manager;
using Penumbra.Communication;
using Penumbra.Import.Textures;
using Penumbra.Interop.Services;
using Penumbra.UI;
using TextureType = Penumbra.Api.Enums.TextureType;

namespace Penumbra.Api;

public class PenumbraApi : IDisposable, IPenumbraApi
{
public (int, int) ApiVersion
=> (4, 20);
=> (4, 21);

public event Action<string>? PreSettingsPanelDraw
{
Expand Down Expand Up @@ -124,12 +128,13 @@ public bool Valid
private RedrawService _redrawService;
private ModFileSystem _modFileSystem;
private ConfigWindow _configWindow;
private TextureManager _textureManager;

public unsafe PenumbraApi(CommunicatorService communicator, ModManager modManager, ResourceLoader resourceLoader,
Configuration config, CollectionManager collectionManager, DalamudServices dalamud, TempCollectionManager tempCollections,
TempModManager tempMods, ActorService actors, CollectionResolver collectionResolver, CutsceneService cutsceneService,
ModImportManager modImportManager, CollectionEditor collectionEditor, RedrawService redrawService, ModFileSystem modFileSystem,
ConfigWindow configWindow)
ConfigWindow configWindow, TextureManager textureManager)
{
_communicator = communicator;
_modManager = modManager;
Expand All @@ -147,6 +152,7 @@ public unsafe PenumbraApi(CommunicatorService communicator, ModManager modManage
_redrawService = redrawService;
_modFileSystem = modFileSystem;
_configWindow = configWindow;
_textureManager = textureManager;
_lumina = _dalamud.GameData.GameData;

_resourceLoader.ResourceLoaded += OnResourceLoaded;
Expand Down Expand Up @@ -179,6 +185,7 @@ public unsafe void Dispose()
_redrawService = null!;
_modFileSystem = null!;
_configWindow = null!;
_textureManager = null!;
}

public event ChangedItemClick? ChangedItemClicked
Expand Down Expand Up @@ -992,6 +999,39 @@ public string GetPlayerMetaManipulations()
return Functions.ToCompressedBase64(set, MetaManipulation.CurrentVersion);
}

public Task ConvertTextureFile(string inputFile, string outputFile, TextureType textureType, bool mipMaps)
=> textureType switch
{
TextureType.Png => _textureManager.SavePng(inputFile, outputFile),
TextureType.AsIsTex => _textureManager.SaveAs(CombinedTexture.TextureSaveType.AsIs, mipMaps, true, inputFile, outputFile),
TextureType.AsIsDds => _textureManager.SaveAs(CombinedTexture.TextureSaveType.AsIs, mipMaps, false, inputFile, outputFile),
TextureType.RgbaTex => _textureManager.SaveAs(CombinedTexture.TextureSaveType.Bitmap, mipMaps, true, inputFile, outputFile),
TextureType.RgbaDds => _textureManager.SaveAs(CombinedTexture.TextureSaveType.Bitmap, mipMaps, false, inputFile, outputFile),
TextureType.Bc3Tex => _textureManager.SaveAs(CombinedTexture.TextureSaveType.BC3, mipMaps, true, inputFile, outputFile),
TextureType.Bc3Dds => _textureManager.SaveAs(CombinedTexture.TextureSaveType.BC3, mipMaps, false, inputFile, outputFile),
TextureType.Bc7Tex => _textureManager.SaveAs(CombinedTexture.TextureSaveType.BC7, mipMaps, true, inputFile, outputFile),
TextureType.Bc7Dds => _textureManager.SaveAs(CombinedTexture.TextureSaveType.BC7, mipMaps, false, inputFile, outputFile),
_ => Task.FromException(new Exception($"Invalid input value {textureType}.")),
};

// @formatter:off
public Task ConvertTextureData(byte[] rgbaData, int width, string outputFile, TextureType textureType, bool mipMaps)
=> textureType switch
{
TextureType.Png => _textureManager.SavePng(new BaseImage(), outputFile, rgbaData, width, rgbaData.Length / 4 / width),
TextureType.AsIsTex => _textureManager.SaveAs(CombinedTexture.TextureSaveType.AsIs, mipMaps, true, new BaseImage(), outputFile, rgbaData, width, rgbaData.Length / 4 / width),
TextureType.AsIsDds => _textureManager.SaveAs(CombinedTexture.TextureSaveType.AsIs, mipMaps, false, new BaseImage(), outputFile, rgbaData, width, rgbaData.Length / 4 / width),
TextureType.RgbaTex => _textureManager.SaveAs(CombinedTexture.TextureSaveType.Bitmap, mipMaps, true, new BaseImage(), outputFile, rgbaData, width, rgbaData.Length / 4 / width),
TextureType.RgbaDds => _textureManager.SaveAs(CombinedTexture.TextureSaveType.Bitmap, mipMaps, false, new BaseImage(), outputFile, rgbaData, width, rgbaData.Length / 4 / width),
TextureType.Bc3Tex => _textureManager.SaveAs(CombinedTexture.TextureSaveType.BC3, mipMaps, true, new BaseImage(), outputFile, rgbaData, width, rgbaData.Length / 4 / width),
TextureType.Bc3Dds => _textureManager.SaveAs(CombinedTexture.TextureSaveType.BC3, mipMaps, false, new BaseImage(), outputFile, rgbaData, width, rgbaData.Length / 4 / width),
TextureType.Bc7Tex => _textureManager.SaveAs(CombinedTexture.TextureSaveType.BC7, mipMaps, true, new BaseImage(), outputFile, rgbaData, width, rgbaData.Length / 4 / width),
TextureType.Bc7Dds => _textureManager.SaveAs(CombinedTexture.TextureSaveType.BC7, mipMaps, false, new BaseImage(), outputFile, rgbaData, width, rgbaData.Length / 4 / width),
_ => Task.FromException(new Exception($"Invalid input value {textureType}.")),
};
// @formatter:on


// TODO: cleanup when incrementing API
public string GetMetaManipulations(string characterName)
=> GetMetaManipulations(characterName, ushort.MaxValue);
Expand Down
13 changes: 13 additions & 0 deletions Penumbra/Api/PenumbraIpcProviders.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Penumbra.GameData.Enums;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Penumbra.Api.Enums;
using Penumbra.Api.Helpers;
using Penumbra.Collections.Manager;
Expand Down Expand Up @@ -105,6 +106,10 @@ public class PenumbraIpcProviders : IDisposable
internal readonly EventProvider<ModSettingChange, string, string, bool> ModSettingChanged;
internal readonly FuncProvider<string, string, string, PenumbraApiEc> CopyModSettings;

// Editing
internal readonly FuncProvider<string, string, TextureType, bool, Task> ConvertTextureFile;
internal readonly FuncProvider<byte[], int, string, TextureType, bool, Task> ConvertTextureData;

// Temporary
internal readonly FuncProvider<string, string, bool, (PenumbraApiEc, string)> CreateTemporaryCollection;
internal readonly FuncProvider<string, PenumbraApiEc> RemoveTemporaryCollection;
Expand Down Expand Up @@ -219,6 +224,10 @@ public PenumbraIpcProviders(DalamudServices dalamud, IPenumbraApi api, ModManage
() => Api.ModSettingChanged -= ModSettingChangedEvent);
CopyModSettings = Ipc.CopyModSettings.Provider(pi, Api.CopyModSettings);

// Editing
ConvertTextureFile = Ipc.ConvertTextureFile.Provider(pi, Api.ConvertTextureFile);
ConvertTextureData = Ipc.ConvertTextureData.Provider(pi, Api.ConvertTextureData);

// Temporary
CreateTemporaryCollection = Ipc.CreateTemporaryCollection.Provider(pi, Api.CreateTemporaryCollection);
RemoveTemporaryCollection = Ipc.RemoveTemporaryCollection.Provider(pi, Api.RemoveTemporaryCollection);
Expand Down Expand Up @@ -335,6 +344,10 @@ public void Dispose()
RemoveTemporaryModAll.Dispose();
RemoveTemporaryMod.Dispose();

// Editing
ConvertTextureFile.Dispose();
ConvertTextureData.Dispose();

Disposed.Invoke();
Disposed.Dispose();
}
Expand Down
9 changes: 5 additions & 4 deletions Penumbra/Import/Textures/CombinedTexture.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Numerics;
using System.Threading.Tasks;

namespace Penumbra.Import.Textures;

Expand Down Expand Up @@ -29,7 +30,7 @@ private enum Mode

private readonly Texture _centerStorage = new();

public Guid SaveGuid { get; private set; } = Guid.Empty;
public Task SaveTask { get; private set; } = Task.CompletedTask;

public bool IsLoaded
=> _mode != Mode.Empty;
Expand All @@ -55,15 +56,15 @@ public void SaveAsPng(TextureManager textures, string path)
if (!IsLoaded || _current == null)
return;

SaveGuid = textures.SavePng(_current.BaseImage, path, _current.RgbaPixels, _current.TextureWrap!.Width, _current.TextureWrap!.Height);
SaveTask = textures.SavePng(_current.BaseImage, path, _current.RgbaPixels, _current.TextureWrap!.Width, _current.TextureWrap!.Height);
}

private void SaveAs(TextureManager textures, string path, TextureSaveType type, bool mipMaps, bool writeTex)
{
if (!IsLoaded || _current == null)
return;

SaveGuid = textures.SaveAs(type, mipMaps, writeTex, _current.BaseImage, path, _current.RgbaPixels, _current.TextureWrap!.Width,
SaveTask = textures.SaveAs(type, mipMaps, writeTex, _current.BaseImage, path, _current.RgbaPixels, _current.TextureWrap!.Width,
_current.TextureWrap!.Height);
}

Expand Down Expand Up @@ -133,7 +134,7 @@ private void Clean()
{
_centerStorage.Dispose();
_current = null;
SaveGuid = Guid.Empty;
SaveTask = Task.CompletedTask;
_mode = Mode.Empty;
}
}
Loading

0 comments on commit 6e11b36

Please sign in to comment.