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:
- Renderer Core (
src/core/renderer/Renderer.cpp) – Manages DirectX 12 device initialization, swap-chain hooking, and ImGui backend integration - Frontend Manager (
src/core/frontend/manager/UIManager.cpp,Submenu.cpp,Category.cpp) – Maintains the abstract UI hierarchy and forwards draw calls to ImGui - Game-Specific Frontend (
src/game/frontend/GUI.cpp,Menu.cpp) – Defines concrete menu layouts, styles, and game-specific input handling
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:
- Start Frame –
DX12NewFrameprepares ImGui draw data - Execute Callbacks – Registered UI callbacks draw content
- End Frame –
DX12EndFramerecords 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.
Menu Layout and Script Bindings
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:
- Startup –
Renderer::InitImplwaits for the game window handle, then executesInitDX12to capture the swap-chain - Context Creation – ImGui context initializes, styles load, and DX12/Win32 backends bind to the game window
- Per-Frame Execution – On each
Presentcall,DX12OnPresentImplstarts a new ImGui frame, executes all registered callbacks (menus and widgets), then renders viaImGui_ImplDX12_RenderDrawData - 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
AddRendererCallBackImplallows 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →