Compare commits
No commits in common. "c9a102ee302f1cb95bf8fe2d999bf2045ba78476" and "97a1ff5186f6069b57086ab0e6e9512f69fa2bbf" have entirely different histories.
c9a102ee30
...
97a1ff5186
|
@ -26,12 +26,19 @@
|
||||||
#include "System/System.h"
|
#include "System/System.h"
|
||||||
#include "System/Library.h"
|
#include "System/Library.h"
|
||||||
#include "System/ScopedLock.hpp"
|
#include "System/ScopedLock.hpp"
|
||||||
#define GLAD_GL_IMPLEMENTATION
|
|
||||||
#include <glad/gl.h>
|
|
||||||
|
|
||||||
#if defined(WIN64) || defined(_WIN64) || defined(__MINGW64__) \
|
#if defined(WIN64) || defined(_WIN64) || defined(__MINGW64__) \
|
||||||
|| defined(WIN32) || defined(_WIN32) || defined(__MINGW32__)
|
|| defined(WIN32) || defined(_WIN32) || defined(__MINGW32__)
|
||||||
#define RENDERERDETECTOR_OS_WINDOWS
|
#define RENDERERDETECTOR_OS_WINDOWS
|
||||||
|
#elif defined(__linux__) || defined(linux)
|
||||||
|
#define RENDERERDETECTOR_OS_LINUX
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
#define RENDERERDETECTOR_OS_APPLE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef RENDERERDETECTOR_OS_WINDOWS
|
||||||
|
#define GLAD_GL_IMPLEMENTATION
|
||||||
|
#include <glad/gl.h>
|
||||||
|
|
||||||
#include "windows/DX12_Hook.h"
|
#include "windows/DX12_Hook.h"
|
||||||
#include "windows/DX11_Hook.h"
|
#include "windows/DX11_Hook.h"
|
||||||
|
@ -48,18 +55,6 @@
|
||||||
#undef GetModuleHandle
|
#undef GetModuleHandle
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#elif defined(__linux__) || defined(linux)
|
|
||||||
#define RENDERERDETECTOR_OS_LINUX
|
|
||||||
|
|
||||||
#include "linux/OpenGLX_Hook.h"
|
|
||||||
|
|
||||||
#elif defined(__APPLE__)
|
|
||||||
#define RENDERERDETECTOR_OS_APPLE
|
|
||||||
|
|
||||||
#include "macosx/OpenGL_Hook.h"
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class Renderer_Detector
|
class Renderer_Detector
|
||||||
{
|
{
|
||||||
static Renderer_Detector* instance;
|
static Renderer_Detector* instance;
|
||||||
|
@ -73,29 +68,63 @@ public:
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(RENDERERDETECTOR_OS_WINDOWS)
|
static void deleteInst()
|
||||||
#define RENDERER_HOOKS { OpenGL_Hook::DLL_NAME, &Renderer_Detector::hook_opengl },\
|
{
|
||||||
{ Vulkan_Hook::DLL_NAME, &Renderer_Detector::hook_vulkan },\
|
if (instance != nullptr)
|
||||||
{ DX12_Hook::DLL_NAME, &Renderer_Detector::hook_dx12 },\
|
{
|
||||||
{ DX11_Hook::DLL_NAME, &Renderer_Detector::hook_dx11 },\
|
delete instance;
|
||||||
{ DX10_Hook::DLL_NAME, &Renderer_Detector::hook_dx10 },\
|
instance = nullptr;
|
||||||
{ DX9_Hook::DLL_NAME, &Renderer_Detector::hook_dx9 },
|
}
|
||||||
|
}
|
||||||
|
|
||||||
~Renderer_Detector()
|
~Renderer_Detector()
|
||||||
{
|
{
|
||||||
stop_detection();
|
|
||||||
|
|
||||||
delete dx9_hook;
|
delete dx9_hook;
|
||||||
delete dx10_hook;
|
delete dx10_hook;
|
||||||
delete dx11_hook;
|
delete dx11_hook;
|
||||||
delete dx12_hook;
|
delete dx12_hook;
|
||||||
delete opengl_hook;
|
delete opengl_hook;
|
||||||
delete vulkan_hook;
|
delete vulkan_hook;
|
||||||
|
|
||||||
instance = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Renderer_Detector():
|
||||||
|
dxgi_hooked(false),
|
||||||
|
dxgi1_2_hooked(false),
|
||||||
|
dx12_hooked(false),
|
||||||
|
dx11_hooked(false),
|
||||||
|
dx10_hooked(false),
|
||||||
|
dx9_hooked(false),
|
||||||
|
opengl_hooked(false),
|
||||||
|
vulkan_hooked(false),
|
||||||
|
renderer_hook(nullptr),
|
||||||
|
dx9_hook(nullptr),
|
||||||
|
dx10_hook(nullptr),
|
||||||
|
dx11_hook(nullptr),
|
||||||
|
dx12_hook(nullptr),
|
||||||
|
opengl_hook(nullptr),
|
||||||
|
vulkan_hook(nullptr),
|
||||||
|
detection_done(false),
|
||||||
|
force_done(false)
|
||||||
|
{
|
||||||
|
std::wstring tmp(4096, L'\0');
|
||||||
|
tmp.resize(GetSystemDirectoryW(&tmp[0], tmp.size()));
|
||||||
|
_SystemDir = System::Encoding::WCharToUtf8(tmp);
|
||||||
|
|
||||||
|
System::String::ToLower(_SystemDir);
|
||||||
|
|
||||||
|
wchar_t random_str[] = L"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||||
|
std::random_device rd;
|
||||||
|
std::mt19937_64 gen(rd());
|
||||||
|
|
||||||
|
std::uniform_int_distribution<uint64_t> dis(0, 61);
|
||||||
|
_WindowClassName.resize(64);
|
||||||
|
for (int i = 0; i < 64; ++i)
|
||||||
|
_WindowClassName[i] = random_str[dis(gen)];
|
||||||
|
}
|
||||||
|
|
||||||
|
std::timed_mutex detector_mutex;
|
||||||
|
std::mutex renderer_mutex;
|
||||||
|
|
||||||
decltype(&IDXGISwapChain::Present) IDXGISwapChainPresent;
|
decltype(&IDXGISwapChain::Present) IDXGISwapChainPresent;
|
||||||
decltype(&IDXGISwapChain1::Present1) IDXGISwapChainPresent1;
|
decltype(&IDXGISwapChain1::Present1) IDXGISwapChainPresent1;
|
||||||
|
@ -114,6 +143,8 @@ private:
|
||||||
bool opengl_hooked;
|
bool opengl_hooked;
|
||||||
bool vulkan_hooked;
|
bool vulkan_hooked;
|
||||||
|
|
||||||
|
Base_Hook detection_hooks;
|
||||||
|
ingame_overlay::Renderer_Hook* renderer_hook;
|
||||||
DX12_Hook* dx12_hook;
|
DX12_Hook* dx12_hook;
|
||||||
DX11_Hook* dx11_hook;
|
DX11_Hook* dx11_hook;
|
||||||
DX10_Hook* dx10_hook;
|
DX10_Hook* dx10_hook;
|
||||||
|
@ -121,47 +152,15 @@ private:
|
||||||
OpenGL_Hook* opengl_hook;
|
OpenGL_Hook* opengl_hook;
|
||||||
Vulkan_Hook* vulkan_hook;
|
Vulkan_Hook* vulkan_hook;
|
||||||
|
|
||||||
|
bool detection_done, force_done;
|
||||||
|
std::condition_variable stop_detection_cv;
|
||||||
|
std::mutex stop_detection_mutex;
|
||||||
|
|
||||||
HWND dummyWindow = nullptr;
|
HWND dummyWindow = nullptr;
|
||||||
std::wstring _WindowClassName;
|
std::wstring _WindowClassName;
|
||||||
std::string _SystemDir;
|
std::string _SystemDir;
|
||||||
ATOM atom = 0;
|
ATOM atom = 0;
|
||||||
|
|
||||||
Renderer_Detector() :
|
|
||||||
dxgi_hooked(false),
|
|
||||||
dxgi1_2_hooked(false),
|
|
||||||
dx12_hooked(false),
|
|
||||||
dx11_hooked(false),
|
|
||||||
dx10_hooked(false),
|
|
||||||
dx9_hooked(false),
|
|
||||||
opengl_hooked(false),
|
|
||||||
vulkan_hooked(false),
|
|
||||||
renderer_hook(nullptr),
|
|
||||||
dx9_hook(nullptr),
|
|
||||||
dx10_hook(nullptr),
|
|
||||||
dx11_hook(nullptr),
|
|
||||||
dx12_hook(nullptr),
|
|
||||||
opengl_hook(nullptr),
|
|
||||||
vulkan_hook(nullptr),
|
|
||||||
detection_done(false),
|
|
||||||
detection_count(0),
|
|
||||||
detection_cancelled(false)
|
|
||||||
{
|
|
||||||
std::wstring tmp(4096, L'\0');
|
|
||||||
tmp.resize(GetSystemDirectoryW(&tmp[0], tmp.size()));
|
|
||||||
_SystemDir = System::Encoding::WCharToUtf8(tmp);
|
|
||||||
|
|
||||||
System::String::ToLower(_SystemDir);
|
|
||||||
|
|
||||||
wchar_t random_str[] = L"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
|
||||||
std::random_device rd;
|
|
||||||
std::mt19937_64 gen(rd());
|
|
||||||
|
|
||||||
std::uniform_int_distribution<uint64_t> dis(0, 61);
|
|
||||||
_WindowClassName.resize(64);
|
|
||||||
for (int i = 0; i < 64; ++i)
|
|
||||||
_WindowClassName[i] = random_str[dis(gen)];
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string FindPreferedModulePath(std::string const& name)
|
std::string FindPreferedModulePath(std::string const& name)
|
||||||
{
|
{
|
||||||
std::string res;
|
std::string res;
|
||||||
|
@ -983,8 +982,7 @@ private:
|
||||||
phyDevices.resize(count);
|
phyDevices.resize(count);
|
||||||
vkEnumeratePhysicalDevices(instance, &count, phyDevices.data());
|
vkEnumeratePhysicalDevices(instance, &count, phyDevices.data());
|
||||||
|
|
||||||
[&]()
|
[&]() {
|
||||||
{// Lambda for nested for break.
|
|
||||||
VkPhysicalDeviceProperties props{};
|
VkPhysicalDeviceProperties props{};
|
||||||
std::vector<VkExtensionProperties> ext_props;
|
std::vector<VkExtensionProperties> ext_props;
|
||||||
|
|
||||||
|
@ -1043,13 +1041,65 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EnterDetection()
|
public:
|
||||||
|
ingame_overlay::Renderer_Hook* detect_renderer(std::chrono::milliseconds timeout)
|
||||||
{
|
{
|
||||||
return CreateHWND() != nullptr;
|
std::unique_lock<std::timed_mutex> detection_lock(detector_mutex, std::defer_lock);
|
||||||
|
|
||||||
|
if (!detection_lock.try_lock_for(timeout))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lk(renderer_mutex);
|
||||||
|
if (detection_done)
|
||||||
|
{
|
||||||
|
if (renderer_hook != nullptr || force_done)
|
||||||
|
return renderer_hook;
|
||||||
|
|
||||||
|
detection_done = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExitDetection()
|
if (CreateHWND() == nullptr)
|
||||||
{
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SPDLOG_TRACE("Started renderer detection.");
|
||||||
|
|
||||||
|
std::pair<std::string, void(Renderer_Detector::*)(std::string const&)> libraries[]{
|
||||||
|
{OpenGL_Hook::DLL_NAME, &Renderer_Detector::hook_opengl},
|
||||||
|
{Vulkan_Hook::DLL_NAME, &Renderer_Detector::hook_vulkan},
|
||||||
|
{ DX12_Hook::DLL_NAME, &Renderer_Detector::hook_dx12 },
|
||||||
|
{ DX11_Hook::DLL_NAME, &Renderer_Detector::hook_dx11 },
|
||||||
|
{ DX10_Hook::DLL_NAME, &Renderer_Detector::hook_dx10 },
|
||||||
|
{ DX9_Hook::DLL_NAME, &Renderer_Detector::hook_dx9 },
|
||||||
|
};
|
||||||
|
std::string name;
|
||||||
|
|
||||||
|
auto start_time = std::chrono::steady_clock::now();
|
||||||
|
do
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lck(stop_detection_mutex);
|
||||||
|
if (detection_done)
|
||||||
|
break;
|
||||||
|
|
||||||
|
for (auto const& library : libraries)
|
||||||
|
{
|
||||||
|
void* lib_handle = System::Library::GetLibraryHandle(library.first.c_str());
|
||||||
|
if (lib_handle != nullptr)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lk(renderer_mutex);
|
||||||
|
name = FindPreferedModulePath(library.first);
|
||||||
|
(this->*library.second)(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stop_detection_cv.wait_for(lck, std::chrono::milliseconds{ 100 });
|
||||||
|
} while (!detection_done && (timeout.count() == -1 || (std::chrono::steady_clock::now() - start_time) <= timeout));
|
||||||
|
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lk(renderer_mutex);
|
||||||
DestroyHWND();
|
DestroyHWND();
|
||||||
|
|
||||||
detection_done = true;
|
detection_done = true;
|
||||||
|
@ -1072,42 +1122,74 @@ private:
|
||||||
delete vulkan_hook; vulkan_hook = nullptr;
|
delete vulkan_hook; vulkan_hook = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SPDLOG_TRACE("Renderer detection done {}.", (void*)renderer_hook);
|
||||||
|
|
||||||
|
return renderer_hook;
|
||||||
|
}
|
||||||
|
|
||||||
|
void stop_detection()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
System::scoped_lock lk(renderer_mutex, stop_detection_mutex);
|
||||||
|
detection_done = true;
|
||||||
|
force_done = true;
|
||||||
|
}
|
||||||
|
stop_detection_cv.notify_all();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Renderer_Detector* Renderer_Detector::instance = nullptr;
|
||||||
|
|
||||||
#elif defined(RENDERERDETECTOR_OS_LINUX)
|
#elif defined(RENDERERDETECTOR_OS_LINUX)
|
||||||
#define RENDERER_HOOKS { OpenGLX_Hook::DLL_NAME, &Renderer_Detector::hook_openglx },
|
#define GLAD_GL_IMPLEMENTATION
|
||||||
|
#include <glad/gl.h>
|
||||||
|
|
||||||
|
#include "linux/OpenGLX_Hook.h"
|
||||||
|
|
||||||
|
class Renderer_Detector
|
||||||
|
{
|
||||||
|
static Renderer_Detector* instance;
|
||||||
|
public:
|
||||||
|
static Renderer_Detector* Inst()
|
||||||
|
{
|
||||||
|
if (instance == nullptr)
|
||||||
|
{
|
||||||
|
instance = new Renderer_Detector;
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
~Renderer_Detector()
|
~Renderer_Detector()
|
||||||
{
|
{
|
||||||
stop_detection();
|
|
||||||
|
|
||||||
delete openglx_hook;
|
delete openglx_hook;
|
||||||
//delete vulkan_hook;
|
//delete vulkan_hook;
|
||||||
|
|
||||||
instance = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
decltype(::glXSwapBuffers)* glXSwapBuffers;
|
|
||||||
|
|
||||||
bool openglx_hooked;
|
|
||||||
//bool vulkan_hooked;
|
|
||||||
|
|
||||||
OpenGLX_Hook* openglx_hook;
|
|
||||||
//Vulkan_Hook* vulkan_hook;
|
|
||||||
|
|
||||||
Renderer_Detector() :
|
Renderer_Detector() :
|
||||||
openglx_hooked(false),
|
openglx_hooked(false),
|
||||||
renderer_hook(nullptr),
|
renderer_hook(nullptr),
|
||||||
openglx_hook(nullptr),
|
openglx_hook(nullptr),
|
||||||
//vulkan_hook(nullptr),
|
//vulkan_hook(nullptr),
|
||||||
detection_done(false),
|
detection_done(false)
|
||||||
detection_count(0),
|
|
||||||
detection_cancelled(false)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
std::string FindPreferedModulePath(std::string const& name)
|
std::timed_mutex detector_mutex;
|
||||||
{
|
std::mutex renderer_mutex;
|
||||||
return name;
|
|
||||||
}
|
Base_Hook detection_hooks;
|
||||||
|
|
||||||
|
decltype(::glXSwapBuffers)* glXSwapBuffers;
|
||||||
|
|
||||||
|
bool openglx_hooked;
|
||||||
|
//bool vulkan_hooked;
|
||||||
|
|
||||||
|
ingame_overlay::Renderer_Hook* renderer_hook;
|
||||||
|
OpenGLX_Hook* openglx_hook;
|
||||||
|
|
||||||
|
bool detection_done;
|
||||||
|
std::condition_variable stop_detection_cv;
|
||||||
|
std::mutex stop_detection_mutex;
|
||||||
|
|
||||||
static void MyglXSwapBuffers(Display* dpy, GLXDrawable drawable)
|
static void MyglXSwapBuffers(Display* dpy, GLXDrawable drawable)
|
||||||
{
|
{
|
||||||
|
@ -1166,57 +1248,128 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EnterDetection()
|
public:
|
||||||
|
ingame_overlay::Renderer_Hook* detect_renderer(std::chrono::milliseconds timeout)
|
||||||
{
|
{
|
||||||
return true;
|
std::pair<const char*, void(Renderer_Detector::*)(std::string const&)> libraries[]{
|
||||||
|
std::pair<const char*, void(Renderer_Detector::*)(std::string const&)>{OpenGLX_Hook::DLL_NAME, &Renderer_Detector::hook_openglx},
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unique_lock<std::timed_mutex> detection_lock(detector_mutex, std::defer_lock);
|
||||||
|
|
||||||
|
if (!detection_lock.try_lock_for(timeout))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lk(renderer_mutex);
|
||||||
|
if (detection_done)
|
||||||
|
{
|
||||||
|
if (renderer_hook != nullptr || force_done)
|
||||||
|
return renderer_hook;
|
||||||
|
|
||||||
|
detection_done = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExitDetection()
|
SPDLOG_TRACE("Started renderer detection.");
|
||||||
|
|
||||||
|
auto start_time = std::chrono::steady_clock::now();
|
||||||
|
do
|
||||||
{
|
{
|
||||||
|
std::unique_lock<std::mutex> lck(stop_detection_mutex);
|
||||||
|
if (detection_done)
|
||||||
|
break;
|
||||||
|
|
||||||
|
for (auto const& library : libraries)
|
||||||
|
{
|
||||||
|
void* lib_handle = System::Library::GetLibraryHandle(library.first);
|
||||||
|
if (lib_handle != nullptr)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lk(renderer_mutex);
|
||||||
|
std::string lib_path = System::Library::GetLibraryPath(lib_handle);
|
||||||
|
(this->*library.second)(lib_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stop_detection_cv.wait_for(lck, std::chrono::milliseconds{ 100 });
|
||||||
|
} while (!detection_done && (timeout.count() == -1 || (std::chrono::steady_clock::now() - start_time) <= timeout));
|
||||||
|
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lk(renderer_mutex);
|
||||||
|
|
||||||
detection_done = true;
|
detection_done = true;
|
||||||
detection_hooks.UnhookAll();
|
detection_hooks.UnhookAll();
|
||||||
|
|
||||||
openglx_hooked = false;
|
openglx_hooked = false;
|
||||||
//vulkan_hooked = false;
|
|
||||||
|
|
||||||
delete openglx_hook; openglx_hook = nullptr;
|
delete openglx_hook; openglx_hook = nullptr;
|
||||||
//delete vulkan_hook; vulkan_hook = nullptr;
|
//delete vulkan_hook; vulkan_hook = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SPDLOG_TRACE("Renderer detection done {}.", (void*)renderer_hook);
|
||||||
|
|
||||||
|
return renderer_hook;
|
||||||
|
}
|
||||||
|
|
||||||
|
void stop_detection()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
System::scoped_lock lk(renderer_mutex, stop_detection_mutex);
|
||||||
|
detection_done = true;
|
||||||
|
force_done = true;
|
||||||
|
}
|
||||||
|
stop_detection_cv.notify_all();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Renderer_Detector* Renderer_Detector::instance = nullptr;
|
||||||
|
|
||||||
#elif defined(RENDERERDETECTOR_OS_APPLE)
|
#elif defined(RENDERERDETECTOR_OS_APPLE)
|
||||||
#define RENDERER_HOOKS { OpenGL_Hook::DLL_NAME, & Renderer_Detector::hook_opengl },
|
#include "macosx/OpenGL_Hook.h"
|
||||||
|
#define GLAD_GL_IMPLEMENTATION
|
||||||
|
#include <glad/gl.h>
|
||||||
|
|
||||||
|
class Renderer_Detector
|
||||||
|
{
|
||||||
|
static Renderer_Detector* instance;
|
||||||
|
public:
|
||||||
|
static Renderer_Detector* Inst()
|
||||||
|
{
|
||||||
|
if (instance == nullptr)
|
||||||
|
{
|
||||||
|
instance = new Renderer_Detector;
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
~Renderer_Detector()
|
~Renderer_Detector()
|
||||||
{
|
{
|
||||||
stop_detection();
|
|
||||||
|
|
||||||
delete opengl_hook;
|
delete opengl_hook;
|
||||||
|
|
||||||
instance = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
decltype(::CGLFlushDrawable)* CGLFlushDrawable;
|
|
||||||
|
|
||||||
bool opengl_hooked;
|
|
||||||
//bool metal_hooked;
|
|
||||||
|
|
||||||
OpenGL_Hook* opengl_hook;
|
|
||||||
//Metal_Hook* metal_hook;
|
|
||||||
|
|
||||||
Renderer_Detector():
|
Renderer_Detector():
|
||||||
opengl_hooked(false),
|
opengl_hooked(false),
|
||||||
renderer_hook(nullptr),
|
renderer_hook(nullptr),
|
||||||
opengl_hook(nullptr),
|
opengl_hook(nullptr),
|
||||||
detection_done(false),
|
detection_done(false)
|
||||||
detection_count(0),
|
|
||||||
detection_cancelled(false)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
std::string FindPreferedModulePath(std::string const& name)
|
std::timed_mutex detector_mutex;
|
||||||
{
|
std::mutex renderer_mutex;
|
||||||
return name;
|
|
||||||
}
|
Base_Hook detection_hooks;
|
||||||
|
|
||||||
|
decltype(::CGLFlushDrawable)* CGLFlushDrawable;
|
||||||
|
|
||||||
|
bool opengl_hooked;
|
||||||
|
|
||||||
|
ingame_overlay::Renderer_Hook* renderer_hook;
|
||||||
|
OpenGL_Hook* opengl_hook;
|
||||||
|
|
||||||
|
bool detection_done;
|
||||||
|
std::condition_variable stop_detection_cv;
|
||||||
|
std::mutex stop_detection_mutex;
|
||||||
|
|
||||||
static int64_t MyCGLFlushDrawable(CGLDrawable_t* glDrawable)
|
static int64_t MyCGLFlushDrawable(CGLDrawable_t* glDrawable)
|
||||||
{
|
{
|
||||||
|
@ -1275,164 +1428,89 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EnterDetection()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExitDetection()
|
|
||||||
{
|
|
||||||
detection_done = true;
|
|
||||||
detection_hooks.UnhookAll();
|
|
||||||
|
|
||||||
opengl_hooked = false;
|
|
||||||
//metal_hooked = false;
|
|
||||||
|
|
||||||
delete opengl_hook; opengl_hook = nullptr;
|
|
||||||
//delete metal_hook; metal_hook = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::timed_mutex detector_mutex;
|
|
||||||
std::mutex renderer_mutex;
|
|
||||||
|
|
||||||
Base_Hook detection_hooks;
|
|
||||||
ingame_overlay::Renderer_Hook* renderer_hook;
|
|
||||||
|
|
||||||
bool detection_done;
|
|
||||||
uint32_t detection_count;
|
|
||||||
bool detection_cancelled;
|
|
||||||
std::condition_variable stop_detection_cv;
|
|
||||||
std::mutex stop_detection_mutex;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::future<ingame_overlay::Renderer_Hook*> detect_renderer(std::chrono::milliseconds timeout)
|
ingame_overlay::Renderer_Hook* detect_renderer(std::chrono::milliseconds timeout)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lk(stop_detection_mutex);
|
std::pair<const char*, void(Renderer_Detector::*)(std::string const&)> libraries[]{
|
||||||
|
std::pair<const char*, void(Renderer_Detector::*)(std::string const&)>{OpenGL_Hook::DLL_NAME, &Renderer_Detector::hook_opengl}
|
||||||
|
};
|
||||||
|
|
||||||
if (detection_count == 0)
|
|
||||||
{// If we have no detections in progress, restart detection.
|
|
||||||
detection_cancelled = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
++detection_count;
|
|
||||||
|
|
||||||
return std::async(std::launch::async, [this, timeout]() -> ingame_overlay::Renderer_Hook*
|
|
||||||
{
|
|
||||||
std::unique_lock<std::timed_mutex> detection_lock(detector_mutex, std::defer_lock);
|
std::unique_lock<std::timed_mutex> detection_lock(detector_mutex, std::defer_lock);
|
||||||
constexpr std::chrono::milliseconds infinite_timeout{ -1 };
|
|
||||||
|
|
||||||
if (!detection_lock.try_lock_for(timeout))
|
if (!detection_lock.try_lock_for(timeout))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
bool cancel = false;
|
|
||||||
{
|
|
||||||
System::scoped_lock lk(renderer_mutex, stop_detection_mutex);
|
|
||||||
|
|
||||||
if (!detection_cancelled)
|
|
||||||
{
|
{
|
||||||
|
std::lock_guard<std::mutex> lk(renderer_mutex);
|
||||||
if (detection_done)
|
if (detection_done)
|
||||||
{
|
{
|
||||||
if (renderer_hook == nullptr)
|
if (renderer_hook != nullptr || force_done)
|
||||||
{// Renderer detection was run but we didn't find it, restart the detection
|
return renderer_hook;
|
||||||
|
|
||||||
detection_done = false;
|
detection_done = false;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{// Renderer already detected, cancel detection and return the renderer.
|
|
||||||
cancel = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!EnterDetection())
|
|
||||||
cancel = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{// Detection was cancelled, cancel this detection
|
|
||||||
cancel = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cancel)
|
|
||||||
{
|
|
||||||
--detection_count;
|
|
||||||
stop_detection_cv.notify_all();
|
|
||||||
return renderer_hook;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SPDLOG_TRACE("Started renderer detection.");
|
SPDLOG_TRACE("Started renderer detection.");
|
||||||
|
|
||||||
std::pair<std::string, void(Renderer_Detector::*)(std::string const&)> libraries[]{
|
|
||||||
RENDERER_HOOKS
|
|
||||||
};
|
|
||||||
std::string name;
|
|
||||||
|
|
||||||
auto start_time = std::chrono::steady_clock::now();
|
auto start_time = std::chrono::steady_clock::now();
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lck(stop_detection_mutex);
|
std::unique_lock<std::mutex> lck(stop_detection_mutex);
|
||||||
if (detection_cancelled || detection_done)
|
if (detection_done)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
for (auto const& library : libraries)
|
for (auto const& library : libraries)
|
||||||
{
|
{
|
||||||
std::string lib_path = FindPreferedModulePath(library.first);
|
void* lib_handle = System::Library::GetLibraryHandle(library.first);
|
||||||
if (!lib_path.empty())
|
|
||||||
{
|
|
||||||
void* lib_handle = System::Library::GetLibraryHandle(lib_path.c_str());
|
|
||||||
if (lib_handle != nullptr)
|
if (lib_handle != nullptr)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lk(renderer_mutex);
|
std::lock_guard<std::mutex> lk(renderer_mutex);
|
||||||
(this->*library.second)(System::Library::GetLibraryPath(lib_handle));
|
std::string lib_path = System::Library::GetLibraryPath(lib_handle);
|
||||||
}
|
(this->*library.second)(lib_path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stop_detection_cv.wait_for(lck, std::chrono::milliseconds{ 100 });
|
stop_detection_cv.wait_for(lck, std::chrono::milliseconds{ 100 });
|
||||||
} while (timeout == infinite_timeout || (std::chrono::steady_clock::now() - start_time) <= timeout);
|
} while (!detection_done && (timeout.count() == -1 || (std::chrono::steady_clock::now() - start_time) <= timeout));
|
||||||
|
|
||||||
{
|
{
|
||||||
System::scoped_lock lk(renderer_mutex, stop_detection_mutex);
|
std::lock_guard<std::mutex> lk(renderer_mutex);
|
||||||
|
|
||||||
ExitDetection();
|
detection_done = true;
|
||||||
|
detection_hooks.UnhookAll();
|
||||||
|
|
||||||
--detection_count;
|
opengl_hooked = false;
|
||||||
|
|
||||||
|
delete opengl_hook; opengl_hook = nullptr;
|
||||||
|
//delete vulkan_hook; vulkan_hook = nullptr;
|
||||||
}
|
}
|
||||||
stop_detection_cv.notify_all();
|
|
||||||
|
|
||||||
SPDLOG_TRACE("Renderer detection done {}.", (void*)renderer_hook);
|
SPDLOG_TRACE("Renderer detection done {}.", (void*)renderer_hook);
|
||||||
|
|
||||||
return renderer_hook;
|
return renderer_hook;
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void stop_detection()
|
void stop_detection()
|
||||||
{
|
{
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> lk(stop_detection_mutex);
|
|
||||||
if (detection_count == 0)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
System::scoped_lock lk(renderer_mutex, stop_detection_mutex);
|
System::scoped_lock lk(renderer_mutex, stop_detection_mutex);
|
||||||
detection_cancelled = true;
|
detection_done = true;
|
||||||
|
force_done = true;
|
||||||
}
|
}
|
||||||
stop_detection_cv.notify_all();
|
stop_detection_cv.notify_all();
|
||||||
{
|
|
||||||
std::unique_lock<std::mutex> lk(stop_detection_mutex);
|
|
||||||
stop_detection_cv.wait(lk, [&]() { return detection_count == 0; });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Renderer_Detector* Renderer_Detector::instance = nullptr;
|
Renderer_Detector* Renderer_Detector::instance = nullptr;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace ingame_overlay {
|
namespace ingame_overlay {
|
||||||
|
|
||||||
std::future<ingame_overlay::Renderer_Hook*> DetectRenderer(std::chrono::milliseconds timeout)
|
std::future<ingame_overlay::Renderer_Hook*> DetectRenderer(std::chrono::milliseconds timeout)
|
||||||
{
|
{
|
||||||
return Renderer_Detector::Inst()->detect_renderer(timeout);
|
return std::async(std::launch::async, &Renderer_Detector::detect_renderer, Renderer_Detector::Inst(), timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StopRendererDetection()
|
void StopRendererDetection()
|
||||||
|
@ -1440,9 +1518,9 @@ void StopRendererDetection()
|
||||||
Renderer_Detector::Inst()->stop_detection();
|
Renderer_Detector::Inst()->stop_detection();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FreeDetector()
|
void FreeRendererDetection()
|
||||||
{
|
{
|
||||||
delete Renderer_Detector::Inst();
|
Renderer_Detector::deleteInst();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -31,6 +31,5 @@ namespace ingame_overlay {
|
||||||
|
|
||||||
std::future<Renderer_Hook*> DetectRenderer(std::chrono::milliseconds timeout = std::chrono::milliseconds{ -1 });
|
std::future<Renderer_Hook*> DetectRenderer(std::chrono::milliseconds timeout = std::chrono::milliseconds{ -1 });
|
||||||
void StopRendererDetection();
|
void StopRendererDetection();
|
||||||
void FreeDetector();
|
void FreeRendererDetection();
|
||||||
|
|
||||||
}
|
}
|
|
@ -39,8 +39,7 @@ class Renderer_Hook
|
||||||
public:
|
public:
|
||||||
Renderer_Hook():
|
Renderer_Hook():
|
||||||
OverlayProc(&DefaultOverlayProc),
|
OverlayProc(&DefaultOverlayProc),
|
||||||
OverlayHookReady(&DefaultOverlayHookReady),
|
OverlayHookReady(&DefaultOverlayHookReady)
|
||||||
ImGuiFontAtlas(nullptr)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
static void DefaultOverlayProc() {}
|
static void DefaultOverlayProc() {}
|
||||||
|
@ -48,7 +47,6 @@ public:
|
||||||
std::function<void()> OverlayProc;
|
std::function<void()> OverlayProc;
|
||||||
std::function<void(bool)> OverlayHookReady;
|
std::function<void(bool)> OverlayHookReady;
|
||||||
|
|
||||||
void *ImGuiFontAtlas;
|
|
||||||
virtual bool StartHook(std::function<bool(bool)> key_combination_callback, std::set<ToggleKey> toggle_keys) = 0;
|
virtual bool StartHook(std::function<bool(bool)> key_combination_callback, std::set<ToggleKey> toggle_keys) = 0;
|
||||||
virtual bool IsStarted() = 0;
|
virtual bool IsStarted() = 0;
|
||||||
// Returns a Handle to the renderer image ressource or nullptr if it failed to create the resource, the handle can be used in ImGui's Image calls, image_buffer must be RGBA ordered
|
// Returns a Handle to the renderer image ressource or nullptr if it failed to create the resource, the handle can be used in ImGui's Image calls, image_buffer must be RGBA ordered
|
||||||
|
|
|
@ -84,7 +84,7 @@ void OpenGLX_Hook::_PrepareForOverlay(Display* display, GLXDrawable drawable)
|
||||||
{
|
{
|
||||||
if( !_Initialized )
|
if( !_Initialized )
|
||||||
{
|
{
|
||||||
ImGui::CreateContext((ImFontAtlas *)ImGuiFontAtlas);
|
ImGui::CreateContext();
|
||||||
ImGui_ImplOpenGL3_Init();
|
ImGui_ImplOpenGL3_Init();
|
||||||
|
|
||||||
//int attributes[] = { //can't be const b/c X11 doesn't like it. Not sure if that's intentional or just stupid.
|
//int attributes[] = { //can't be const b/c X11 doesn't like it. Not sure if that's intentional or just stupid.
|
||||||
|
|
|
@ -128,8 +128,7 @@ Steam_Overlay::Steam_Overlay(Settings* settings, SteamCallResults* callback_resu
|
||||||
i_have_lobby(false),
|
i_have_lobby(false),
|
||||||
show_achievements(false),
|
show_achievements(false),
|
||||||
show_settings(false),
|
show_settings(false),
|
||||||
_renderer(nullptr),
|
_renderer(nullptr)
|
||||||
fonts_atlas(nullptr)
|
|
||||||
{
|
{
|
||||||
strncpy(username_text, settings->get_local_name(), sizeof(username_text));
|
strncpy(username_text, settings->get_local_name(), sizeof(username_text));
|
||||||
|
|
||||||
|
@ -208,7 +207,7 @@ void Steam_Overlay::UnSetupOverlay()
|
||||||
if (!Ready() && future_renderer.valid()) {
|
if (!Ready() && future_renderer.valid()) {
|
||||||
if (future_renderer.wait_for(std::chrono::milliseconds{500}) == std::future_status::ready) {
|
if (future_renderer.wait_for(std::chrono::milliseconds{500}) == std::future_status::ready) {
|
||||||
future_renderer.get();
|
future_renderer.get();
|
||||||
ingame_overlay::FreeDetector();
|
ingame_overlay::FreeRendererDetection();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -710,10 +709,11 @@ void Steam_Overlay::BuildNotifications(int width, int height)
|
||||||
|
|
||||||
void Steam_Overlay::CreateFonts()
|
void Steam_Overlay::CreateFonts()
|
||||||
{
|
{
|
||||||
if (fonts_atlas) return;
|
//TODO: remove from dx_whatever hook
|
||||||
|
if(ImGui::GetCurrentContext() == nullptr)
|
||||||
ImFontAtlas *Fonts = new ImFontAtlas();
|
ImGui::CreateContext();
|
||||||
|
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
ImFontConfig fontcfg;
|
ImFontConfig fontcfg;
|
||||||
|
|
||||||
float font_size = 16.0;
|
float font_size = 16.0;
|
||||||
|
@ -727,7 +727,7 @@ void Steam_Overlay::CreateFonts()
|
||||||
font_builder.AddText(x.description.c_str());
|
font_builder.AddText(x.description.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
font_builder.AddRanges(Fonts->GetGlyphRangesDefault());
|
font_builder.AddRanges(io.Fonts->GetGlyphRangesDefault());
|
||||||
|
|
||||||
ImVector<ImWchar> ranges;
|
ImVector<ImWchar> ranges;
|
||||||
font_builder.BuildRanges(&ranges);
|
font_builder.BuildRanges(&ranges);
|
||||||
|
@ -744,11 +744,11 @@ void Steam_Overlay::CreateFonts()
|
||||||
ImFont *font = NULL;
|
ImFont *font = NULL;
|
||||||
|
|
||||||
#if defined(__WINDOWS__)
|
#if defined(__WINDOWS__)
|
||||||
font = Fonts->AddFontFromFileTTF("C:\\Windows\\Fonts\\micross.ttf", font_size, &fontcfg);
|
font = io.Fonts->AddFontFromFileTTF("C:\\Windows\\Fonts\\micross.ttf", font_size, &fontcfg);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!font) {
|
if (!font) {
|
||||||
font = Fonts->AddFontDefault(&fontcfg);
|
font = io.Fonts->AddFontDefault(&fontcfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
font_notif = font_default = font;
|
font_notif = font_default = font;
|
||||||
|
@ -757,16 +757,15 @@ void Steam_Overlay::CreateFonts()
|
||||||
PRINT_DEBUG("loading extra fonts\n");
|
PRINT_DEBUG("loading extra fonts\n");
|
||||||
fontcfg.MergeMode = true;
|
fontcfg.MergeMode = true;
|
||||||
#if defined(__WINDOWS__)
|
#if defined(__WINDOWS__)
|
||||||
Fonts->AddFontFromFileTTF("C:\\Windows\\Fonts\\simsun.ttc", font_size, &fontcfg);
|
io.Fonts->AddFontFromFileTTF("C:\\Windows\\Fonts\\simsun.ttc", font_size, &fontcfg);
|
||||||
Fonts->AddFontFromFileTTF("C:\\Windows\\Fonts\\malgun.ttf", font_size, &fontcfg);
|
io.Fonts->AddFontFromFileTTF("C:\\Windows\\Fonts\\malgun.ttf", font_size, &fontcfg);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
Fonts->Build();
|
io.Fonts->Build();
|
||||||
fonts_atlas = (void *)Fonts;
|
|
||||||
|
|
||||||
// ImGuiStyle& style = ImGui::GetStyle();
|
ImGuiStyle& style = ImGui::GetStyle();
|
||||||
// style.WindowRounding = 0.0; // Disable round window
|
style.WindowRounding = 0.0; // Disable round window
|
||||||
reset_LastError();
|
reset_LastError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1049,7 +1048,6 @@ void Steam_Overlay::RunCallbacks()
|
||||||
auto callback = std::bind(&Steam_Overlay::OpenOverlayHook, this, std::placeholders::_1);
|
auto callback = std::bind(&Steam_Overlay::OpenOverlayHook, this, std::placeholders::_1);
|
||||||
PRINT_DEBUG("start renderer\n", _renderer);
|
PRINT_DEBUG("start renderer\n", _renderer);
|
||||||
std::set<ingame_overlay::ToggleKey> keys = {ingame_overlay::ToggleKey::SHIFT, ingame_overlay::ToggleKey::TAB};
|
std::set<ingame_overlay::ToggleKey> keys = {ingame_overlay::ToggleKey::SHIFT, ingame_overlay::ToggleKey::TAB};
|
||||||
_renderer->ImGuiFontAtlas = fonts_atlas;
|
|
||||||
bool started = _renderer->StartHook(callback, keys);
|
bool started = _renderer->StartHook(callback, keys);
|
||||||
PRINT_DEBUG("tried to start renderer %u\n", started);
|
PRINT_DEBUG("tried to start renderer %u\n", started);
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,7 +102,6 @@ class Steam_Overlay
|
||||||
std::string show_url;
|
std::string show_url;
|
||||||
std::vector<Overlay_Achievement> achievements;
|
std::vector<Overlay_Achievement> achievements;
|
||||||
bool show_achievements, show_settings;
|
bool show_achievements, show_settings;
|
||||||
void *fonts_atlas;
|
|
||||||
|
|
||||||
bool disable_forced, local_save, warning_forced;
|
bool disable_forced, local_save, warning_forced;
|
||||||
uint32_t appid;
|
uint32_t appid;
|
||||||
|
|
|
@ -115,7 +115,7 @@ void DX10_Hook::_PrepareForOverlay(IDXGISwapChain* pSwapChain)
|
||||||
pDevice->CreateRenderTargetView(pBackBuffer, nullptr, &mainRenderTargetView);
|
pDevice->CreateRenderTargetView(pBackBuffer, nullptr, &mainRenderTargetView);
|
||||||
pBackBuffer->Release();
|
pBackBuffer->Release();
|
||||||
|
|
||||||
ImGui::CreateContext((ImFontAtlas *)ImGuiFontAtlas);
|
ImGui::CreateContext();
|
||||||
ImGui_ImplDX10_Init(pDevice);
|
ImGui_ImplDX10_Init(pDevice);
|
||||||
|
|
||||||
Windows_Hook::Inst()->SetInitialWindowSize(desc.OutputWindow);
|
Windows_Hook::Inst()->SetInitialWindowSize(desc.OutputWindow);
|
||||||
|
|
|
@ -147,7 +147,7 @@ void DX11_Hook::_PrepareForOverlay(IDXGISwapChain* pSwapChain)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(ImGui::GetCurrentContext() == nullptr)
|
if(ImGui::GetCurrentContext() == nullptr)
|
||||||
ImGui::CreateContext((ImFontAtlas *)ImGuiFontAtlas);
|
ImGui::CreateContext();
|
||||||
|
|
||||||
ImGui_ImplDX11_Init(pDevice, pContext);
|
ImGui_ImplDX11_Init(pDevice, pContext);
|
||||||
|
|
||||||
|
|
|
@ -264,7 +264,7 @@ void DX12_Hook::_PrepareForOverlay(IDXGISwapChain* pSwapChain, ID3D12CommandQueu
|
||||||
|
|
||||||
//auto heaps = std::move(get_free_texture_heap());
|
//auto heaps = std::move(get_free_texture_heap());
|
||||||
|
|
||||||
ImGui::CreateContext((ImFontAtlas *)ImGuiFontAtlas);
|
ImGui::CreateContext();
|
||||||
ImGui_ImplDX12_Init(pDevice, bufferCount, DXGI_FORMAT_R8G8B8A8_UNORM, pSrvDescHeap,
|
ImGui_ImplDX12_Init(pDevice, bufferCount, DXGI_FORMAT_R8G8B8A8_UNORM, pSrvDescHeap,
|
||||||
pSrvDescHeap->GetCPUDescriptorHandleForHeapStart(),
|
pSrvDescHeap->GetCPUDescriptorHandleForHeapStart(),
|
||||||
pSrvDescHeap->GetGPUDescriptorHandleForHeapStart());
|
pSrvDescHeap->GetGPUDescriptorHandleForHeapStart());
|
||||||
|
|
|
@ -133,7 +133,7 @@ void DX9_Hook::_PrepareForOverlay(IDirect3DDevice9 *pDevice, HWND destWindow)
|
||||||
pDevice->AddRef();
|
pDevice->AddRef();
|
||||||
_pDevice = pDevice;
|
_pDevice = pDevice;
|
||||||
|
|
||||||
ImGui::CreateContext((ImFontAtlas *)ImGuiFontAtlas);
|
ImGui::CreateContext();
|
||||||
ImGui_ImplDX9_Init(pDevice);
|
ImGui_ImplDX9_Init(pDevice);
|
||||||
|
|
||||||
_LastWindow = destWindow;
|
_LastWindow = destWindow;
|
||||||
|
|
|
@ -86,7 +86,7 @@ void OpenGL_Hook::_PrepareForOverlay(HDC hDC)
|
||||||
|
|
||||||
if (!_Initialized)
|
if (!_Initialized)
|
||||||
{
|
{
|
||||||
ImGui::CreateContext((ImFontAtlas *)ImGuiFontAtlas);
|
ImGui::CreateContext();
|
||||||
ImGui_ImplOpenGL3_Init();
|
ImGui_ImplOpenGL3_Init();
|
||||||
|
|
||||||
_LastWindow = hWnd;
|
_LastWindow = hWnd;
|
||||||
|
|
Loading…
Reference in New Issue