Vlog 03: Integrating Dear ImGui (1.92.0+) with latest jME3: Initial Findings, Traps, and Architecture Choices
Hi everyone,
I am currently running some integration tests between the latest versions of the imgui-java wrapper (specifically targeting Dear ImGui 1.92.0+) and jMonkeyEngine 3.10.0+.
My goal is to build a robust, desktop-targeted UI integration layer. During my initial research and implementation phases, I encountered a few architectural shifts in both ecosystems that drastically change how we used to integrate ImGui in the past.
I wanted to share my current findings with the community as a personal study. Please note: these notes represent the current state of my ongoing tests. Some assumptions might be partial or subject to change as I dive deeper into the engine’s source code, so feedback or corrections from anyone more experienced are highly welcome!
Here is a summary of the pros, cons, and structural gotchas that have emerged from my test environment so far.
1. The jME Backend Shift: GLFW vs SDL3
The latest iterations of jME3 default to an SDL-based backend rather than the classic GLFW configuration.
- Pros: From what I can see, this is a great move for framework stability. SDL handles modern gamepads, complex multi-monitor environments, and Windows 11 DPI quirks much more robustly out of the box.
- Cons (for ImGui): This shift breaks immediate compatibility with standard ImGui setups. If you were relying on the well-tested
ImGuiImplGlfwbackend, you can no longer use it seamlessly if jME initializes the window context via SDL.
2. The Multi-Viewport Dilemma in Java
- Current Status: In the
imgui-javawrapper, the Multi-Viewport binding wrapper for SDL3 (ImGuiImplSdl3) does not seem to be fully completed or exposed yet, whereas it is fully operational inImGuiImplGlfw. - The Catch: * If you stick with jME’s new SDL backend , you might have to sacrifice Multi-Viewports for now, disabling
ImGuiConfigFlags.ViewportsEnableand keeping all UI windows docked internally.
3. Graphics API: OpenGL Desktop vs ANGLE (OpenGLES)
jME 3.10.0 introduces ANGLE as a default option (translating GLES3 commands into DirectX/Vulkan). On the other hand, the standard ImGuiImplGl3 renderer bundled in imgui-java performs hard-coded queries to the desktop org.lwjgl.opengl.GL subsystem.
- The Crash Trap: If you boot jME with
AppSettings.ANGLE_GLES3,imgui-javawill crash instantly duringinit()with an LWJGLIllegalStateException: setFunctionMissingAddresses has been called already. This happens because LWJGL does not allow initializing both Desktop GL and OpenGLES capabilities simultaneously on the same thread context. - Current Workaround: For a pure desktop target, forcing OpenGL Core Profile explicitly via
AppSettings.LWJGL_OPENGL32. - (Note: Supporting ANGLE would technically require duplicating the ImGui renderer class and manually swapping all standard OpenGL static imports with
org.lwjgl.opengles.GLES30counterparts, which might not be worth the overhead unless cross-platform mobile/web parity is required).
4. Mandatory Frame-by-Frame Sizing (io.setDisplaySize)
- What changed: In ImGui 1.92.0+, updating
io.setDisplaySize(logicalWidth, logicalHeight)on every single frame inside your update/render loop is highly recommended, if not mandatory. - Why it matters: With Windows 11 dynamic DPI scaling, moving a window across monitors with different scale factors instantly alters the logical bounds even if the pixel resolution looks identical. Updating this frame-by-frame prevents mouse misalignment and viewport stuttering.
5. Input Sinking & Custom Adapters
Because of these backend shifts, relying on automatic platform callbacks from ImGui can cause conflicts. Writing a custom JmeImGuiInputAdapter (subclassing RawInputListener) seems to be the most reliable path.
- Pros: It allows for precise input consumption. You can check if ImGui wants the mouse/keyboard and call
evt.setConsumed()to stop inputs from bleeding into your game’s camera or character controllers. - Cons: It requires a fair amount of boilerplate code to manually map every jME
KeyInputEventorMouseButtonEventto their correspondingImGuiKeyenums.
Current Conclusion for my Setup
Based on these early tests, if your target is strictly a Desktop Tool/Game :
- Forcing jME to run on OpenGL Desktop (
LWJGL_OPENGL33) feels like the safest choice to keep ImGui stable and performant. - If docked (internal) UI windows are enough for your project, sticking with jME’s new SDL standard is likely the best future-proof path. If you absolutely need floating OS viewports , falling back to the GLFW window context might be required until the Java SDL bindings mature.
I am completely open to any thoughts, workarounds, or alternative viewpoints on this topic. If you have managed to get this combination working differently, or if any of my assumptions need a correction, please let me know!
- Dear ImGui (1.92.0+) with latest jME3
Note: keep in mind that the latest versions of imgui-java now strictly require Java 17 to compile the project
plugins {
id 'java'
id 'application'
}
group = 'com.jme3.imgui'
version = '1.0.0-SNAPSHOT'
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
ext {
// jmeVersion = '3.9.0-stable'
jmeVersion = '3.10.0-beta1'
imguiVersion = '1.92.0'
}
repositories {
mavenCentral()
}
dependencies {
// jMonkeyEngine
implementation "org.jmonkeyengine:jme3-core:${jmeVersion}"
implementation "org.jmonkeyengine:jme3-desktop:${jmeVersion}"
implementation "org.jmonkeyengine:jme3-lwjgl3:${jmeVersion}"
runtimeOnly "org.jmonkeyengine:jme3-awt-dialogs:${jmeVersion}"
// ImGui Java
implementation "io.github.spair:imgui-java-app:${imguiVersion}"
implementation "io.github.spair:imgui-java-binding:${imguiVersion}"
// Native libraries (multi-platform)
runtimeOnly "io.github.spair:imgui-java-natives-windows:${imguiVersion}"
runtimeOnly "io.github.spair:imgui-java-natives-linux:${imguiVersion}"
runtimeOnly "io.github.spair:imgui-java-natives-macos:${imguiVersion}"
}
application {
mainClass = 'com.jme3.imgui.TestImGuiApplication'
}
tasks.withType(JavaCompile).configureEach {
options.encoding = 'UTF-8'
}
Discussion in the ATmosphere