From efd2c40cfd15b8e9e1142f368e4b2fdc5e1aec14 Mon Sep 17 00:00:00 2001 From: Dario Date: Tue, 3 Dec 2024 20:44:55 -0300 Subject: [PATCH] Add Scale and Origin to ImGui shaders. Change text to be squashed. --- UnleashedRecomp/gpu/imgui_common.h | 14 +++++- UnleashedRecomp/gpu/shader/imgui_common.hlsli | 2 + UnleashedRecomp/gpu/shader/imgui_vs.hlsl | 3 +- UnleashedRecomp/gpu/video.cpp | 8 ++++ UnleashedRecomp/locale/locale.h | 2 + UnleashedRecomp/ui/imgui_utils.h | 14 ++++++ UnleashedRecomp/ui/installer_wizard.cpp | 46 ++++++++++--------- 7 files changed, 66 insertions(+), 23 deletions(-) diff --git a/UnleashedRecomp/gpu/imgui_common.h b/UnleashedRecomp/gpu/imgui_common.h index d550bf38..2a357f21 100644 --- a/UnleashedRecomp/gpu/imgui_common.h +++ b/UnleashedRecomp/gpu/imgui_common.h @@ -10,7 +10,9 @@ enum class ImGuiCallback : int32_t { SetGradient = -1, - SetShaderModifier = -2 + SetShaderModifier = -2, + SetOrigin = -3, + SetScale = -4, }; union ImGuiCallbackData @@ -27,6 +29,16 @@ union ImGuiCallbackData { uint32_t shaderModifier; } setShaderModifier; + + struct + { + float origin[2]; + } setOrigin; + + struct + { + float scale[2]; + } setScale; }; #endif diff --git a/UnleashedRecomp/gpu/shader/imgui_common.hlsli b/UnleashedRecomp/gpu/shader/imgui_common.hlsli index fb838d7f..85a9ecc1 100644 --- a/UnleashedRecomp/gpu/shader/imgui_common.hlsli +++ b/UnleashedRecomp/gpu/shader/imgui_common.hlsli @@ -9,6 +9,8 @@ struct PushConstants uint ShaderModifier; uint Texture2DDescriptorIndex; float2 InverseDisplaySize; + float2 Origin; + float2 Scale; }; Texture2D g_Texture2DDescriptorHeap[] : register(t0, space0); diff --git a/UnleashedRecomp/gpu/shader/imgui_vs.hlsl b/UnleashedRecomp/gpu/shader/imgui_vs.hlsl index 90481cd7..5b7820d4 100644 --- a/UnleashedRecomp/gpu/shader/imgui_vs.hlsl +++ b/UnleashedRecomp/gpu/shader/imgui_vs.hlsl @@ -2,7 +2,8 @@ void main(in float2 position : POSITION, in float2 uv : TEXCOORD, in float4 color : COLOR, out Interpolators interpolators) { - interpolators.Position = float4(position * g_PushConstants.InverseDisplaySize * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0); + float2 correctedPosition = g_PushConstants.Origin + (position - g_PushConstants.Origin) * g_PushConstants.Scale; + interpolators.Position = float4(correctedPosition * g_PushConstants.InverseDisplaySize * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0); interpolators.UV = uv; interpolators.Color = color; } diff --git a/UnleashedRecomp/gpu/video.cpp b/UnleashedRecomp/gpu/video.cpp index b3fc8e3f..a1240954 100644 --- a/UnleashedRecomp/gpu/video.cpp +++ b/UnleashedRecomp/gpu/video.cpp @@ -1057,6 +1057,8 @@ struct ImGuiPushConstants uint32_t shaderModifier{}; uint32_t texture2DDescriptorIndex{}; ImVec2 inverseDisplaySize{}; + ImVec2 origin{ 0.0f, 0.0f }; + ImVec2 scale{ 1.0f, 1.0f }; }; static void CreateImGuiBackend() @@ -1812,6 +1814,12 @@ static void ProcDrawImGui(const RenderCommand& cmd) case ImGuiCallback::SetShaderModifier: commandList->setGraphicsPushConstants(0, &callbackData->setShaderModifier, offsetof(ImGuiPushConstants, shaderModifier), sizeof(callbackData->setShaderModifier)); break; + case ImGuiCallback::SetOrigin: + commandList->setGraphicsPushConstants(0, &callbackData->setOrigin, offsetof(ImGuiPushConstants, origin), sizeof(callbackData->setOrigin)); + break; + case ImGuiCallback::SetScale: + commandList->setGraphicsPushConstants(0, &callbackData->setScale, offsetof(ImGuiPushConstants, scale), sizeof(callbackData->setScale)); + break; } } else diff --git a/UnleashedRecomp/locale/locale.h b/UnleashedRecomp/locale/locale.h index 0c81ff0d..ac1eb716 100644 --- a/UnleashedRecomp/locale/locale.h +++ b/UnleashedRecomp/locale/locale.h @@ -103,6 +103,7 @@ inline static std::unordered_mapsetShaderModifier.shaderModifier = shaderModifier; } +static void SetOrigin(ImVec2 origin) +{ + auto callbackData = AddCallback(ImGuiCallback::SetOrigin); + callbackData->setOrigin.origin[0] = origin.x; + callbackData->setOrigin.origin[1] = origin.y; +} + +static void SetScale(ImVec2 scale) +{ + auto callbackData = AddCallback(ImGuiCallback::SetScale); + callbackData->setScale.scale[0] = scale.x; + callbackData->setScale.scale[1] = scale.y; +} + // Aspect ratio aware. static float Scale(float size) { diff --git a/UnleashedRecomp/ui/installer_wizard.cpp b/UnleashedRecomp/ui/installer_wizard.cpp index 01849cfa..d1172879 100644 --- a/UnleashedRecomp/ui/installer_wizard.cpp +++ b/UnleashedRecomp/ui/installer_wizard.cpp @@ -434,25 +434,21 @@ static void DrawButtonContainer(ImVec2 min, ImVec2 max, int baser, int baseg, fl SetShaderModifier(IMGUI_SHADER_MODIFIER_NONE); } -static ImVec2 ComputeTextSizeAndRatio(ImFont *font, const char *text, float &size, float maxTextWidth = FLT_MAX) +static ImVec2 ComputeTextSize(ImFont *font, const char *text, float size, float &squashRatio, float maxTextWidth = FLT_MAX) { ImVec2 textSize = font->CalcTextSizeA(size, FLT_MAX, 0.0f, text); if (textSize.x > maxTextWidth) { - float shrinkRatio = maxTextWidth / textSize.x; - size *= shrinkRatio; - textSize.x *= shrinkRatio; - textSize.y *= shrinkRatio; + squashRatio = maxTextWidth / textSize.x; + } + else + { + squashRatio = 1.0f; } return textSize; } -static ImVec2 ComputeTextSize(ImFont *font, const char *text, float size, float maxTextWidth = FLT_MAX) -{ - return ComputeTextSizeAndRatio(font, text, size, maxTextWidth); -} - static void DrawButton(ImVec2 min, ImVec2 max, const char *buttonText, bool sourceButton, bool buttonEnabled, bool &buttonPressed, float maxTextWidth = FLT_MAX) { buttonPressed = false; @@ -482,7 +478,8 @@ static void DrawButton(ImVec2 min, ImVec2 max, const char *buttonText, bool sour ImFont *font = sourceButton ? g_newRodinFont : g_dfsogeistdFont; float size = Scale(sourceButton ? 15.0f : 20.0f); - ImVec2 textSize = ComputeTextSizeAndRatio(font, buttonText, size, Scale(maxTextWidth)); + float squashRatio; + ImVec2 textSize = ComputeTextSize(font, buttonText, size, squashRatio, Scale(maxTextWidth)); min.x += ((max.x - min.x) - textSize.x) / 2.0f; min.y += ((max.y - min.y) - textSize.y) / 2.0f; @@ -491,11 +488,13 @@ static void DrawButton(ImVec2 min, ImVec2 max, const char *buttonText, bool sour // Fixes slight misalignment caused by this particular font. min.y -= Scale(1.0f); } - + + SetOrigin({ min.x + textSize.x / 2.0f, min.y }); + SetScale({ squashRatio, 1.0f }); SetGradient ( min, - { min.x + textSize.x, min.y + textSize.y }, + { min.x + textSize.x, textSize.y }, IM_COL32(baser + 192, 255, 0, 255), IM_COL32(baser + 128, baseg + 170, 0, 255) ); @@ -512,6 +511,8 @@ static void DrawButton(ImVec2 min, ImVec2 max, const char *buttonText, bool sour ); ResetGradient(); + SetScale({ 1.0f, 1.0f }); + SetOrigin({ 0.0f, 0.0f }); } enum ButtonColumn @@ -735,24 +736,25 @@ static void DrawSourcePickers() { constexpr float ADD_BUTTON_MAX_TEXT_WIDTH = 160.0f; const std::string &addFilesText = Localise("Installer_Button_AddFiles"); - ImVec2 textSize = ComputeTextSize(g_dfsogeistdFont, addFilesText.c_str(), 20.0f, ADD_BUTTON_MAX_TEXT_WIDTH); + float squashRatio; + ImVec2 textSize = ComputeTextSize(g_dfsogeistdFont, addFilesText.c_str(), 20.0f, squashRatio, ADD_BUTTON_MAX_TEXT_WIDTH); textSize.x += BUTTON_TEXT_GAP; ImVec2 min = { Scale(AlignToNextGrid(CONTAINER_X) + BOTTOM_X_GAP), Scale(AlignToNextGrid(CONTAINER_Y + CONTAINER_HEIGHT) + BOTTOM_Y_GAP) }; - ImVec2 max = { Scale(AlignToNextGrid(CONTAINER_X) + BOTTOM_X_GAP + textSize.x), Scale(AlignToNextGrid(CONTAINER_Y + CONTAINER_HEIGHT) + BOTTOM_Y_GAP + BUTTON_HEIGHT) }; + ImVec2 max = { Scale(AlignToNextGrid(CONTAINER_X) + BOTTOM_X_GAP + textSize.x * squashRatio), Scale(AlignToNextGrid(CONTAINER_Y + CONTAINER_HEIGHT) + BOTTOM_Y_GAP + BUTTON_HEIGHT) }; DrawButton(min, max, addFilesText.c_str(), false, true, buttonPressed, ADD_BUTTON_MAX_TEXT_WIDTH); if (buttonPressed && ShowFilesPicker(paths)) { ParseSourcePaths(paths); } - min.x += Scale(BOTTOM_X_GAP + textSize.x); + min.x += Scale(BOTTOM_X_GAP + textSize.x * squashRatio); const std::string &addFolderText = Localise("Installer_Button_AddFolder"); - textSize = ComputeTextSize(g_dfsogeistdFont, addFolderText.c_str(), 20.0f, ADD_BUTTON_MAX_TEXT_WIDTH); + textSize = ComputeTextSize(g_dfsogeistdFont, addFolderText.c_str(), 20.0f, squashRatio, ADD_BUTTON_MAX_TEXT_WIDTH); textSize.x += BUTTON_TEXT_GAP; - max.x = min.x + Scale(textSize.x); + max.x = min.x + Scale(textSize.x * squashRatio); DrawButton(min, max, addFolderText.c_str(), false, true, buttonPressed, ADD_BUTTON_MAX_TEXT_WIDTH); if (buttonPressed && ShowFoldersPicker(paths)) { @@ -856,15 +858,17 @@ static void DrawNextButton() skipButton = std::all_of(g_dlcSourcePaths.begin(), g_dlcSourcePaths.end(), [](const std::filesystem::path &path) { return path.empty(); }); } + float squashRatio; + constexpr float NEXT_BUTTON_MAX_TEXT_WIDTH = 100.0f; const std::string &buttonText = Localise(skipButton ? "Installer_Button_Skip" : "Installer_Button_Next"); - ImVec2 textSize = g_newRodinFont->CalcTextSizeA(20.0f, FLT_MAX, 0.0f, buttonText.c_str()); + ImVec2 textSize = ComputeTextSize(g_newRodinFont, buttonText.c_str(), 20.0f, squashRatio, NEXT_BUTTON_MAX_TEXT_WIDTH); textSize.x += BUTTON_TEXT_GAP; - ImVec2 min = { Scale(AlignToNextGrid(CONTAINER_X + CONTAINER_WIDTH) - textSize.x - BOTTOM_X_GAP), Scale(AlignToNextGrid(CONTAINER_Y + CONTAINER_HEIGHT) + BOTTOM_Y_GAP) }; + ImVec2 min = { Scale(AlignToNextGrid(CONTAINER_X + CONTAINER_WIDTH) - textSize.x * squashRatio - BOTTOM_X_GAP), Scale(AlignToNextGrid(CONTAINER_Y + CONTAINER_HEIGHT) + BOTTOM_Y_GAP) }; ImVec2 max = { Scale(AlignToNextGrid(CONTAINER_X + CONTAINER_WIDTH) - BOTTOM_X_GAP), Scale(AlignToNextGrid(CONTAINER_Y + CONTAINER_HEIGHT) + BOTTOM_Y_GAP + BUTTON_HEIGHT) }; bool buttonPressed = false; - DrawButton(min, max, buttonText.c_str(), false, nextButtonEnabled, buttonPressed); + DrawButton(min, max, buttonText.c_str(), false, nextButtonEnabled, buttonPressed, NEXT_BUTTON_MAX_TEXT_WIDTH); if (buttonPressed) {