Skip to content

Commit 56339ff

Browse files
committed
Remove the need to define the imgui function table in add-on projects
1 parent 7ad2f33 commit 56339ff

File tree

12 files changed

+436
-437
lines changed

12 files changed

+436
-437
lines changed

REFERENCE.md

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,19 +45,15 @@ For more complex examples, see the [examples directory in this repository](../ex
4545
## Overlays
4646
4747
It is also supported to add an overlay, which can e.g. be used to display debug information or interact with the user in-application.
48-
Overlays are created with the use of [Dear ImGui](https://github.com/ocornut/imgui/). Including the `reshade.hpp` header after `imgui.h` will automatically overwrite all Dear ImGui functions to use the instance created and managed by ReShade. This means all you have to do is include these two headers, define the function table variable in one of your source code file and use Dear ImGui as usual (without actually having to build its source code files, only the header files are needed):
48+
Overlays are created with the use of [Dear ImGui](https://github.com/ocornut/imgui/). Including the `reshade.hpp` header after `imgui.h` will automatically overwrite all Dear ImGui functions to use the instance created and managed by ReShade. This means all you have to do is include these two headers and use Dear ImGui as usual (without having to build its source code files):
4949
5050
```cpp
5151
#include <imgui.h>
5252
#include <reshade.hpp>
5353
54-
// Define this variable in exactly one of your source code files.
55-
// The function table is automatically populated in the call to 'reshade::register_addon()' and overwrites all Dear ImGui functions.
56-
imgui_function_table g_imgui_function_table = {};
57-
5854
bool g_popup_window_visible = false;
5955
60-
static void draw_debug_overlay(reshade::api::effect_runtime *runtime, void *imgui_context)
56+
static void draw_debug_overlay(reshade::api::effect_runtime *runtime)
6157
{
6258
ImGui::TextUnformatted("Some text");
6359
@@ -72,7 +68,7 @@ static void draw_debug_overlay(reshade::api::effect_runtime *runtime, void *imgu
7268
}
7369
}
7470
75-
static void draw_settings_overlay(reshade::api::effect_runtime *runtime, void *imgui_context)
71+
static void draw_settings_overlay(reshade::api::effect_runtime *runtime)
7672
{
7773
ImGui::Checkbox("Popup window is visible", &g_popup_window_visible);
7874
}

examples/api_trace/api_trace.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111
#include <unordered_map>
1212
#include <cassert>
1313

14-
imgui_function_table g_imgui_function_table;
15-
1614
namespace
1715
{
1816
bool s_do_capture = false;
@@ -789,7 +787,7 @@ static void on_present(reshade::api::command_queue *, reshade::api::swapchain *)
789787
s_do_capture = false;
790788
}
791789

792-
static void draw_overlay(reshade::api::effect_runtime *, void *)
790+
static void draw_overlay(reshade::api::effect_runtime *)
793791
{
794792
if (!s_do_capture)
795793
{

examples/generic_depth/generic_depth.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@ static std::mutex s_mutex;
1515

1616
#ifdef BUILTIN_ADDON
1717
#include "ini_file.hpp"
18-
#else
19-
imgui_function_table g_imgui_function_table;
2018
#endif
2119

2220
using namespace reshade::api;
@@ -692,7 +690,7 @@ static void on_finish_render_effects(effect_runtime *runtime, command_list *cmd_
692690
}
693691
}
694692

695-
static void draw_settings_overlay(effect_runtime *runtime, void *)
693+
static void draw_settings_overlay(effect_runtime *runtime)
696694
{
697695
device *const device = runtime->get_device();
698696
state_tracking_context &device_state = device->get_private_data<state_tracking_context>(state_tracking_context::GUID);

examples/texturemod_dump/texturemod_overlay.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111
#include <unordered_set>
1212
#include <malloc.h>
1313

14-
imgui_function_table g_imgui_function_table;
15-
1614
using namespace reshade::api;
1715

1816
struct set_data
@@ -313,7 +311,7 @@ static void on_present(command_queue *queue, swapchain *runtime)
313311
// See implementation in 'texturemod_dump.cpp'
314312
extern bool dump_texture(command_queue *queue, resource tex, const resource_desc &desc);
315313

316-
static void draw_overlay(effect_runtime *runtime, void *)
314+
static void draw_overlay(effect_runtime *runtime)
317315
{
318316
assert(s_is_in_reshade_runtime);
319317

include/reshade.hpp

Lines changed: 62 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -11,45 +11,62 @@
1111
#include <Psapi.h>
1212

1313
#define RESHADE_API_VERSION 1
14-
#define RESHADE_API_VERSION_IMGUI IMGUI_VERSION_NUM
1514

1615
namespace reshade
1716
{
18-
/// <summary>
19-
/// Gets the handle to the ReShade module in the current process.
20-
/// </summary>
21-
inline HMODULE &get_reshade_module_handle()
17+
namespace internal
2218
{
23-
static HMODULE handle = nullptr;
24-
if (handle == nullptr)
19+
/// <summary>
20+
/// Gets the handle to the ReShade module in the current process.
21+
/// </summary>
22+
inline HMODULE &get_reshade_module_handle()
2523
{
26-
// Use the kernel32 variant of module enumeration functions so it can be safely called from 'DllMain'
27-
HMODULE modules[1024]; DWORD num = 0;
28-
if (K32EnumProcessModules(GetCurrentProcess(), modules, sizeof(modules), &num))
24+
static HMODULE handle = nullptr;
25+
if (handle == nullptr)
2926
{
30-
if (num > sizeof(modules))
31-
num = sizeof(modules);
32-
33-
for (DWORD i = 0; i < num / sizeof(HMODULE); ++i)
27+
// Use the kernel32 variant of module enumeration functions so it can be safely called from 'DllMain'
28+
HMODULE modules[1024]; DWORD num = 0;
29+
if (K32EnumProcessModules(GetCurrentProcess(), modules, sizeof(modules), &num))
3430
{
35-
if (GetProcAddress(modules[i], "ReShadeRegisterAddon") &&
36-
GetProcAddress(modules[i], "ReShadeUnregisterAddon"))
31+
if (num > sizeof(modules))
32+
num = sizeof(modules);
33+
34+
for (DWORD i = 0; i < num / sizeof(HMODULE); ++i)
3735
{
38-
handle = modules[i];
39-
break;
36+
if (GetProcAddress(modules[i], "ReShadeRegisterAddon") &&
37+
GetProcAddress(modules[i], "ReShadeUnregisterAddon"))
38+
{
39+
handle = modules[i];
40+
break;
41+
}
4042
}
4143
}
4244
}
45+
return handle;
4346
}
44-
return handle;
45-
}
46-
/// <summary>
47-
/// Gets the handle to the current add-on module.
48-
/// </summary>
49-
inline HMODULE &get_current_module_handle()
50-
{
51-
static HMODULE handle = nullptr;
52-
return handle;
47+
48+
/// <summary>
49+
/// Gets the handle to the current add-on module.
50+
/// </summary>
51+
inline HMODULE &get_current_module_handle()
52+
{
53+
static HMODULE handle = nullptr;
54+
return handle;
55+
}
56+
57+
#if defined(IMGUI_VERSION_NUM)
58+
/// <summary>
59+
/// Gets a pointer to the Dear ImGui function table.
60+
/// </summary>
61+
inline const imgui_function_table *get_imgui_function_table()
62+
{
63+
static const auto func = reinterpret_cast<const imgui_function_table *(*)(uint32_t)>(
64+
GetProcAddress(get_reshade_module_handle(), "ReShadeGetImGuiFunctionTable"));
65+
if (func != nullptr)
66+
return func(IMGUI_VERSION_NUM);
67+
return nullptr;
68+
}
69+
#endif
5370
}
5471

5572
/// <summary>
@@ -60,8 +77,8 @@ namespace reshade
6077
inline void log_message(int level, const char *message)
6178
{
6279
static const auto func = reinterpret_cast<void(*)(HMODULE, int, const char *)>(
63-
GetProcAddress(get_reshade_module_handle(), "ReShadeLogMessage"));
64-
func(get_current_module_handle(), level, message);
80+
GetProcAddress(internal::get_reshade_module_handle(), "ReShadeLogMessage"));
81+
func(internal::get_current_module_handle(), level, message);
6582
}
6683

6784
/// <summary>
@@ -71,9 +88,9 @@ namespace reshade
7188
/// <param name="module">Handle of the current add-on module.</param>
7289
inline bool register_addon(HMODULE module)
7390
{
74-
get_current_module_handle() = module;
91+
internal::get_current_module_handle() = module;
7592

76-
const HMODULE reshade_module = get_reshade_module_handle();
93+
const HMODULE reshade_module = internal::get_reshade_module_handle();
7794
if (reshade_module == nullptr)
7895
return false;
7996

@@ -83,18 +100,10 @@ namespace reshade
83100
if (!func(module, RESHADE_API_VERSION))
84101
return false;
85102

86-
#if defined(IMGUI_VERSION)
87-
// Check that the ReShade module was built with Dear ImGui support
88-
const auto imgui_func = reinterpret_cast<const imgui_function_table *(*)(uint32_t)>(
89-
GetProcAddress(reshade_module, "ReShadeGetImGuiFunctionTable"));
90-
if (imgui_func == nullptr)
91-
return false;
92-
93-
// Check that the ReShade module supports the used Dear ImGui version
94-
const imgui_function_table *const imgui_table = imgui_func(RESHADE_API_VERSION_IMGUI);
95-
if (imgui_table == nullptr)
103+
#if defined(IMGUI_VERSION_NUM)
104+
// Check that the ReShade module was built with Dear ImGui support and supports the used Dear ImGui version
105+
if (!internal::get_imgui_function_table())
96106
return false;
97-
g_imgui_function_table = *imgui_table;
98107
#endif
99108

100109
return true;
@@ -105,7 +114,7 @@ namespace reshade
105114
/// <param name="module">Handle of the current add-on module.</param>
106115
inline void unregister_addon(HMODULE module)
107116
{
108-
const HMODULE reshade_module = get_reshade_module_handle();
117+
const HMODULE reshade_module = internal::get_reshade_module_handle();
109118
if (reshade_module == nullptr)
110119
return;
111120

@@ -123,7 +132,7 @@ namespace reshade
123132
inline void register_event(typename reshade::addon_event_traits<ev>::decl callback)
124133
{
125134
static const auto func = reinterpret_cast<void(*)(reshade::addon_event, void *)>(
126-
GetProcAddress(get_reshade_module_handle(), "ReShadeRegisterEvent"));
135+
GetProcAddress(internal::get_reshade_module_handle(), "ReShadeRegisterEvent"));
127136
func(ev, static_cast<void *>(callback));
128137
}
129138
/// <summary>
@@ -134,7 +143,7 @@ namespace reshade
134143
inline void unregister_event(typename reshade::addon_event_traits<ev>::decl callback)
135144
{
136145
static const auto func = reinterpret_cast<void(*)(reshade::addon_event, void *)>(
137-
GetProcAddress(get_reshade_module_handle(), "ReShadeUnregisterEvent"));
146+
GetProcAddress(internal::get_reshade_module_handle(), "ReShadeUnregisterEvent"));
138147
func(ev, static_cast<void *>(callback));
139148
}
140149

@@ -144,23 +153,21 @@ namespace reshade
144153
/// </summary>
145154
/// <param name="title">A null-terminated title string, or <see langword="nullptr"/> to register a settings overlay for this add-on.</param>
146155
/// <param name="callback">Pointer to the callback function.</param>
147-
inline void register_overlay(const char *title, void(*callback)(reshade::api::effect_runtime *runtime, void *imgui_context))
156+
inline void register_overlay(const char *title, void(*callback)(reshade::api::effect_runtime *runtime))
148157
{
149-
static const auto func = reinterpret_cast<void(*)(const char *, void(*)(reshade::api::effect_runtime *, void *))>(
150-
GetProcAddress(get_reshade_module_handle(), "ReShadeRegisterOverlay"));
151-
if (func != nullptr) // May not exist if ReShade was built without "RESHADE_GUI" defined
152-
func(title, callback);
158+
static const auto func = reinterpret_cast<void(*)(const char *, void(*)(reshade::api::effect_runtime *))>(
159+
GetProcAddress(internal::get_reshade_module_handle(), "ReShadeRegisterOverlay"));
160+
func(title, callback);
153161
}
154162
/// <summary>
155163
/// Unregisters an overlay that was previously registered via <see cref="register_overlay"/>.
156164
/// </summary>
157165
/// <param name="title">A null-terminated title string.</param>
158166
/// <param name="callback">Pointer to the callback function.</param>
159-
inline void unregister_overlay(const char *title, void(*callback)(reshade::api::effect_runtime *runtime, void *imgui_context))
167+
inline void unregister_overlay(const char *title, void(*callback)(reshade::api::effect_runtime *runtime))
160168
{
161-
static const auto func = reinterpret_cast<void(*)(const char *, void(*)(reshade::api::effect_runtime *, void *))>(
162-
GetProcAddress(get_reshade_module_handle(), "ReShadeUnregisterOverlay"));
163-
if (func != nullptr)
164-
func(title, callback);
169+
static const auto func = reinterpret_cast<void(*)(const char *, void(*)(reshade::api::effect_runtime *))>(
170+
GetProcAddress(internal::get_reshade_module_handle(), "ReShadeUnregisterOverlay"));
171+
func(title, callback);
165172
}
166173
}

0 commit comments

Comments
 (0)