@@ -242,6 +242,10 @@ public boolean init() {
242242 * Method to do an initialization of the {@link ImGuiImplGl3} state.
243243 * It SHOULD be called before calling of the {@link ImGuiImplGl3#renderDrawData(ImDrawData)} method.
244244 * <p>
245+ * GL device objects (shader, buffers, font texture) are <b>not</b> created here; they are
246+ * created lazily on the first {@link #newFrame()} or {@link #renderDrawData(ImDrawData)} call
247+ * (behavior since 1.87, matching upstream). Prefer calling {@link #newFrame()} every frame.
248+ * <p>
245249 * Method takes an argument, which should be a valid GLSL string with the version to use.
246250 * <pre>
247251 * ----------------------------------------
@@ -371,7 +375,25 @@ public void shutdown() {
371375 data = null ;
372376 }
373377
378+ /**
379+ * Prepare per-frame GL resources.
380+ * <p>
381+ * Since Dear ImGui 1.87 / imgui-java 1.87, shader program, buffers and the font
382+ * texture are created lazily here (not in {@link #init(String)}). Call this every
383+ * frame before {@link ImGui#newFrame()}, or at least once after {@code init} and
384+ * before the first {@link #renderDrawData(ImDrawData)}.
385+ */
374386 public void newFrame () {
387+ ensureDeviceObjects ();
388+ }
389+
390+ /**
391+ * Create shader/program/VBO and font texture if they are not yet available.
392+ * Shared by {@link #newFrame()} and {@link #renderDrawData(ImDrawData)} so that
393+ * integrators that only call {@code init} + {@code renderDrawData} (the pre-1.87
394+ * pattern) do not hit a native NULL dereference in {@code glDrawElementsBaseVertex}.
395+ */
396+ protected void ensureDeviceObjects () {
375397 if (data .shaderHandle == 0 ) {
376398 createDeviceObjects ();
377399 }
@@ -470,6 +492,12 @@ public void renderDrawData(final ImDrawData drawData) {
470492 return ;
471493 }
472494
495+ // Device objects used to be created in init() (imgui-java <= 1.86). Since 1.87 they are
496+ // created lazily in newFrame() to match upstream imgui_impl_opengl3. Ensure them here as
497+ // well so call sites that skip newFrame() (common after upgrades; see #361) do not crash
498+ // with a native NULL pointer inside glDrawElementsBaseVertex.
499+ ensureDeviceObjects ();
500+
473501 // In C++: iterates draw_data->Textures and calls ImGui_ImplOpenGL3_UpdateTexture for each non-OK status.
474502 // In Java: ImTextureData is not exposed in imgui-binding (follow-up); we keep the legacy createFontsTexture
475503 // path triggered from newFrame(), so dynamic atlas updates are not honored here yet.
0 commit comments