Skip to content

ImMalkah/UniversalOverlay

Repository files navigation

UniversalOverlay

CI Docs Documentation C++23 Platform Renderers License: MIT

UniversalOverlay is a C++23 static library for injected Win32 overlays. It hooks the target renderer, starts Dear ImGui, routes input, draws your menu/windows, persists settings, and unloads cleanly.

Use it when you want a debugging menu, SDK inspection panel, cheat menu, entity viewer, live diagnostics window, or always-on overlay without rebuilding renderer hooks and ImGui plumbing for every project.

Read the docs: malkahservices.ca/UniversalOverlay

Pick Your Renderer

Choose the renderer used by the target process, pass it to Initialize(), then build/reload your host DLL.

Target renderer Use this enum Hook path
Direct3D 11 GraphicsAPI::D3D11 IDXGISwapChain::Present and ResizeBuffers
Direct3D 12 GraphicsAPI::D3D12 Present, ResizeBuffers, and command queue ExecuteCommandLists
Direct3D 9 GraphicsAPI::D3D9 IDirect3DDevice9::EndScene and Reset
OpenGL 3 GraphicsAPI::OpenGL3 wglSwapBuffers
UniversalOverlay::Initialize(UniversalOverlay::GraphicsAPI::D3D11);

Only initialize one renderer per overlay lifetime. If you need runtime selection, decide before Initialize():

UniversalOverlay::GraphicsAPI api = UniversalOverlay::GraphicsAPI::D3D11;

if (useD3D12)
    api = UniversalOverlay::GraphicsAPI::D3D12;
else if (useD3D9)
    api = UniversalOverlay::GraphicsAPI::D3D9;
else if (useOpenGL)
    api = UniversalOverlay::GraphicsAPI::OpenGL3;

if (!UniversalOverlay::Initialize(api))
    return;

Quick Setup

  1. Open UniversalOverlay.sln in Visual Studio 2022.
  2. Build Debug or Release for x86 or x64.
  3. Link your injected DLL against:
Build/[Configuration]/[Platform]/UniversalOverlay.lib

In your DLL project:

  • Add include dirs: Src/, External/ImGui, External/ImGui/Backends, External/MinHook/include.
  • Link the matching libMinHook.x86.lib or libMinHook.x64.lib.
  • Use C++23 (/std:c++23).
  • Include UniversalOverlay.h and imgui.h.

3. Basic Example

Copy this into your injected DLL project, then change the GraphicsAPI enum for the target renderer.

#include <Windows.h>
#include <cstdio>
#include <filesystem>
#include <string>

#include "UniversalOverlay.h"
#include "imgui.h"

namespace
{
    bool g_enabled = true;
    float g_alpha = 0.85f;
    int g_mode = 1;

    std::wstring GetConfigPath(HMODULE module)
    {
        wchar_t modulePath[MAX_PATH] = {};
        const DWORD length = GetModuleFileNameW(module, modulePath, MAX_PATH);

        if (length == 0)
            return L".\\UniversalOverlaySettings.ini";

        return (std::filesystem::path(modulePath).parent_path() / L"UniversalOverlaySettings.ini").wstring();
    }

    void DrawExampleSettings()
    {
        bool changed = false;
        changed |= ImGui::Checkbox("Enabled", &g_enabled);
        changed |= ImGui::SliderFloat("Overlay alpha", &g_alpha, 0.10f, 1.0f, "%.2f");
        changed |= ImGui::Combo("Mode", &g_mode, "Idle\0Tracking\0Warning\0\0");

        if (changed)
            UniversalOverlay::MarkConfigDirty();
    }

    void DrawExampleTab()
    {
        ImGui::TextUnformatted("UniversalOverlay starter");
        DrawExampleSettings();

        if (ImGui::Button("Open status window"))
            UniversalOverlay::SetFloatingWindowOpen("Example Status", true);

        if (ImGui::Button("Save preset 1"))
            UniversalOverlay::SaveConfigPreset(1);

        ImGui::SameLine();
        if (ImGui::Button("Load preset 1"))
            UniversalOverlay::LoadConfigPreset(1);
    }

    void DrawExampleWindow(bool menuOpen)
    {
        ImGui::Text("Mode: %d", g_mode);

        if (menuOpen)
            DrawExampleSettings();
    }

    void DrawExampleOverlay()
    {
        if (!g_enabled)
            return;

        char label[64] = {};
        sprintf_s(label, "UniversalOverlay alpha %.2f", g_alpha);

        ImGui::GetBackgroundDrawList()->AddText(
            ImVec2(20.0f, 20.0f),
            IM_COL32(80, 220, 255, static_cast<int>(255.0f * g_alpha)),
            label);
    }

    DWORD WINAPI OverlayThread(LPVOID parameter)
    {
        HMODULE module = static_cast<HMODULE>(parameter);
        const std::wstring configPath = GetConfigPath(module);

        if (!UniversalOverlay::Initialize(UniversalOverlay::GraphicsAPI::D3D11))
            FreeLibraryAndExitThread(module, 0);

        UniversalOverlay::SetMenuDefaultSize(980.0f, 640.0f);

        UniversalOverlay::RegisterConfigBool("Example", "Enabled", &g_enabled);
        UniversalOverlay::RegisterConfigFloat("Example", "Alpha", &g_alpha, 0.85f);
        UniversalOverlay::RegisterConfigInt("Example", "Mode", &g_mode, 1);
        UniversalOverlay::LoadConfig(configPath);

        UniversalOverlay::RegisterSettingsSection("Example", DrawExampleSettings);
        UniversalOverlay::RegisterTab("Example", DrawExampleTab);
        UniversalOverlay::RegisterFloatingWindow("Example Status", DrawExampleWindow, true, false, 0.55f);
        UniversalOverlay::RegisterRenderCallback(DrawExampleOverlay);

        while (!UniversalOverlay::ShouldUnload())
            Sleep(100);

        UniversalOverlay::SaveConfig(configPath);
        UniversalOverlay::Shutdown();
        FreeLibraryAndExitThread(module, 0);
        return 0;
    }
}

BOOL APIENTRY DllMain(HMODULE module, DWORD reason, LPVOID)
{
    if (reason != DLL_PROCESS_ATTACH)
        return TRUE;

    DisableThreadLibraryCalls(module);

    HANDLE thread = CreateThread(nullptr, 0, OverlayThread, module, 0, nullptr);
    if (thread)
        CloseHandle(thread);

    return TRUE;
}

Main Features

  • Renderer hooks: OpenGL 3, Direct3D 9, Direct3D 11, and Direct3D 12.
  • Menu extension: register tabs with RegisterTab() and Settings sections with RegisterSettingsSection().
  • Per-frame drawing: use RegisterRenderCallback() for labels, boxes, meters, crosshairs, and drawlist work.
  • Floating windows: use RegisterFloatingWindow() for inspectors, watch lists, logs, or pinned utility windows.
  • Settings and presets: register bool, float, int, and uint64_t values, then LoadConfig(), SaveConfig(), SaveConfigPreset(), and LoadConfigPreset().
  • Fonts and icons: built-in vector fonts, Font Awesome icon glyphs, plus custom file or memory fonts with RegisterFont(), SetSelectedFont(), and GetSelectedFontId().
  • Theming: built-in Themes surface, theme tokens, compact layouts, status pills, badges, meters, and draw helpers.
  • Input and cursor handling: hooked WndProc input routing while the menu is open, with cursor-lock handoff.
  • Diagnostics: rotating logs under %TEMP%\UniversalOverlay\<process-id>\ through External/spdlog; debug builds include richer diagnostics surfaces.
  • Safe unload: RequestUnload() and ShouldUnload() let your host thread save config, shut down hooks, and exit cleanly.

Rules That Matter

  • Register config values before LoadConfig().
  • Call MarkConfigDirty() after an ImGui control changes a registered value.
  • RegisterRenderCallback() runs while the overlay is active, even when the menu is closed.
  • RegisterTab() callbacks run while the menu is open and the tab is selected.
  • Unpinned floating windows show while the menu is open; pinned windows can stay visible after it closes.
  • Default hotkeys are . for menu toggle and F1 for unload.

API You Will Use Most

  • Initialize(GraphicsAPI api) / Shutdown()
  • ShouldUnload() / RequestUnload()
  • IsMenuOpen() / SetMenuOpen(bool open)
  • SetMenuDefaultSize(float width, float height)
  • RegisterTab(name, callback)
  • RegisterSettingsSection(name, callback)
  • RegisterRenderCallback(callback)
  • RegisterFloatingWindow(name, callback, defaultOpen, defaultPinned, backgroundAlpha)
  • SetFloatingWindowOpen(name, open) / SetFloatingWindowPinned(name, pinned)
  • RegisterFont(spec) / SetSelectedFont(id) / GetSelectedFontId()
  • RegisterConfigBool/Float/Int(section, key, pointer, defaultValue)
  • LoadConfig(path) / SaveConfig(path)
  • SaveConfigPreset(slot) / LoadConfigPreset(slot)

Documentation

The full Doxygen site is published automatically:

Open the UniversalOverlay documentation

  • Users do not need to install Doxygen or generate docs locally.
  • Source pages start at docs/doxygen/pages/mainpage.md.
  • GitHub Actions builds the site from production and publishes it with GitHub Pages.
  • Generated HTML stays out of git under docs/doxygen/html/.

Source Map

Most users only need Src/UniversalOverlay.h.

Useful internals:

  • Core/config/logging: Src/Core/UniversalOverlayCore.cpp, ConfigSystem.h/cpp, OverlayLog.h/cpp; logging uses External/spdlog.
  • Renderer hooks/backends: Src/Hooks/Hooks.h/cpp, WndProcHook.h/cpp, CursorHook.h/cpp, Src/Renderer/Renderer.h/cpp, RendererTypes.h, and Renderer/Backends.
  • UI shell/helpers: Menu.h/cpp, UIRegistry.h/cpp, OverlayTheme.h/cpp, OverlayLayout.h/cpp, OverlayDraw.h/cpp, OverlayWidgets.h/cpp, OverlayWindowManager.h/cpp, OverlayFonts.h/cpp, OverlayIcons.h/cpp, OverlayThemes.h/cpp.

Extra notes live in docs/wiki/, especially logging/diagnostics and third-party dependency notes.

License

MIT. See LICENSE.

About

A universal C++23 game overlay framework using Dear ImGui and MinHook, supporting OpenGL3, Direct3D 9, Direct3D 11, and Direct3D 12.

Topics

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors