diff --git a/imgui-lwjgl3/src/main/java/imgui/gl3/ImGuiImplGl3.java b/imgui-lwjgl3/src/main/java/imgui/gl3/ImGuiImplGl3.java index 7a135a84..ba5c7fa8 100644 --- a/imgui-lwjgl3/src/main/java/imgui/gl3/ImGuiImplGl3.java +++ b/imgui-lwjgl3/src/main/java/imgui/gl3/ImGuiImplGl3.java @@ -242,6 +242,10 @@ public boolean init() { * Method to do an initialization of the {@link ImGuiImplGl3} state. * It SHOULD be called before calling of the {@link ImGuiImplGl3#renderDrawData(ImDrawData)} method. *

+ * GL device objects (shader, buffers, font texture) are not created here; they are + * created lazily on the first {@link #newFrame()} or {@link #renderDrawData(ImDrawData)} call + * (behavior since 1.87, matching upstream). Prefer calling {@link #newFrame()} every frame. + *

* Method takes an argument, which should be a valid GLSL string with the version to use. *

      * ----------------------------------------
@@ -371,7 +375,25 @@ public void shutdown() {
         data = null;
     }
 
+    /**
+     * Prepare per-frame GL resources.
+     * 

+ * Since Dear ImGui 1.87 / imgui-java 1.87, shader program, buffers and the font + * texture are created lazily here (not in {@link #init(String)}). Call this every + * frame before {@link ImGui#newFrame()}, or at least once after {@code init} and + * before the first {@link #renderDrawData(ImDrawData)}. + */ public void newFrame() { + ensureDeviceObjects(); + } + + /** + * Create shader/program/VBO and font texture if they are not yet available. + * Shared by {@link #newFrame()} and {@link #renderDrawData(ImDrawData)} so that + * integrators that only call {@code init} + {@code renderDrawData} (the pre-1.87 + * pattern) do not hit a native NULL dereference in {@code glDrawElementsBaseVertex}. + */ + protected void ensureDeviceObjects() { if (data.shaderHandle == 0) { createDeviceObjects(); } @@ -470,6 +492,12 @@ public void renderDrawData(final ImDrawData drawData) { return; } + // Device objects used to be created in init() (imgui-java <= 1.86). Since 1.87 they are + // created lazily in newFrame() to match upstream imgui_impl_opengl3. Ensure them here as + // well so call sites that skip newFrame() (common after upgrades; see #361) do not crash + // with a native NULL pointer inside glDrawElementsBaseVertex. + ensureDeviceObjects(); + // In C++: iterates draw_data->Textures and calls ImGui_ImplOpenGL3_UpdateTexture for each non-OK status. // In Java: ImTextureData is not exposed in imgui-binding (follow-up); we keep the legacy createFontsTexture // path triggered from newFrame(), so dynamic atlas updates are not honored here yet.