Dear ImGui in an RPS UI panel
RPS UI is a panel render host. It does not export Dear ImGui functions, share an
ImGuiContext, or impose an ImGui ABI on consumers. Build Dear ImGui and its
DX11 renderer backend in your own mod. A non-ImGui D3D11 renderer can implement
the same callback contract.
For each independently managed consumer renderer:
- Prepare font bytes and persistent application data outside the render path.
- On the render thread, create your own ImGui context and initialize
ImGui_ImplDX11_Initwith the callback device/context. SetIniFilenameandLogFilenameto null if the panel should not perform implicit ImGui file I/O. - Before every ImGui call, select your context. Preserve/restore the previous context if your integration shares an ImGui library instance with other code.
- Set display size to the panel's pixel dimensions and framebuffer scale to 1. Supply finite positive delta time from the render frame.
- Add pointer position/button and scroll input, call the backend's
NewFrame,ImGui::NewFrame, draw widgets, thenImGui::RenderandImGui_ImplDX11_RenderDrawDatainto the provided target. - Rebuild backend/device resources on
deviceGenerationchange. Perform final backend/context destruction only after callback lifetime is safe.
Inside an initialized renderer, input mapping follows this pattern:
// frame is callback-borrowed; io belongs to this consumer's selected context.
io.DisplaySize = ImVec2(float(frame->pixelWidth), float(frame->pixelHeight));
io.DisplayFramebufferScale = ImVec2(1.0f, 1.0f);
io.DeltaTime = frame->deltaSeconds;
if (frame->pointerValid) {
io.AddMousePosEvent(frame->pointerPixelX, frame->pointerPixelY);
io.AddMouseButtonEvent(0, frame->primaryDown != 0);
constexpr float scrollUnitsPerSecond = 5.5f; // Consumer UX choice.
io.AddMouseWheelEvent(frame->scrollAxisX * scrollUnitsPerSecond * io.DeltaTime,
frame->scrollAxisY * scrollUnitsPerSecond * io.DeltaTime);
} else {
io.AddMousePosEvent(-FLT_MAX, -FLT_MAX); // <cfloat>
io.AddMouseButtonEvent(0, false);
}
const bool backDown = frame->pointerValid && frame->backDown;
const bool backPressed = backDown && !backWasDown;
backWasDown = backDown; // Render-thread-owned state; clear on close/lifecycle loss.
This is an integration fragment, not a second complete example plugin. The
SDK's compiled example covers the host registration/presentation calls without
requiring ImGui as a dependency. backPressed should enqueue a bounded UI action
or update local navigation; game/config writes belong on the game task thread.
Use ConfigNavigation only when the requested feature grant includes it.
For a radial wheel, combine Transparent, FixedSize, and CircularInput,
draw the circle yourself with alpha outside it, and omit ConfigNavigation.
The opening hold and release-to-select gesture remain the consumer's policy.
The current host has no keyboard/text-input API, shared font/texture registry, modal arbitration API, application settings schema, or callback-drain API. Treat these as absent capabilities. Do not describe them as supported because Dear ImGui itself can draw the corresponding widgets.