kotlin-graphics / imgui

Bloat-free Immediate Mode Graphical User interface for JVM with minimal dependencies (rewrite of dear imgui)
MIT License
604 stars 36 forks source link

java.lang.NoClassDefFoundError: uno/glfw/HWND #190

Closed doceazedo closed 1 year ago

doceazedo commented 1 year ago

I'm trying to use this library in a Minecraft mod, but the wiki seems to be very outdated (#113).

The game is crashing when I create a new context (line 4 below):

static {
    ImguiKt.MINECRAFT_BEHAVIORS = true;
    GlfwWindow window = new GlfwWindow(MinecraftClient.getInstance().getWindow().getHandle());
    new Context();
    implGlfw = new ImplGlfw(window, false, null);
    implGl3 = new ImplGL3();
}
Full code ```java package com.doceazedo.screen; import com.doceazedo.ExampleMod; import imgui.ImGui; import imgui.ImguiKt; import imgui.classes.Context; import imgui.classes.IO; import imgui.impl.gl.ImplGL3; import imgui.impl.glfw.ImplGlfw; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.screen.Screen; import net.minecraft.text.Text; import org.slf4j.Logger; import uno.glfw.GlfwWindow; import java.util.*; @Environment(EnvType.CLIENT) public class ImguiScreen extends Screen { private static ImGui imgui = ImGui.INSTANCE; private static ImplGL3 implGl3; private static ImplGlfw implGlfw; private static IO ImGuiIO; private static HashSet keyBuffer = new HashSet(); public ImguiScreen() { super(Text.of("ImguiScreen")); } // Initialization for imgui. static { ImguiKt.MINECRAFT_BEHAVIORS = true; GlfwWindow window = new GlfwWindow(MinecraftClient.getInstance().getWindow().getHandle()); new Context(); implGlfw = new ImplGlfw(window, false, null); implGl3 = new ImplGL3(); } // Prevents Minecraft from pausing the game whenever we open the GUI. @Override public boolean shouldPause() { return false; } // Tells imgui to enter a character, when typing on a textbox or similar. @Override public boolean charTyped(char chr, int keyCode) { if (ImGuiIO.getWantTextInput()) { ImGuiIO.addInputCharacter(chr); } super.charTyped(chr, keyCode); return true; } // Passes mouse scrolling to imgui. @Override public boolean mouseScrolled(double d, double e, double amount) { if (ImGuiIO.getWantCaptureMouse()) { ImGuiIO.setMouseWheel((float) amount); } super.mouseScrolled(d, e, amount); return true; } // Passes keypresses for imgui to handle. @Override public boolean keyPressed(int keyCode, int scanCode, int modifiers) { if (ImGuiIO.getWantCaptureKeyboard()) { ImGuiIO.getKeysDown()[keyCode] = true; keyBuffer.add(keyCode); } // Skip handling of the ESC key, because Minecraft uses it to close the screen. if (keyCode == 256) { ImGuiIO.getKeysDown()[256] = false; } super.keyPressed(keyCode, scanCode, modifiers); return true; } // Tells imgui the keys pressed have been released. @Override public boolean keyReleased(int keyCode, int scanCode, int modifiers) { ImGuiIO.getKeysDown()[keyCode] = false; keyBuffer.remove(keyCode); super.keyReleased(keyCode, scanCode, modifiers); return true; } @Override public void close() { // When Minecraft closes the screen, clear the key buffer. for (int keyCode: keyBuffer) { ImGuiIO.getKeysDown()[keyCode] = false; } keyBuffer.clear(); super.close(); } @Override public void render(DrawContext context, int mouseX, int mouseY, float delta) { ImGuiIO = imgui.getIo(); implGl3.newFrame(); implGlfw.newFrame(); imgui.newFrame(); imgui.showDemoWindow(new boolean[]{true}); imgui.render(); implGl3.renderDrawData(Objects.requireNonNull(imgui.getDrawData())); } } ```

With the following error:

[Render thread/ERROR] (Minecraft) Unreported exception thrown!
 java.lang.NoClassDefFoundError: uno/glfw/HWND
    at imgui.classes.IO.<init>(IO.kt:156) ~[imgui-core-1.79+05.jar:?]
    at imgui.classes.Context.<init>(Context.kt:37) ~[imgui-core-1.79+05.jar:?]
    at imgui.classes.Context.<init>(Context.kt:30) ~[imgui-core-1.79+05.jar:?]
    at imgui.classes.Context.<init>(Context.kt) ~[imgui-core-1.79+05.jar:?]
    at com.doceazedo.screen.ImguiScreen.<clinit>(ImguiScreen.java:45) ~[client/:?]
    at com.doceazedo.ExampleModClient.initializeKeybinds$lambda$0(ExampleModClient.kt:34) ~[client/:?]
    at net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents.lambda$static$2(ClientTickEvents.java:43) ~[fabric-lifecycle-events-v1-client-2.2.21+b3afc78b77.jar:?]
    at net.minecraft.client.MinecraftClient.handler$zcp000$fabric-lifecycle-events-v1$onEndTick(MinecraftClient.java:4522) ~[minecraft-clientonly-project-root-1.20.1-net.fabricmc.yarn.1_20_1.1.20.1+build.10-v2.jar:?]
    at net.minecraft.client.MinecraftClient.tick(MinecraftClient.java:1957) ~[minecraft-clientonly-project-root-1.20.1-net.fabricmc.yarn.1_20_1.1.20.1+build.10-v2.jar:?]
    at net.minecraft.client.MinecraftClient.render(MinecraftClient.java:1181) ~[minecraft-clientonly-project-root-1.20.1-net.fabricmc.yarn.1_20_1.1.20.1+build.10-v2.jar:?]
    at net.minecraft.client.MinecraftClient.run(MinecraftClient.java:802) ~[minecraft-clientonly-project-root-1.20.1-net.fabricmc.yarn.1_20_1.1.20.1+build.10-v2.jar:?]
    at net.minecraft.client.main.Main.main(Main.java:250) ~[minecraft-clientonly-project-root-1.20.1-net.fabricmc.yarn.1_20_1.1.20.1+build.10-v2.jar:?]
    at net.fabricmc.loader.impl.game.minecraft.MinecraftGameProvider.launch(MinecraftGameProvider.java:468) ~[fabric-loader-0.14.22.jar:?]
    at net.fabricmc.loader.impl.launch.knot.Knot.launch(Knot.java:74) ~[fabric-loader-0.14.22.jar:?]
    at net.fabricmc.loader.impl.launch.knot.KnotClient.main(KnotClient.java:23) ~[fabric-loader-0.14.22.jar:?]
    at net.fabricmc.devlaunchinjector.Main.main(Main.java:86) ~[dev-launch-injector-0.2.1+build.8.jar:?]
Caused by: java.lang.ClassNotFoundException: uno.glfw.HWND
    at jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) ~[?:?]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:525) ~[?:?]
    at net.fabricmc.loader.impl.launch.knot.KnotClassDelegate.loadClass(KnotClassDelegate.java:226) ~[fabric-loader-0.14.22.jar:?]
    at net.fabricmc.loader.impl.launch.knot.KnotClassLoader.loadClass(KnotClassLoader.java:112) ~[fabric-loader-0.14.22.jar:?]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:525) ~[?:?]
    ... 16 more
Caused by: java.lang.ClassNotFoundException: uno.glfw.HWND

The discussion points here are:

If we can get this fixed, I'm more than willing to update the docs/wiki/readme.

Thanks!

elect86 commented 1 year ago

Hello DoceAzedo,

in Uno I decoupled the OpenGL related stuff from GlfwWindow, in order to have GlWindow for OpenGL and VkWindow, later on, for Vulkan

If you need Opengl, use GlWindow now, which extends GlfwWindow in turns, all the methods you mentioned are there

Is the project public? I might look into that

I'll send you an invitation for the updating

doceazedo commented 1 year ago

Thanks for your reply!

I see, but GlWindow still doesn't seem to have the from method tho... so I tried using GlWindow in a similar way I was doing in the original post, but the error is the same:

ImguiKt.MINECRAFT_BEHAVIORS = true;
GlfwWindow glfwWindow = new GlfwWindow(MinecraftClient.getInstance().getWindow().getHandle());
GlWindow window = new GlWindow(glfwWindow, Caps.Profile.COMPATIBILITY, true);

// This doesn't seem to make any difference, as it's already being called when GlWindow is built:
window.makeCurrent(true); 

// Crashing here: `java.lang.NoClassDefFoundError: uno/glfw/HWND`
new Context();

implGlfw = new ImplGlfw(window, false, null);
implGl3 = new ImplGL3();

I uploaded the full source code here. I was using breadbyte/fabric-example-imgui and the wiki as references. The relevant class can be found here.

doceazedo commented 1 year ago

Welp, after a little more digging I think uno/glfw/HWND does not, in fact, exist:

CleanShot 2023-09-04 at 17 12 08@2x

I followed the stack trace to imgui-core's file IO.kt and noticed it is trying to import uno.glfw.HWND, which does not exist, instead of uno.kotlin.HWND. Does this work anywhere else?

I'm not sure where the source code for this resides so it's hard to debug it any further.

doceazedo commented 1 year ago

Got it! 🥳

Seems like I was using 1.79+05 as the README told me to, instead of the latest version, 1.89.7.

I had to add the Jitpack repo so sealed-enum would stop complaining:

repositories {
    maven {
        url "https://raw.githubusercontent.com/kotlin-graphics/mary/master"
    }
    maven {
        url "https://jitpack.io"
    }
}

I will now get the mouse click to work (only mouse hover is working atm for some reason) and clean up the code. When I get everything right I will update the docs.

CleanShot 2023-09-04 at 18 36 11@2x

Thanks for you help :)