YimMenuV2 GUI/Renderer Architecture: How the Menu Rendering System Works

YimMenuV2 uses a three-layer architecture built on Dear ImGui and DirectX 12, separating low-level rendering, UI hierarchy management, and game-specific menu layouts through a callback-driven singleton pattern.

YimMenuV2 implements its in-game overlay using a modular GUI/Renderer architecture that integrates Dear ImGui with a custom DirectX 12 backend. This design splits responsibilities across the core renderer, frontend manager, and game-specific frontend layers, enabling safe hooking into GTA V's rendering pipeline while maintaining clean separation between graphics API code and menu logic.

Three-Layer Architecture Overview

The YimMenuV2 rendering stack is organized into distinct layers that handle specific concerns:

This separation allows developers to modify menu content without touching DirectX code, or port the renderer to a different graphics API without rewriting menu logic.

Renderer Core Layer

The Renderer Core in src/core/renderer/Renderer.cpp provides thread-safe singleton access to DirectX 12 resources through Renderer::GetInstance(). This layer abstracts all graphics API interaction away from the UI code.

DirectX 12 Device and Swap-Chain Management

Initialization begins with InitDX12, which retrieves the game's swap-chain and command queue via the Pointers struct. The implementation creates a ComPtr<IDXGISwapChain1>, extracts the underlying ID3D12Device, and sets up essential GPU resources:

  • A descriptor heap for CBV/SRV/UAV slots
  • Back-buffer RTV (Render Target View) heap
  • Command allocator and command list
  • Fence for GPU synchronization

These resources are stored in the singleton instance, ensuring consistent access across the application lifecycle.

ImGui Backend Integration

The renderer binds Dear ImGui to the game's window and DirectX 12 context through ImGui_ImplWin32_Init and ImGui_ImplDX12_Init. These calls connect ImGui to the Win32 window handle (Pointers.Hwnd) and the D3D12 device/command queue. Custom SRV (Shader Resource View) allocation callbacks forward to an internal HeapAllocator class that manages GPU memory descriptors.

Frame Synchronization

Each rendered frame follows a strict execution path within DX12OnPresentImpl:

  1. Start Frame – DX12NewFrame prepares ImGui draw data
  2. Execute Callbacks – Registered UI callbacks draw content
  3. End Frame – DX12EndFrame records fence values, presents the back-buffer, and advances the frame index

Fences ensure the CPU does not modify resources currently in use by the GPU, preventing race conditions during rendering.

Frontend Manager Layer

The Frontend Manager abstracts ImGui calls into a structured menu hierarchy that supports dynamic registration from both C++ and Lua scripts.

UIManager and Submenu Hierarchy

UIManager (defined in src/core/frontend/manager/UIManager.cpp) owns a collection of submenus stored as std::vector<std::shared_ptr<Submenu>>. It receives the per-frame callback from Renderer::DX12OnPresentImpl and forwards it to all registered UI components.

Submenus group related functionality under collapsible headings. The Submenu class in src/core/frontend/manager/Submenu.cpp maintains a list of categories and provides registration hooks used by the script engine. Developers create submenus via UIManager::GetInstance().AddSubmenu(), supplying a name and render callback:

auto& ui = UIManager::GetInstance();
auto misc = ui.AddSubmenu("Misc", []() {
    ImGui::Checkbox("God Mode", &g_GodMode);
});

Category Grouping System

Categories (implemented in src/core/frontend/manager/Category.cpp) organize options within submenus. Each category contains related toggles, sliders, or buttons. The class provides helper methods such as BeginGroup() and EndGroup() that map directly to ImGui's BeginGroup/EndGroup functions, ensuring consistent spacing and layout across the menu.

Game-Specific Frontend Layer

The Game-Specific Frontend translates the abstract UI hierarchy into the concrete menu visible during gameplay, handling input injection and visual styling.

GUI.cpp Entry Point

src/game/frontend/GUI.cpp serves as the primary entry point for the in-game interface. It configures global ImGui styles, loads fonts, and defines the top-level draw routine DrawGUI. The file registers a Win32 procedure callback (Renderer::WndProcImpl) that intercepts keyboard and mouse events, forwarding them to ImGui for input processing before the game processes them.

src/game/frontend/Menu.cpp defines the concrete menu structure visible to users, including tabs for "Self", "Vehicle", and "World". This file uses the UIManager API to instantiate submenus and categories, binding option callbacks (toggles, commands, sliders) to game variables.

The architecture allows Lua scripts to register new menu entries at runtime by calling the same UIManager methods used by the core C++ code, enabling extensibility without recompilation.

Custom Widget Implementation

Custom widgets demonstrate how the architecture extends beyond standard ImGui controls. The toggle widget in src/core/frontend/widgets/toggle/imgui_toggle.cpp provides a custom renderer in imgui_toggle_renderer.cpp that draws animated toggles using ImGui primitives. These widgets register with the Renderer through AddRendererCallBackImpl, inserting themselves into the per-frame draw list:

Renderer::GetInstance().AddRendererCallBackImpl(
    []() { ImGui::Text("Hello from a custom callback!"); },
    /*priority=*/100);

Rendering Execution Flow

The complete rendering pipeline follows this sequence:

  1. Startup – Renderer::InitImpl waits for the game window handle, then executes InitDX12 to capture the swap-chain
  2. Context Creation – ImGui context initializes, styles load, and DX12/Win32 backends bind to the game window
  3. Per-Frame Execution – On each Present call, DX12OnPresentImpl starts a new ImGui frame, executes all registered callbacks (menus and widgets), then renders via ImGui_ImplDX12_RenderDrawData
  4. Presentation – The frame fence synchronizes GPU completion before the back-buffer displays

This callback-driven approach ensures that UI code runs safely within the game's render thread without blocking or interfering with the main simulation loop.

Summary

  • YimMenuV2 employs a three-layer architecture separating DirectX 12 rendering, UI hierarchy management, and game-specific menu definitions
  • The Renderer Core (src/core/renderer/Renderer.cpp) manages GPU resources and ImGui backend integration through a thread-safe singleton
  • UIManager (src/core/frontend/manager/UIManager.cpp) maintains the submenu and category hierarchy, forwarding draw calls to ImGui
  • Game-specific code (src/game/frontend/GUI.cpp, Menu.cpp) handles concrete menu layouts, input hooks, and Lua bindings
  • Callback registration via AddRendererCallBackImpl allows both core features and scripts to inject custom draw code into the render loop
  • Strict fence synchronization prevents GPU/CPU race conditions during frame presentation

Frequently Asked Questions

What graphics API does YimMenuV2 use for menu rendering?

YimMenuV2 uses DirectX 12 as its graphics API, hooking into the game's existing swap-chain and command queue. The renderer extracts the ID3D12Device from the game's IDXGISwapChain1 and creates dedicated descriptor heaps and command lists for ImGui rendering, as implemented in src/core/renderer/Renderer.cpp.

How does YimMenuV2 integrate Dear ImGui with GTA V?

The integration uses the ImGui Win32 and DX12 backends. During initialization in Renderer.cpp, the code calls ImGui_ImplWin32_Init with the game's window handle (Pointers.Hwnd) and ImGui_ImplDX12_Init with the captured D3D12 device. Input is forwarded through a custom WndProc hook that processes keyboard and mouse events before they reach the game's message queue.

What is the purpose of the UIManager class in YimMenuV2?

UIManager serves as the abstract UI controller that owns the menu hierarchy. It maintains a vector of Submenu objects, each containing Category groups that hold individual options. The class provides the bridge between the low-level Renderer callbacks and high-level menu definitions, allowing both C++ code and Lua scripts to register new menu entries dynamically via AddSubmenu().

How can developers add custom widgets to the YimMenuV2 GUI?

Developers register custom draw code using Renderer::AddRendererCallBackImpl, supplying a lambda or function pointer that contains ImGui drawing commands. For reusable widgets, the architecture follows the pattern seen in src/core/frontend/widgets/toggle/imgui_toggle.cpp: create a renderer class that draws using ImGui primitives, then register it with a priority value to control drawing order relative to other UI elements.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →