diff --git a/OptiScaler/Config.h b/OptiScaler/Config.h index f0119afb..4ee680c7 100644 --- a/OptiScaler/Config.h +++ b/OptiScaler/Config.h @@ -304,6 +304,8 @@ public: bool libxessExist = false; bool fsrHooks = false; + bool isHdrActive = false; + IFeature* CurrentFeature = nullptr; std::vector d3d12Devices; diff --git a/OptiScaler/hooks/wrapped_swapchain.h b/OptiScaler/hooks/wrapped_swapchain.h index 9d014c42..8e3d6c85 100644 --- a/OptiScaler/hooks/wrapped_swapchain.h +++ b/OptiScaler/hooks/wrapped_swapchain.h @@ -1,6 +1,7 @@ #pragma once #include "../pch.h" +#include "../Config.h" #include "dxgi1_6.h" #include "d3d12.h" @@ -233,6 +234,9 @@ struct DECLSPEC_UUID("3af622a3-82d0-49cd-994f-cce05122c222") WrappedIDXGISwapCha virtual HRESULT STDMETHODCALLTYPE SetColorSpace1(DXGI_COLOR_SPACE_TYPE ColorSpace) { + Config::Instance()->isHdrActive = ColorSpace == DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020 || ColorSpace == DXGI_COLOR_SPACE_YCBCR_FULL_GHLG_TOPLEFT_P2020 || + ColorSpace == DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P2020 || ColorSpace == DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709; + return m_pReal3->SetColorSpace1(ColorSpace); } diff --git a/OptiScaler/imgui/imgui_common.cpp b/OptiScaler/imgui/imgui_common.cpp index 969b37c6..cfae01c1 100644 --- a/OptiScaler/imgui/imgui_common.cpp +++ b/OptiScaler/imgui/imgui_common.cpp @@ -4,6 +4,8 @@ #include "../nvapi/fakenvapi.h" static ImVec2 overlayPosition(-1000.0f, -1000.0f); +static bool hdrTonemapApplied = false; +static ImVec4 SdrColors[ImGuiCol_COUNT]; void ImGuiCommon::ShowTooltip(const char* tip) { if (ImGui::IsItemHovered()) @@ -760,6 +762,16 @@ void ImGuiCommon::PopulateCombo(std::string name, std::optional* value } } +static ImVec4 toneMapColor(const ImVec4& color) +{ + // Apply tone mapping (e.g., Reinhard tone mapping) + float luminance = 0.2126f * color.x + 0.7152f * color.y + 0.0722f * color.z; + float mappedLuminance = luminance / (1.0f + luminance); + float scale = mappedLuminance / luminance; + + return ImVec4(color.x * scale, color.y * scale, color.z * scale, color.w); +} + bool ImGuiCommon::RenderMenu() { if (!_isInited) @@ -767,6 +779,34 @@ bool ImGuiCommon::RenderMenu() ImGuiIO& io = ImGui::GetIO(); (void)io; + if (Config::Instance()->isHdrActive) + { + if (!hdrTonemapApplied) + { + ImGuiStyle& style = ImGui::GetStyle(); + + CopyMemory(SdrColors, style.Colors, sizeof(style.Colors)); + + // Apply tone mapping to the ImGui style + for (int i = 0; i < ImGuiCol_COUNT; ++i) + { + ImVec4 color = style.Colors[i]; + style.Colors[i] = toneMapColor(color); + } + + hdrTonemapApplied = true; + } + } + else + { + if (hdrTonemapApplied) + { + ImGuiStyle& style = ImGui::GetStyle(); + CopyMemory(style.Colors, SdrColors, sizeof(style.Colors)); + hdrTonemapApplied = false; + } + } + if (!Config::Instance()->MenuScale.has_value()) { // 900p is minimum for 1.0 menu ratio diff --git a/OptiScaler/resource.h b/OptiScaler/resource.h index 8f3c83b8..2d665576 100644 --- a/OptiScaler/resource.h +++ b/OptiScaler/resource.h @@ -21,7 +21,7 @@ #define VER_MAJOR_VERSION 0 #define VER_MINOR_VERSION 7 #define VER_HOTFIX_VERSION 0 -#define VER_BUILD_NUMBER 92 +#define VER_BUILD_NUMBER 93 #define VER_PRE_RELEASE