mirror of
https://github.com/optiscaler/OptiScaler.git
synced 2026-10-19 18:20:59 +00:00
1090 lines
33 KiB
C++
1090 lines
33 KiB
C++
#include "../Config.h"
|
|
#include "../Logger.h"
|
|
|
|
#include "Imgui_Base.h"
|
|
#include "imgui/imgui_impl_win32.h"
|
|
|
|
#include "../detours/detours.h"
|
|
#pragma comment(lib, "../detours/detours.lib")
|
|
|
|
PFN_SetCursorPos pfn_SetPhysicalCursorPos = nullptr;
|
|
PFN_SetCursorPos pfn_SetCursorPos = nullptr;
|
|
PFN_mouse_event pfn_mouse_event = nullptr;
|
|
PFN_SendInput pfn_SendInput = nullptr;
|
|
PFN_SendMessageW pfn_SendMessageW = nullptr;
|
|
|
|
bool pfn_SetPhysicalCursorPos_hooked = false;
|
|
bool pfn_SetCursorPos_hooked = false;
|
|
bool pfn_mouse_event_hooked = false;
|
|
bool pfn_SendInput_hooked = false;
|
|
bool pfn_SendMessageW_hooked = false;
|
|
|
|
bool showMipmapCalcWindow = false;
|
|
float mipBias = 0.0f;
|
|
float mipBiasCalculated = 0.0f;
|
|
uint32_t mipmapUpscalerQuality = 0;
|
|
float mipmapUpscalerRatio = 0;
|
|
uint32_t displayWidth = 0;
|
|
uint32_t renderWidth = 0;
|
|
|
|
float ssRatio = 0.0f;
|
|
bool ssEnabled = false;
|
|
|
|
bool _isVisible = false;
|
|
WNDPROC _oWndProc = nullptr;
|
|
|
|
LRESULT WINAPI hkSendMessageW(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
if (_isVisible && Msg == 0x0020)
|
|
return TRUE;
|
|
else
|
|
return pfn_SendMessageW(hWnd, Msg, wParam, lParam);
|
|
}
|
|
|
|
BOOL WINAPI hkSetPhysicalCursorPos(int x, int y)
|
|
{
|
|
if (_isVisible)
|
|
return TRUE;
|
|
else
|
|
return pfn_SetPhysicalCursorPos(x, y);
|
|
}
|
|
|
|
BOOL WINAPI hkSetCursorPos(int x, int y)
|
|
{
|
|
if (_isVisible)
|
|
return TRUE;
|
|
else
|
|
return pfn_SetCursorPos(x, y);
|
|
}
|
|
|
|
void WINAPI hkmouse_event(DWORD dwFlags, DWORD dx, DWORD dy, DWORD dwData, ULONG_PTR dwExtraInfo)
|
|
{
|
|
if (_isVisible)
|
|
return;
|
|
else
|
|
pfn_mouse_event(dwFlags, dx, dy, dwData, dwExtraInfo);
|
|
}
|
|
|
|
UINT WINAPI hkSendInput(UINT cInputs, LPINPUT pInputs, int cbSize)
|
|
{
|
|
if (_isVisible)
|
|
return TRUE;
|
|
else
|
|
return pfn_SendInput(cInputs, pInputs, cbSize);
|
|
}
|
|
|
|
void AttachHooks()
|
|
{
|
|
DetourTransactionBegin();
|
|
DetourUpdateThread(GetCurrentThread());
|
|
|
|
// Detour the functions
|
|
pfn_SetPhysicalCursorPos = reinterpret_cast<PFN_SetCursorPos>(DetourFindFunction("user32.dll", "SetPhysicalCursorPos"));
|
|
pfn_SetCursorPos = reinterpret_cast<PFN_SetCursorPos>(DetourFindFunction("user32.dll", "SetCursorPos"));
|
|
pfn_mouse_event = reinterpret_cast<PFN_mouse_event>(DetourFindFunction("user32.dll", "mouse_event"));
|
|
pfn_SendInput = reinterpret_cast<PFN_SendInput>(DetourFindFunction("user32.dll", "SendInput"));
|
|
pfn_SendMessageW = reinterpret_cast<PFN_SendMessageW>(DetourFindFunction("user32.dll", "SendMessageW"));
|
|
|
|
if (pfn_SetPhysicalCursorPos && (pfn_SetPhysicalCursorPos != pfn_SetCursorPos))
|
|
pfn_SetPhysicalCursorPos_hooked = (DetourAttach(&(PVOID&)pfn_SetPhysicalCursorPos, hkSetPhysicalCursorPos) == 0);
|
|
|
|
if (pfn_SetCursorPos)
|
|
pfn_SetCursorPos_hooked = (DetourAttach(&(PVOID&)pfn_SetCursorPos, hkSetCursorPos) == 0);
|
|
|
|
if (pfn_mouse_event)
|
|
pfn_mouse_event_hooked = (DetourAttach(&(PVOID&)pfn_mouse_event, hkmouse_event) == 0);
|
|
|
|
if (pfn_SendInput)
|
|
pfn_SendInput_hooked = (DetourAttach(&(PVOID&)pfn_SendInput, hkSendInput) == 0);
|
|
|
|
if (pfn_SendMessageW)
|
|
pfn_SendMessageW_hooked = (DetourAttach(&(PVOID&)pfn_SendMessageW, hkSendMessageW) == 0);
|
|
|
|
DetourTransactionCommit();
|
|
}
|
|
|
|
void DetachHooks()
|
|
{
|
|
DetourTransactionBegin();
|
|
DetourUpdateThread(GetCurrentThread());
|
|
|
|
if (pfn_SetPhysicalCursorPos_hooked)
|
|
DetourDetach(&(PVOID&)pfn_SetPhysicalCursorPos, hkSetPhysicalCursorPos);
|
|
|
|
if (pfn_SetCursorPos_hooked)
|
|
DetourDetach(&(PVOID&)pfn_SetCursorPos, hkSetCursorPos);
|
|
|
|
if (pfn_mouse_event_hooked)
|
|
DetourDetach(&(PVOID&)pfn_mouse_event, hkmouse_event);
|
|
|
|
if (pfn_SendInput_hooked)
|
|
DetourDetach(&(PVOID&)pfn_SendInput, hkSendInput);
|
|
|
|
if (pfn_SendMessageW_hooked)
|
|
DetourDetach(&(PVOID&)pfn_SendMessageW, hkSendMessageW);
|
|
|
|
pfn_SetPhysicalCursorPos_hooked = false;
|
|
pfn_SetCursorPos_hooked = false;
|
|
pfn_mouse_event_hooked = false;
|
|
pfn_SendInput_hooked = false;
|
|
pfn_SendMessageW_hooked = false;
|
|
|
|
pfn_SetPhysicalCursorPos = nullptr;
|
|
pfn_SetCursorPos = nullptr;
|
|
pfn_mouse_event = nullptr;
|
|
pfn_SendInput = nullptr;
|
|
pfn_SendMessageW = nullptr;
|
|
|
|
DetourTransactionCommit();
|
|
}
|
|
|
|
/*Forward declare message handler from imgui_impl_win32.cpp*/
|
|
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
|
|
|
//Win32 message handler
|
|
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
if(Config::Instance()->ActiveFeatureCount == 0)
|
|
return CallWindowProc(_oWndProc, hWnd, msg, wParam, lParam);
|
|
|
|
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
|
|
|
// HOME
|
|
if (msg == WM_KEYDOWN && wParam == VK_HOME) // && (GetKeyState(VK_SHIFT) & 0x8000))
|
|
{
|
|
_isVisible = !_isVisible;
|
|
io.MouseDrawCursor = _isVisible;
|
|
io.WantCaptureKeyboard = _isVisible;
|
|
io.WantCaptureMouse = _isVisible;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
if (msg == WM_KEYDOWN && wParam == VK_DELETE && (GetKeyState(VK_SHIFT) & 0x8000))
|
|
{
|
|
Config::Instance()->xessDebug = true;
|
|
return TRUE;
|
|
}
|
|
|
|
// Imgui
|
|
if (_isVisible)
|
|
{
|
|
if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam))
|
|
return TRUE;
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_LBUTTONDOWN:
|
|
case WM_LBUTTONUP:
|
|
case WM_RBUTTONDOWN:
|
|
case WM_RBUTTONUP:
|
|
case WM_MBUTTONDOWN:
|
|
case WM_MBUTTONUP:
|
|
case WM_KEYDOWN:
|
|
case WM_KEYUP:
|
|
case WM_SYSKEYDOWN:
|
|
case WM_SYSKEYUP:
|
|
case WM_MOUSEMOVE:
|
|
case WM_SETCURSOR:
|
|
case WM_LBUTTONDBLCLK:
|
|
case WM_RBUTTONDBLCLK:
|
|
case WM_MBUTTONDBLCLK:
|
|
case WM_XBUTTONDOWN:
|
|
case WM_XBUTTONUP:
|
|
case WM_XBUTTONDBLCLK:
|
|
case WM_MOUSELAST:
|
|
case WM_INPUT:
|
|
return TRUE;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
auto log = std::format("WNDPROC MSG : {}", msg);
|
|
OutputDebugStringA(log.c_str());
|
|
}
|
|
|
|
return CallWindowProc(_oWndProc, hWnd, msg, wParam, lParam);
|
|
}
|
|
|
|
std::string GetBackendName(std::string* code)
|
|
{
|
|
if (*code == "fsr21")
|
|
return "FSR 2.1.2";
|
|
|
|
if (*code == "fsr22")
|
|
return "FSR 2.2.1";
|
|
|
|
if (*code == "fsr21_12")
|
|
return "FSR 2.1.2 w/Dx12";
|
|
|
|
if (*code == "fsr22_12")
|
|
return "FSR 2.2.1 w/Dx12";
|
|
|
|
if (*code == "xess")
|
|
return "XeSS";
|
|
|
|
return "????";
|
|
}
|
|
|
|
std::string GetBackendCode(const NVNGX_Api api)
|
|
{
|
|
std::string code;
|
|
|
|
if (api == NVNGX_DX11)
|
|
code = Config::Instance()->Dx11Upscaler.value_or("fsr22");
|
|
else if (api == NVNGX_DX12)
|
|
code = Config::Instance()->Dx12Upscaler.value_or("xess");
|
|
else
|
|
code = Config::Instance()->VulkanUpscaler.value_or("fsr21");
|
|
|
|
return code;
|
|
}
|
|
|
|
void GetCurrentBackendInfo(const NVNGX_Api api, std::string* code, std::string* name)
|
|
{
|
|
*code = GetBackendCode(api);
|
|
*name = GetBackendName(code);
|
|
}
|
|
|
|
void AddDx11Backends(std::string* code, std::string* name)
|
|
{
|
|
std::string selectedUpscalerName = "";
|
|
|
|
if (Config::Instance()->newBackend == "fsr22" || (Config::Instance()->newBackend == "" && *code == "fsr22"))
|
|
selectedUpscalerName = "FSR 2.2.1";
|
|
else if (Config::Instance()->newBackend == "fsr22_12" || (Config::Instance()->newBackend == "" && *code == "fsr22_12"))
|
|
selectedUpscalerName = "FSR 2.2.1 w/Dx12";
|
|
else if (Config::Instance()->newBackend == "fsr21_12" || (Config::Instance()->newBackend == "" && *code == "fsr21_12"))
|
|
selectedUpscalerName = "FSR 2.1.2 w/Dx12";
|
|
else
|
|
selectedUpscalerName = "XeSS w/Dx12";
|
|
|
|
if (ImGui::BeginCombo("Select", selectedUpscalerName.c_str()))
|
|
{
|
|
if (ImGui::Selectable("FSR 2.2.1", *code == "fsr22"))
|
|
Config::Instance()->newBackend = "fsr22";
|
|
|
|
if (ImGui::Selectable("XeSS w/Dx12", false, *code == "xess"))
|
|
Config::Instance()->newBackend = "xess";
|
|
|
|
if (ImGui::Selectable("FSR 2.1.2 w/Dx12", *code == "fsr21_12"))
|
|
Config::Instance()->newBackend = "fsr21_12";
|
|
|
|
if (ImGui::Selectable("FSR 2.2.1 w/Dx12", *code == "fsr22_12"))
|
|
Config::Instance()->newBackend = "fsr22_12";
|
|
|
|
ImGui::EndCombo();
|
|
}
|
|
}
|
|
|
|
void AddDx12Backends(std::string* code, std::string* name)
|
|
{
|
|
std::string selectedUpscalerName = "";
|
|
|
|
if (Config::Instance()->newBackend == "fsr21" || (Config::Instance()->newBackend == "" && *code == "fsr21"))
|
|
selectedUpscalerName = "FSR 2.1.2";
|
|
else if (Config::Instance()->newBackend == "fsr22" || (Config::Instance()->newBackend == "" && *code == "fsr22"))
|
|
selectedUpscalerName = "FSR 2.2.1";
|
|
else
|
|
selectedUpscalerName = "XeSS";
|
|
|
|
if (ImGui::BeginCombo("Select", selectedUpscalerName.c_str()))
|
|
{
|
|
if (ImGui::Selectable("XeSS", false, *code == "xess"))
|
|
Config::Instance()->newBackend = "xess";
|
|
|
|
if (ImGui::Selectable("FSR 2.1.2", *code == "fsr21"))
|
|
Config::Instance()->newBackend = "fsr21";
|
|
|
|
if (ImGui::Selectable("FSR 2.2.1", *code == "fsr22"))
|
|
Config::Instance()->newBackend = "fsr22";
|
|
|
|
ImGui::EndCombo();
|
|
}
|
|
}
|
|
|
|
void AddVulkanBackends(std::string* code, std::string* name)
|
|
{
|
|
std::string selectedUpscalerName = "";
|
|
|
|
if (Config::Instance()->newBackend == "fsr21" || (Config::Instance()->newBackend == "" && *code == "fsr21"))
|
|
selectedUpscalerName = "FSR 2.1.2";
|
|
else
|
|
selectedUpscalerName = "FSR 2.2.1";
|
|
|
|
if (ImGui::BeginCombo("Select", selectedUpscalerName.c_str()))
|
|
{
|
|
if (ImGui::Selectable("FSR 2.1.2", *code == "fsr21"))
|
|
Config::Instance()->newBackend = "fsr21";
|
|
|
|
if (ImGui::Selectable("FSR 2.2.1", *code == "fsr22"))
|
|
Config::Instance()->newBackend = "fsr22";
|
|
|
|
ImGui::EndCombo();
|
|
}
|
|
}
|
|
|
|
void AddResourceBarrier(std::string name, std::optional<int>* value)
|
|
{
|
|
const char* states[] = { "Auto", "COMMON", "VERTEX_AND_CONSTANT_BUFFER", "INDEX_BUFFER", "RENDER_TARGET", "UNORDERED_ACCESS", "DEPTH_WRITE",
|
|
"DEPTH_READ", "NON_PIXEL_SHADER_RESOURCE", "PIXEL_SHADER_RESOURCE", "STREAM_OUT", "INDIRECT_ARGUMENT", "COPY_DEST", "COPY_SOURCE",
|
|
"RESOLVE_DEST", "RESOLVE_SOURCE", "RAYTRACING_ACCELERATION_STRUCTURE", "SHADING_RATE_SOURCE", "GENERIC_READ", "ALL_SHADER_RESOURCE",
|
|
"PRESENT", "PREDICATION", "VIDEO_DECODE_READ", "VIDEO_DECODE_WRITE", "VIDEO_PROCESS_READ", "VIDEO_PROCESS_WRITE", "VIDEO_ENCODE_READ",
|
|
"VIDEO_ENCODE_WRITE" };
|
|
const int values[] = { -1, 0, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 4194304, 16777216, 2755, 192, 0, 310, 65536,
|
|
131072, 262144, 524288, 2097152, 8388608 };
|
|
|
|
|
|
int selected = value->value_or(-1);
|
|
|
|
const char* selectedName = "";
|
|
|
|
for (int n = 0; n < 28; n++)
|
|
{
|
|
if (values[n] == selected)
|
|
{
|
|
selectedName = states[n];
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (ImGui::BeginCombo(name.c_str(), selectedName))
|
|
{
|
|
if (ImGui::Selectable(states[0], !value->has_value()))
|
|
value->reset();
|
|
|
|
for (int n = 1; n < 28; n++)
|
|
{
|
|
if (ImGui::Selectable(states[n], selected == values[n]))
|
|
*value = values[n];
|
|
}
|
|
|
|
ImGui::EndCombo();
|
|
}
|
|
}
|
|
|
|
void Imgui_Base::RenderMenu()
|
|
{
|
|
ImGuiIO const& io = ImGui::GetIO(); (void)io;
|
|
|
|
ImGui_ImplWin32_NewFrame();
|
|
ImGui::NewFrame();
|
|
|
|
{
|
|
ImGuiWindowFlags flags = 0;
|
|
flags |= ImGuiWindowFlags_NoSavedSettings;
|
|
flags |= ImGuiWindowFlags_NoCollapse;
|
|
|
|
auto posX = (Config::Instance()->CurrentFeature->DisplayWidth() - 770.0f) / 2.0f;
|
|
auto posY = (Config::Instance()->CurrentFeature->DisplayHeight() - 670.0f) / 2.0f;
|
|
|
|
ImGui::SetNextWindowPos(ImVec2{ posX , posY }, ImGuiCond_FirstUseEver);
|
|
ImGui::SetNextWindowSize(ImVec2{ 770.0f, 670.0f }, ImGuiCond_FirstUseEver);
|
|
|
|
if (ImGui::Begin("OmniScaler v0.4", nullptr, flags))
|
|
{
|
|
if (ImGui::BeginTable("main", 2))
|
|
{
|
|
ImGui::TableNextColumn();
|
|
|
|
// UPSCALERS -----------------------------
|
|
ImGui::SeparatorText("Upscalers");
|
|
|
|
std::string selectedUpscalerName = "";
|
|
std::string currentBackend;
|
|
std::string currentBackendName;
|
|
|
|
GetCurrentBackendInfo(Config::Instance()->Api, ¤tBackend, ¤tBackendName);
|
|
|
|
switch (Config::Instance()->Api)
|
|
{
|
|
case NVNGX_DX11:
|
|
ImGui::Text("DirextX 11 - %s (%d.%d.%d)", Config::Instance()->CurrentFeature->Name(), Config::Instance()->CurrentFeature->Version().major, Config::Instance()->CurrentFeature->Version().minor, Config::Instance()->CurrentFeature->Version().patch);
|
|
AddDx11Backends(¤tBackend, ¤tBackendName);
|
|
break;
|
|
|
|
case NVNGX_DX12:
|
|
ImGui::Text("DirextX 12 - %s (%d.%d.%d)", Config::Instance()->CurrentFeature->Name(), Config::Instance()->CurrentFeature->Version().major, Config::Instance()->CurrentFeature->Version().minor, Config::Instance()->CurrentFeature->Version().patch);
|
|
AddDx12Backends(¤tBackend, ¤tBackendName);
|
|
break;
|
|
|
|
default:
|
|
ImGui::Text("Vulkan - %s (%d.%d.%d)", Config::Instance()->CurrentFeature->Name(), Config::Instance()->CurrentFeature->Version().major, Config::Instance()->CurrentFeature->Version().minor, Config::Instance()->CurrentFeature->Version().patch);
|
|
AddVulkanBackends(¤tBackend, ¤tBackendName);
|
|
}
|
|
|
|
if (ImGui::Button("Apply") && Config::Instance()->newBackend != "" && Config::Instance()->newBackend != currentBackend)
|
|
Config::Instance()->changeBackend = true;
|
|
|
|
ImGui::SameLine(0.0f, 6.0f);
|
|
|
|
if (ImGui::Button("Revert"))
|
|
Config::Instance()->newBackend = "";
|
|
|
|
// Dx11
|
|
ImGui::BeginDisabled(Config::Instance()->Api != NVNGX_DX11 ||
|
|
(Config::Instance()->Api == NVNGX_DX11 && Config::Instance()->Dx11Upscaler.value_or("fsr22") == "fsr22"));
|
|
|
|
const char* sync[] = { "No Syncing", "Shared Fences", "Shared Fences + Flush", "Shared Fences + Query", "Mostly Queries" };
|
|
|
|
const char* selectedSync = sync[Config::Instance()->UseSafeSyncQueries.value_or(1)];
|
|
|
|
if (ImGui::BeginCombo("Dx12wDx11 Sync", selectedSync))
|
|
{
|
|
for (int n = 0; n < 5; n++)
|
|
{
|
|
if (ImGui::Selectable(sync[n], (Config::Instance()->UseSafeSyncQueries.value_or(1) == n)))
|
|
Config::Instance()->UseSafeSyncQueries = n;
|
|
}
|
|
|
|
ImGui::EndCombo();
|
|
}
|
|
|
|
ImGui::EndDisabled();
|
|
|
|
// UPSCALER SPECIFIC -----------------------------
|
|
// XeSS
|
|
ImGui::BeginDisabled(currentBackend != "xess");
|
|
ImGui::SeparatorText("XeSS Settings");
|
|
|
|
const char* models[] = { "KPSS", "SPLAT", "MODEL_3", "MODEL_4", "MODEL_5", "MODEL_6" };
|
|
auto configModes = Config::Instance()->NetworkModel.value_or(0);
|
|
|
|
if (configModes < 0 || configModes > 5)
|
|
configModes = 0;
|
|
|
|
const char* selectedModel = models[configModes];
|
|
|
|
if (ImGui::BeginCombo("Network Models", selectedModel))
|
|
{
|
|
for (int n = 0; n < 6; n++)
|
|
{
|
|
if (ImGui::Selectable(models[n], (Config::Instance()->NetworkModel.value_or(0) == n)))
|
|
{
|
|
Config::Instance()->NetworkModel = n;
|
|
Config::Instance()->changeBackend = true;
|
|
}
|
|
}
|
|
|
|
ImGui::EndCombo();
|
|
}
|
|
|
|
if (bool cas = Config::Instance()->CasEnabled.value_or(false); ImGui::Checkbox("CAS", &cas))
|
|
{
|
|
Config::Instance()->CasEnabled = cas;
|
|
Config::Instance()->changeCAS = true;
|
|
}
|
|
|
|
ImGui::SameLine(0.0f, 6.0f);
|
|
if (bool dbg = Config::Instance()->xessDebug; ImGui::Checkbox("Dump (Shift+Del)", &dbg))
|
|
Config::Instance()->xessDebug = dbg;
|
|
|
|
ImGui::SameLine(0.0f, 6.0f);
|
|
int dbgCount = Config::Instance()->xessDebugFrames;
|
|
|
|
ImGui::PushItemWidth(85.0);
|
|
if (ImGui::InputInt("frames", &dbgCount))
|
|
{
|
|
if (dbgCount < 4)
|
|
dbgCount = 4;
|
|
else if (dbgCount > 999)
|
|
dbgCount = 999;
|
|
|
|
Config::Instance()->xessDebugFrames = dbgCount;
|
|
}
|
|
|
|
ImGui::PopItemWidth();
|
|
|
|
ImGui::BeginDisabled(!Config::Instance()->CasEnabled.value_or(false));
|
|
|
|
const char* cs[] = { "LINEAR", "GAMMA20", "GAMMA22", "SRGB_OUTPUT", "SRGB_INPUT_OUTPUT" };
|
|
auto configCs = Config::Instance()->CasColorSpaceConversion.value_or(0);
|
|
|
|
if (configCs < 0)
|
|
configCs = 0;
|
|
else if (configCs > 4)
|
|
configCs = 4;
|
|
|
|
const char* selectedCs = cs[configCs];
|
|
|
|
if (ImGui::BeginCombo("Color Space", selectedCs))
|
|
{
|
|
for (int n = 0; n < 5; n++)
|
|
{
|
|
if (ImGui::Selectable(cs[n], (Config::Instance()->CasColorSpaceConversion.value_or(0) == n)))
|
|
{
|
|
Config::Instance()->CasColorSpaceConversion = n;
|
|
Config::Instance()->changeCAS = true;
|
|
}
|
|
}
|
|
|
|
ImGui::EndCombo();
|
|
}
|
|
|
|
ImGui::EndDisabled();
|
|
|
|
ImGui::EndDisabled();
|
|
|
|
// FSR -----------------
|
|
ImGui::BeginDisabled(currentBackend == "xess");
|
|
ImGui::SeparatorText("FSR Settings");
|
|
|
|
bool useVFov = Config::Instance()->FsrVerticalFov.has_value() || !Config::Instance()->FsrHorizontalFov.has_value();
|
|
|
|
float vfov;
|
|
float hfov;
|
|
|
|
vfov = Config::Instance()->FsrVerticalFov.value_or(60.0f);
|
|
hfov = Config::Instance()->FsrHorizontalFov.value_or(90.0f);
|
|
|
|
if (ImGui::RadioButton("Use Vert. Fov", useVFov))
|
|
{
|
|
Config::Instance()->FsrHorizontalFov.reset();
|
|
useVFov = true;
|
|
}
|
|
|
|
ImGui::SameLine();
|
|
|
|
if (ImGui::RadioButton("Use Horz. Fov", !useVFov))
|
|
{
|
|
Config::Instance()->FsrVerticalFov.reset();
|
|
useVFov = false;
|
|
}
|
|
|
|
ImGui::BeginDisabled(!useVFov);
|
|
|
|
if (ImGui::SliderFloat("Vert. FOV", &vfov, 0.0f, 180.0f, "%.1f", ImGuiSliderFlags_NoRoundToFormat))
|
|
Config::Instance()->FsrVerticalFov = vfov;
|
|
|
|
ImGui::EndDisabled();
|
|
|
|
ImGui::BeginDisabled(useVFov);
|
|
|
|
if (ImGui::SliderFloat("Horz. FOV", &hfov, 0.0f, 180.0f, "%.1f", ImGuiSliderFlags_NoRoundToFormat))
|
|
Config::Instance()->FsrHorizontalFov = hfov;
|
|
|
|
ImGui::EndDisabled();
|
|
|
|
ImGui::EndDisabled();
|
|
|
|
// SUPERSAMPLING -----------------------------
|
|
ImGui::SeparatorText("Supersampling");
|
|
|
|
bool isXess12 = (Config::Instance()->Dx12Upscaler.value_or("xess") == "xess" || Config::Instance()->Dx11Upscaler.value_or("fsr22") == "xess") &&
|
|
Config::Instance()->CurrentFeature->Version().major <= 1 && Config::Instance()->CurrentFeature->Version().minor <= 2;
|
|
|
|
float defaultRatio = 2.5f;
|
|
|
|
if (ssRatio == 0.0f)
|
|
{
|
|
ssRatio = Config::Instance()->SuperSamplingMultiplier.value_or(2.5f);
|
|
ssEnabled = Config::Instance()->SuperSamplingEnabled.value_or(false);
|
|
}
|
|
|
|
ImGui::BeginDisabled(
|
|
(Config::Instance()->Api == NVNGX_VULKAN || (Config::Instance()->Api == NVNGX_DX11 && Config::Instance()->Dx11Upscaler.value_or("fsr22") == "fsr22")) ||
|
|
Config::Instance()->DisplayResolution.value_or(false)
|
|
);
|
|
|
|
ImGui::Checkbox("Enable", &ssEnabled);
|
|
|
|
ImGui::SameLine(0.0f, 6.0f);
|
|
|
|
if (ImGui::Button("Apply Change"))
|
|
{
|
|
if (ssEnabled != Config::Instance()->SuperSamplingEnabled.value_or(false) || ssRatio != Config::Instance()->SuperSamplingMultiplier.value_or(defaultRatio))
|
|
{
|
|
Config::Instance()->SuperSamplingEnabled = ssEnabled;
|
|
Config::Instance()->SuperSamplingMultiplier = ssRatio;
|
|
Config::Instance()->changeBackend = true;
|
|
}
|
|
}
|
|
|
|
ImGui::SliderFloat("Ratio", &ssRatio, (float)Config::Instance()->CurrentFeature->DisplayWidth() / (float)Config::Instance()->CurrentFeature->RenderWidth(), isXess12 ? 2.5f : 5.0f, "%.2f");
|
|
|
|
ImGui::EndDisabled();
|
|
|
|
// SHARPNESS -----------------------------
|
|
ImGui::SeparatorText("Sharpness");
|
|
|
|
if (bool overrideSharpness = Config::Instance()->OverrideSharpness.value_or(false); ImGui::Checkbox("Override", &overrideSharpness))
|
|
Config::Instance()->OverrideSharpness = overrideSharpness;
|
|
|
|
ImGui::BeginDisabled(!Config::Instance()->OverrideSharpness.value_or(false));
|
|
|
|
float sharpness = Config::Instance()->Sharpness.value_or(0.3f);
|
|
ImGui::SliderFloat("Sharpness", &sharpness, 0.0f, 1.0f, "%.3f", ImGuiSliderFlags_NoRoundToFormat);
|
|
Config::Instance()->Sharpness = sharpness;
|
|
|
|
ImGui::EndDisabled();
|
|
|
|
// MIPMAP BIAS -----------------------------
|
|
ImGui::SeparatorText("Mipmap Bias (Dx12)");
|
|
|
|
ImGui::BeginDisabled(Config::Instance()->Api != NVNGX_DX12);
|
|
|
|
if (Config::Instance()->MipmapBiasOverride.has_value() && mipBias == 0.0f)
|
|
mipBias = Config::Instance()->MipmapBiasOverride.value();
|
|
|
|
ImGui::SliderFloat("Mipmap Bias", &mipBias, -15.0f, 15.0f, "%.6f", ImGuiSliderFlags_NoRoundToFormat);
|
|
|
|
ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "This will be applied after first resolution change!");
|
|
|
|
if (ImGui::Button("Set"))
|
|
Config::Instance()->MipmapBiasOverride = mipBias;
|
|
|
|
ImGui::SameLine(0.0f, 6.0f);
|
|
|
|
if (ImGui::Button("Reset"))
|
|
{
|
|
Config::Instance()->MipmapBiasOverride.reset();
|
|
mipBias = 0.0f;
|
|
}
|
|
|
|
ImGui::SameLine(0.0f, 6.0f);
|
|
|
|
if (ImGui::Button("Calculate"))
|
|
{
|
|
showMipmapCalcWindow = true;
|
|
}
|
|
|
|
ImGui::SameLine(0.0f, 6.0f);
|
|
|
|
ImGui::Text("Current : %.6f", Config::Instance()->lastMipBias);
|
|
|
|
ImGui::EndDisabled();
|
|
|
|
// UPSCALE RATIO OVERRIDE -----------------
|
|
ImGui::SeparatorText("Upscale Ratio");
|
|
if (bool upOverride = Config::Instance()->UpscaleRatioOverrideEnabled.value_or(false); ImGui::Checkbox("Ratio Override", &upOverride))
|
|
Config::Instance()->UpscaleRatioOverrideEnabled = upOverride;
|
|
|
|
ImGui::BeginDisabled(!Config::Instance()->UpscaleRatioOverrideEnabled.value_or(false));
|
|
|
|
float urOverride = Config::Instance()->UpscaleRatioOverrideValue.value_or(1.3f);
|
|
ImGui::SliderFloat("Override Ratio", &urOverride, 1.0f, 3.0f, "%.3f", ImGuiSliderFlags_NoRoundToFormat);
|
|
Config::Instance()->UpscaleRatioOverrideValue = urOverride;
|
|
|
|
ImGui::EndDisabled();
|
|
|
|
ImGui::TableNextColumn();
|
|
|
|
// QUALITY OVERRIDES -----------------------------
|
|
ImGui::SeparatorText("Quality Overrides");
|
|
|
|
if (bool qOverride = Config::Instance()->QualityRatioOverrideEnabled.value_or(false); ImGui::Checkbox("Quality Override", &qOverride))
|
|
Config::Instance()->QualityRatioOverrideEnabled = qOverride;
|
|
|
|
ImGui::BeginDisabled(!Config::Instance()->QualityRatioOverrideEnabled.value_or(false));
|
|
|
|
float qUq = Config::Instance()->QualityRatio_UltraQuality.value_or(1.3f);
|
|
ImGui::SliderFloat("Ultra Quality", &qUq, 1.0f, 3.0f, "%.3f", ImGuiSliderFlags_NoRoundToFormat);
|
|
Config::Instance()->QualityRatio_UltraQuality = qUq;
|
|
|
|
float qQ = Config::Instance()->QualityRatio_Quality.value_or(1.5f);
|
|
ImGui::SliderFloat("Quality", &qQ, 1.0f, 3.0f, "%.3f", ImGuiSliderFlags_NoRoundToFormat);
|
|
Config::Instance()->QualityRatio_Quality = qQ;
|
|
|
|
float qB = Config::Instance()->QualityRatio_Balanced.value_or(1.7f);
|
|
ImGui::SliderFloat("Balanced", &qB, 1.0f, 3.0f, "%.3f", ImGuiSliderFlags_NoRoundToFormat);
|
|
Config::Instance()->QualityRatio_Balanced = qB;
|
|
|
|
float qP = Config::Instance()->QualityRatio_Performance.value_or(2.0f);
|
|
ImGui::SliderFloat("Performance", &qP, 1.0f, 3.0f, "%.3f", ImGuiSliderFlags_NoRoundToFormat);
|
|
Config::Instance()->QualityRatio_Performance = qP;
|
|
|
|
float qUp = Config::Instance()->QualityRatio_UltraPerformance.value_or(3.0f);
|
|
ImGui::SliderFloat("Ultra Performance", &qUp, 1.0f, 3.0f, "%.3f", ImGuiSliderFlags_NoRoundToFormat);
|
|
Config::Instance()->QualityRatio_UltraPerformance = qUp;
|
|
|
|
ImGui::EndDisabled();
|
|
|
|
// INIT -----------------------------
|
|
ImGui::SeparatorText("Init Flags");
|
|
if (ImGui::BeginTable("init", 2))
|
|
{
|
|
ImGui::TableNextColumn();
|
|
if (bool autoExposure = Config::Instance()->AutoExposure.value_or(false); ImGui::Checkbox("Auto Exposure", &autoExposure))
|
|
{
|
|
Config::Instance()->AutoExposure = autoExposure;
|
|
Config::Instance()->changeBackend = true;
|
|
}
|
|
|
|
ImGui::TableNextColumn();
|
|
if (bool hdr = Config::Instance()->HDR.value_or(false); ImGui::Checkbox("HDR", &hdr))
|
|
{
|
|
Config::Instance()->HDR = hdr;
|
|
Config::Instance()->changeBackend = true;
|
|
}
|
|
|
|
ImGui::TableNextColumn();
|
|
if (bool depth = Config::Instance()->DepthInverted.value_or(false); ImGui::Checkbox("Depth Inverted", &depth))
|
|
{
|
|
Config::Instance()->DepthInverted = depth;
|
|
Config::Instance()->changeBackend = true;
|
|
}
|
|
|
|
ImGui::TableNextColumn();
|
|
if (bool jitter = Config::Instance()->JitterCancellation.value_or(false); ImGui::Checkbox("Jitter Cancellation", &jitter))
|
|
{
|
|
Config::Instance()->JitterCancellation = jitter;
|
|
Config::Instance()->changeBackend = true;
|
|
}
|
|
|
|
ImGui::TableNextColumn();
|
|
if (bool mv = Config::Instance()->DisplayResolution.value_or(false); ImGui::Checkbox("Display Res. MV", &mv))
|
|
{
|
|
Config::Instance()->DisplayResolution = mv;
|
|
Config::Instance()->changeBackend = true;
|
|
}
|
|
|
|
ImGui::TableNextColumn();
|
|
if (bool rm = Config::Instance()->DisableReactiveMask.value_or(true); ImGui::Checkbox("Disable Reactive Mask", &rm))
|
|
{
|
|
Config::Instance()->DisableReactiveMask = rm;
|
|
Config::Instance()->changeBackend = true;
|
|
}
|
|
|
|
ImGui::EndTable();
|
|
}
|
|
|
|
// BARRIERS -----------------------------
|
|
ImGui::SeparatorText("Resource Barriers (Dx12)");
|
|
ImGui::BeginDisabled(Config::Instance()->Api != NVNGX_DX12);
|
|
|
|
AddResourceBarrier("Color", &Config::Instance()->ColorResourceBarrier);
|
|
AddResourceBarrier("Depth", &Config::Instance()->DepthResourceBarrier);
|
|
AddResourceBarrier("Motion", &Config::Instance()->MVResourceBarrier);
|
|
AddResourceBarrier("Exposure", &Config::Instance()->ExposureResourceBarrier);
|
|
AddResourceBarrier("Mask", &Config::Instance()->MaskResourceBarrier);
|
|
AddResourceBarrier("Output", &Config::Instance()->OutputResourceBarrier);
|
|
|
|
ImGui::EndDisabled();
|
|
|
|
// HOTFIXES -----------------------------
|
|
ImGui::SeparatorText("Hotfixes (Dx12)");
|
|
|
|
ImGui::BeginDisabled(Config::Instance()->Api != NVNGX_DX12);
|
|
|
|
if (bool crs = Config::Instance()->RestoreComputeSignature.value_or(false); ImGui::Checkbox("Restore Compute RS", &crs))
|
|
Config::Instance()->RestoreComputeSignature = crs;
|
|
|
|
ImGui::SameLine(0.0f, 6.0f);
|
|
if (bool grs = Config::Instance()->RestoreGraphicSignature.value_or(false); ImGui::Checkbox("Restore Graphic RS", &grs))
|
|
Config::Instance()->RestoreGraphicSignature = grs;
|
|
|
|
ImGui::EndDisabled();
|
|
|
|
// LOGGING -----------------------------
|
|
ImGui::SeparatorText("Logging");
|
|
|
|
if (bool logging = Config::Instance()->LoggingEnabled.value_or(true); ImGui::Checkbox("Logging", &logging))
|
|
{
|
|
Config::Instance()->LoggingEnabled = logging;
|
|
|
|
if (logging)
|
|
spdlog::default_logger()->set_level((spdlog::level::level_enum)Config::Instance()->LogLevel.value_or(2));
|
|
else
|
|
spdlog::default_logger()->set_level(spdlog::level::off);
|
|
}
|
|
|
|
ImGui::SameLine(0.0f, 6.0f);
|
|
if (bool toFile = Config::Instance()->LogToFile.value_or(false); ImGui::Checkbox("To File", &toFile))
|
|
{
|
|
Config::Instance()->LogToFile = toFile;
|
|
PrepareLogger();
|
|
}
|
|
|
|
ImGui::SameLine(0.0f, 6.0f);
|
|
if (bool toConsole = Config::Instance()->LogToConsole.value_or(false); ImGui::Checkbox("To Console", &toConsole))
|
|
{
|
|
Config::Instance()->LogToConsole = toConsole;
|
|
PrepareLogger();
|
|
}
|
|
|
|
const char* logLevels[] = { "Trace", "Debug", "Information", "Warning", "Error" };
|
|
const char* selectedLevel = logLevels[Config::Instance()->LogLevel.value_or(2)];
|
|
|
|
if (ImGui::BeginCombo("Log Level", selectedLevel))
|
|
{
|
|
for (int n = 0; n < 5; n++)
|
|
{
|
|
if (ImGui::Selectable(logLevels[n], (Config::Instance()->LogLevel.value_or(2) == n)))
|
|
{
|
|
Config::Instance()->LogLevel = n;
|
|
spdlog::default_logger()->set_level((spdlog::level::level_enum)Config::Instance()->LogLevel.value_or(2));
|
|
}
|
|
}
|
|
|
|
ImGui::EndCombo();
|
|
}
|
|
|
|
ImGui::EndTable();
|
|
|
|
// BOTTOM LINE ---------------
|
|
ImGui::Spacing();
|
|
ImGui::Separator();
|
|
ImGui::Spacing();
|
|
|
|
auto cf = Config::Instance()->CurrentFeature;
|
|
if (cf != nullptr)
|
|
ImGui::Text("%dx%d -> %dx%d (%dx%d)", cf->RenderWidth(), cf->RenderHeight(), cf->TargetWidth(), cf->TargetHeight(), cf->DisplayWidth(), cf->DisplayHeight());
|
|
|
|
ImGui::SameLine(0.0f, 4.0f);
|
|
|
|
ImGui::Text("%.3f ms/frame (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate);
|
|
|
|
ImGui::SameLine(ImGui::GetWindowWidth() - 130.0f);
|
|
|
|
if (ImGui::Button("Save INI"))
|
|
Config::Instance()->SaveIni();
|
|
|
|
ImGui::SameLine(0.0f, 6.0f);
|
|
|
|
if (ImGui::Button("Close"))
|
|
{
|
|
showMipmapCalcWindow = false;
|
|
_isVisible = false;
|
|
}
|
|
|
|
ImGui::Spacing();
|
|
ImGui::Separator();
|
|
}
|
|
|
|
auto pos = ImGui::GetWindowPos();
|
|
_top = pos.y;
|
|
_left = pos.x;
|
|
|
|
auto size = ImGui::GetWindowSize();
|
|
_width = size.x;
|
|
_height = size.y;
|
|
|
|
ImGui::End();
|
|
}
|
|
|
|
if (showMipmapCalcWindow)
|
|
{
|
|
posX = (Config::Instance()->CurrentFeature->DisplayWidth() - 450.0f) / 2.0f;
|
|
posY = (Config::Instance()->CurrentFeature->DisplayHeight() - 200.0f) / 2.0f;
|
|
|
|
ImGui::SetNextWindowPos(ImVec2{ posX , posY }, ImGuiCond_FirstUseEver);
|
|
ImGui::SetNextWindowSize(ImVec2{ 450.0f, 200.0f }, ImGuiCond_FirstUseEver);
|
|
|
|
if (displayWidth == 0)
|
|
{
|
|
displayWidth = Config::Instance()->CurrentFeature->DisplayWidth();
|
|
renderWidth = displayWidth / 3.0;
|
|
mipmapUpscalerQuality = 0;
|
|
mipmapUpscalerRatio = 3.0f;
|
|
mipBiasCalculated = log2((float)renderWidth / (float)displayWidth);
|
|
}
|
|
|
|
if (ImGui::Begin("Mipmap Bias", nullptr, flags))
|
|
{
|
|
if (ImGui::InputScalar("Display Width", ImGuiDataType_U32, &displayWidth, NULL, NULL, "%u"))
|
|
{
|
|
if (displayWidth <= 0)
|
|
displayWidth = Config::Instance()->CurrentFeature->DisplayWidth();
|
|
|
|
renderWidth = displayWidth / mipmapUpscalerRatio;
|
|
mipBiasCalculated = log2((float)renderWidth / (float)displayWidth);
|
|
}
|
|
|
|
const char* q[] = { "Ultra Performance", "Performance", "Balanced", "Quality", "Ultra Quality", "DLAA" };
|
|
float xr[] = { 3.0f, 2.3f, 2.0f, 1.7f, 1.5f, 1.0f };
|
|
float fr[] = { 3.0f, 2.0f, 1.7f, 1.5f, 1.3f, 1.0f };
|
|
auto configQ = mipmapUpscalerQuality;
|
|
|
|
const char* selectedQ = q[configQ];
|
|
|
|
ImGui::BeginDisabled(Config::Instance()->UpscaleRatioOverrideEnabled.value_or(false));
|
|
|
|
if (ImGui::BeginCombo("Upscaler Quality", selectedQ))
|
|
{
|
|
for (int n = 0; n < 6; n++)
|
|
{
|
|
if (ImGui::Selectable(q[n], (mipmapUpscalerQuality == n)))
|
|
{
|
|
mipmapUpscalerQuality = n;
|
|
|
|
float ov = -1.0f;
|
|
|
|
if (Config::Instance()->QualityRatioOverrideEnabled.value_or(false))
|
|
{
|
|
switch (n)
|
|
{
|
|
case 0:
|
|
ov = Config::Instance()->QualityRatio_UltraPerformance.value_or(-1.0f);
|
|
break;
|
|
|
|
case 1:
|
|
ov = Config::Instance()->QualityRatio_Performance.value_or(-1.0f);
|
|
break;
|
|
|
|
case 2:
|
|
ov = Config::Instance()->QualityRatio_Balanced.value_or(-1.0f);
|
|
break;
|
|
|
|
case 3:
|
|
ov = Config::Instance()->QualityRatio_Quality.value_or(-1.0f);
|
|
break;
|
|
|
|
case 4:
|
|
ov = Config::Instance()->QualityRatio_UltraQuality.value_or(-1.0f);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (ov > 0.0f)
|
|
{
|
|
mipmapUpscalerRatio = ov;
|
|
}
|
|
else
|
|
{
|
|
if (Config::Instance()->Dx12Upscaler.value_or("xess") == "xess")
|
|
mipmapUpscalerRatio = xr[n];
|
|
else
|
|
mipmapUpscalerRatio = fr[n];
|
|
}
|
|
|
|
renderWidth = displayWidth / mipmapUpscalerRatio;
|
|
mipBiasCalculated = log2((float)renderWidth / (float)displayWidth);
|
|
}
|
|
}
|
|
|
|
ImGui::EndCombo();
|
|
}
|
|
|
|
ImGui::EndDisabled();
|
|
|
|
if (ImGui::SliderFloat("Upscaler Ratio", &mipmapUpscalerRatio, 1.0f, 3.0f, "%.3f", ImGuiSliderFlags_NoRoundToFormat))
|
|
{
|
|
renderWidth = displayWidth / mipmapUpscalerRatio;
|
|
mipBiasCalculated = log2((float)renderWidth / (float)displayWidth);
|
|
}
|
|
|
|
if (ImGui::InputScalar("Render Width", ImGuiDataType_U32, &renderWidth, NULL, NULL, "%u"))
|
|
mipBiasCalculated = log2((float)renderWidth / (float)displayWidth);
|
|
|
|
ImGui::SliderFloat("Mipmap Bias", &mipBiasCalculated, -15.0f, 0.0f, "%.6f", ImGuiSliderFlags_NoRoundToFormat);
|
|
|
|
// BOTTOM LINE
|
|
ImGui::Spacing();
|
|
ImGui::Separator();
|
|
ImGui::Spacing();
|
|
|
|
ImGui::SameLine(ImGui::GetWindowWidth() - 130.0f);
|
|
|
|
if (ImGui::Button("Use Value"))
|
|
{
|
|
mipBias = mipBiasCalculated;
|
|
showMipmapCalcWindow = false;
|
|
}
|
|
|
|
ImGui::SameLine(0.0f, 6.0f);
|
|
|
|
if (ImGui::Button("Close"))
|
|
showMipmapCalcWindow = false;
|
|
|
|
ImGui::Spacing();
|
|
ImGui::Separator();
|
|
|
|
ImGui::End();
|
|
}
|
|
}
|
|
}
|
|
|
|
ImGui::Render();
|
|
}
|
|
|
|
bool Imgui_Base::IsHandleDifferent()
|
|
{
|
|
DWORD procId;
|
|
|
|
HWND frontWindow = GetForegroundWindow(); // Util::GetProcessWindow(); -- for linux compatibility
|
|
GetWindowThreadProcessId(frontWindow, &procId);
|
|
|
|
if (processId != procId)
|
|
return false;
|
|
|
|
if (frontWindow == _handle)
|
|
return false;
|
|
|
|
_handle = frontWindow;
|
|
|
|
return true;
|
|
}
|
|
|
|
Imgui_Base::Imgui_Base(HWND handle)
|
|
{
|
|
// Setup Dear ImGui context
|
|
IMGUI_CHECKVERSION();
|
|
context = ImGui::CreateContext();
|
|
ImGui::SetCurrentContext(context);
|
|
ImGui::StyleColorsDark();
|
|
|
|
auto style = ImGui::GetStyle();
|
|
style.Colors[ImGuiCol_WindowBg] = ImVec4(0.1f, 0.1f, 0.1f, 0.20f);
|
|
style.Colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.10f, 0.10f, 0.10f, 0.20f);
|
|
|
|
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
|
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;
|
|
|
|
io.MouseDrawCursor = _isVisible;
|
|
io.WantCaptureKeyboard = _isVisible;
|
|
io.WantCaptureMouse = _isVisible;
|
|
io.WantSetMousePos = _isVisible;
|
|
|
|
_handle = handle;
|
|
|
|
_baseInit = ImGui_ImplWin32_Init(_handle);
|
|
|
|
if (IsHandleDifferent())
|
|
return;
|
|
|
|
if (_oWndProc == nullptr)
|
|
_oWndProc = (WNDPROC)SetWindowLongPtr(_handle, GWLP_WNDPROC, (LONG_PTR)WndProc);
|
|
|
|
if (!pfn_SetCursorPos_hooked)
|
|
AttachHooks();
|
|
}
|
|
|
|
Imgui_Base::~Imgui_Base()
|
|
{
|
|
if (!_baseInit)
|
|
return;
|
|
|
|
if (auto currCtx = ImGui::GetCurrentContext(); currCtx && context != currCtx)
|
|
{
|
|
ImGui::SetCurrentContext(context);
|
|
ImGui_ImplWin32_Shutdown();
|
|
ImGui::SetCurrentContext(currCtx);
|
|
}
|
|
else
|
|
{
|
|
if (_oWndProc != nullptr)
|
|
{
|
|
SetWindowLongPtr((HWND)ImGui::GetMainViewport()->PlatformHandleRaw, GWLP_WNDPROC, (LONG_PTR)_oWndProc);
|
|
_oWndProc = nullptr;
|
|
}
|
|
|
|
if (pfn_SetCursorPos_hooked)
|
|
DetachHooks();
|
|
|
|
ImGui_ImplWin32_Shutdown();
|
|
}
|
|
|
|
ImGui::DestroyContext(context);
|
|
}
|
|
|
|
bool Imgui_Base::IsVisible() const
|
|
{
|
|
return _isVisible;
|
|
}
|
|
|
|
void Imgui_Base::SetVisible(bool visible) const
|
|
{
|
|
_isVisible = visible;
|
|
} |