diff --git a/bin/imgui-java.dll b/bin/imgui-java.dll index a6262fa..1b54c05 100755 Binary files a/bin/imgui-java.dll and b/bin/imgui-java.dll differ diff --git a/bin/imgui-java64.dll b/bin/imgui-java64.dll index 2a6cc7d..8b04c82 100755 Binary files a/bin/imgui-java64.dll and b/bin/imgui-java64.dll differ diff --git a/bin/libimgui-java.so b/bin/libimgui-java.so index e7e62ab..db596dd 100755 Binary files a/bin/libimgui-java.so and b/bin/libimgui-java.so differ diff --git a/bin/libimgui-java64.so b/bin/libimgui-java64.so index 2c4b708..66ef5ac 100755 Binary files a/bin/libimgui-java64.so and b/bin/libimgui-java64.so differ diff --git a/buildSrc/src/main/groovy/imgui/generate/GenerateLibs.groovy b/buildSrc/src/main/groovy/imgui/generate/GenerateLibs.groovy index 447d666..e3609e7 100644 --- a/buildSrc/src/main/groovy/imgui/generate/GenerateLibs.groovy +++ b/buildSrc/src/main/groovy/imgui/generate/GenerateLibs.groovy @@ -24,6 +24,7 @@ class GenerateLibs extends DefaultTask { // Copy ImGui h/cpp files project.copy { CopySpec spec -> spec.from(project.rootProject.file('imgui')) { CopySpec it -> it.include('*.h', '*.cpp') } + spec.from(project.rootProject.file('imgui/misc/freetype')) { CopySpec it -> it.include('*.h', '*.cpp') } spec.from(project.rootProject.file('imgui-binding/src/main/native')) spec.into(jniDir) } @@ -37,6 +38,17 @@ class GenerateLibs extends DefaultTask { def linux32 = BuildTarget.newDefaultTarget(BuildTarget.TargetOs.Linux, false) def linux64 = BuildTarget.newDefaultTarget(BuildTarget.TargetOs.Linux, true) + // Freetype Deps Config + win32.cppFlags += " -fstack-protector -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/harfbuzz -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include" + win32.libraries += "-lfreetype -lbz2 -lssp" + win64.cppFlags += " -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/harfbuzz -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include" + win64.libraries += "-lfreetype -lbz2 -lssp" + linux32.cppFlags += " -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/harfbuzz -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include" + linux32.linkerFlags += " -lfreetype" + linux64.cppFlags += " -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/harfbuzz -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include" + linux64.linkerFlags += " -lfreetype" + // End + new AntScriptGenerator().generate(buildConfig, win32, win64, linux32, linux64) // Generate native libraries diff --git a/imgui-binding/src/main/java/imgui/ImGuiFreeType.java b/imgui-binding/src/main/java/imgui/ImGuiFreeType.java new file mode 100644 index 0000000..89617a8 --- /dev/null +++ b/imgui-binding/src/main/java/imgui/ImGuiFreeType.java @@ -0,0 +1,74 @@ +package imgui; + +/** + * Read: https://raw.githubusercontent.com/ocornut/imgui/v1.76/misc/freetype/README.md + */ +public final class ImGuiFreeType { + private ImGuiFreeType() { + } + + /*JNI + #include + #include + */ + + public static void buildFontAtlas(final ImFontAtlas atlas) { + nBuildFontAtlas(atlas.ptr, 0); + } + + public static void buildFontAtlas(final ImFontAtlas atlas, final int extraFlags) { + nBuildFontAtlas(atlas.ptr, extraFlags); + } + + private static native void nBuildFontAtlas(long atlasPtr, int extraFlags); /* + ImGuiFreeType::BuildFontAtlas((ImFontAtlas*)atlasPtr, (unsigned int)extraFlags); + */ + + /** + * Hinting greatly impacts visuals (and glyph sizes). + * When disabled, FreeType generates blurrier glyphs, more or less matches the stb's output. + * The Default hinting mode usually looks good, but may distort glyphs in an unusual way. + * The Light hinting mode generates fuzzier glyphs but better matches Microsoft's rasterizer. + *

+ * You can set those flags on a per font basis in ImFontConfig::RasterizerFlags. + * Use the 'extra_flags' parameter of BuildFontAtlas() to force a flag on all your fonts. + */ + public static final class RasterizerFlags { + /** + * By default, hinting is enabled and the font's native hinter is preferred over the auto-hinter. + * Disable hinting. This generally generates 'blurrier' bitmap glyphs when the glyph are rendered in any of the anti-aliased modes. + */ + public static final int NoHinting = 1; + /** + * Disable auto-hinter. + */ + public static final int NoAutoHint = 1 << 1; + /** + * Indicates that the auto-hinter is preferred over the font's native hinter. + */ + public static final int ForceAutoHint = 1 << 2; + /** + * A lighter hinting algorithm for gray-level modes. Many generated glyphs are fuzzier but better resemble their original shape. + * This is achieved by snapping glyphs to the pixel grid only vertically (Y-axis), + * as is done by Microsoft's ClearType and Adobe's proprietary font renderer. + * This preserves inter-glyph spacing in horizontal text. + */ + public static final int LightHinting = 1 << 3; + /** + * Strong hinting algorithm that should only be used for monochrome output. + */ + public static final int MonoHinting = 1 << 4; + /** + * Styling: Should we artificially embolden the font? + */ + public static final int Bold = 1 << 5; + /** + * Styling: Should we slant the font, emulating italic style? + */ + public static final int Oblique = 1 << 6; + /** + * Disable anti-aliasing. Combine this with MonoHinting for best results! + */ + public static final int Monochrome = 1 << 7; + } +} diff --git a/imgui-lwjgl3/src/test/java/ImGuiGlfwExample.java b/imgui-lwjgl3/src/test/java/ImGuiGlfwExample.java index 1c2b95a..21b03ee 100644 --- a/imgui-lwjgl3/src/test/java/ImGuiGlfwExample.java +++ b/imgui-lwjgl3/src/test/java/ImGuiGlfwExample.java @@ -1,6 +1,7 @@ import imgui.ImFontAtlas; import imgui.ImFontConfig; import imgui.ImGui; +import imgui.ImGuiFreeType; import imgui.ImGuiIO; import imgui.callbacks.ImStrConsumer; import imgui.callbacks.ImStrSupplier; @@ -29,9 +30,9 @@ import static org.lwjgl.system.MemoryUtil.NULL; @SuppressWarnings("MagicNumber") public final class ImGuiGlfwExample { - private long windowPtr; // current GLFW window pointer + private long windowPtr; // pointer to the current GLFW window - // To get window properties + // For application window properties private final int[] winWidth = new int[1]; private final int[] winHeight = new int[1]; private final int[] fbWidth = new int[1]; @@ -48,7 +49,7 @@ public final class ImGuiGlfwExample { private final ImGuiImplGl3 imGuiGl3 = new ImGuiImplGl3(); private String glslVersion = null; // We can initialize our renderer with different versions of the GLSL - // Ui to render + // User UI to render private final ExampleUi exampleUi = new ExampleUi(); public void run() throws Exception { @@ -60,7 +61,7 @@ public final class ImGuiGlfwExample { destroyGlfw(); } - // Initialize GLFW + create OpenGL context. + // Initialize GLFW + create an OpenGL context. // All code is mostly a copy-paste from the official LWJGL3 "Get Started": https://www.lwjgl.org/guide private void initGlfw() { // Setup an error callback. The default implementation @@ -78,7 +79,6 @@ public final class ImGuiGlfwExample { decideGlGlslVersions(); - // Create the window windowPtr = glfwCreateWindow(1280, 768, "Dear ImGui + GLFW + LWJGL Example", NULL, NULL); if (windowPtr == NULL) { @@ -134,6 +134,7 @@ public final class ImGuiGlfwExample { // This line is critical for Dear ImGui to work. ImGui.createContext(); + // ------------------------------------------------------------ // Initialize ImGuiIO config final ImGuiIO io = ImGui.getIO(); @@ -142,6 +143,7 @@ public final class ImGuiGlfwExample { io.setBackendFlags(ImGuiBackendFlags.HasMouseCursors); // Mouse cursors to display while resizing windows etc. io.setBackendPlatformName("imgui_java_impl_glfw"); + // ------------------------------------------------------------ // Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array. final int[] keyMap = new int[ImGuiKey.COUNT]; keyMap[ImGuiKey.Tab] = GLFW_KEY_TAB; @@ -168,6 +170,7 @@ public final class ImGuiGlfwExample { keyMap[ImGuiKey.Z] = GLFW_KEY_Z; io.setKeyMap(keyMap); + // ------------------------------------------------------------ // Mouse cursors mapping mouseCursors[ImGuiMouseCursor.Arrow] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR); mouseCursors[ImGuiMouseCursor.TextInput] = glfwCreateStandardCursor(GLFW_IBEAM_CURSOR); @@ -180,7 +183,7 @@ public final class ImGuiGlfwExample { mouseCursors[ImGuiMouseCursor.NotAllowed] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR); // ------------------------------------------------------------ - // Here goes GLFW callbacks to update user input in Dear ImGui + // GLFW callbacks to handle user input glfwSetKeyCallback(windowPtr, (w, key, scancode, action, mods) -> { if (action == GLFW_PRESS) { @@ -238,44 +241,43 @@ public final class ImGuiGlfwExample { // ------------------------------------------------------------ // Fonts configuration - - // ------------------- - // Fonts merge example + // Read: https://raw.githubusercontent.com/ocornut/imgui/master/docs/FONTS.txt final ImFontAtlas fontAtlas = io.getFonts(); + final ImFontConfig fontConfig = new ImFontConfig(); // Natively allocated object, should be explicitly destroyed - // First of all we add a default font, which is 'ProggyClean.ttf, 13px' + // Glyphs could be added per-font as well as per config used globally like here + fontConfig.setGlyphRanges(fontAtlas.getGlyphRangesCyrillic()); + + // Add a default font, which is 'ProggyClean.ttf, 13px' fontAtlas.addFontDefault(); - final ImFontConfig fontConfig = new ImFontConfig(); // Keep in mind that creation of the ImFontConfig will allocate the native memory - fontConfig.setMergeMode(true); // All fonts added while this mode is turned on will be merged with the previously added font + // Fonts merge example + fontConfig.setMergeMode(true); // When enabled, all fonts added with this config would be merged with the previously added font fontConfig.setPixelSnapH(true); - fontConfig.setGlyphRanges(fontAtlas.getGlyphRangesCyrillic()); // Additional glyphs could be added like this or in "addFontFrom*()" methods - // We merge font loaded from resources with the default one. Thus we will get an absent cyrillic glyphs fontAtlas.addFontFromMemoryTTF(loadFromResources("basis33.ttf"), 16, fontConfig); - // Disable merge mode and add all other fonts normally fontConfig.setMergeMode(false); fontConfig.setPixelSnapH(false); - // ------------------------------ // Fonts from file/memory example + // We can add new fonts from the file system + fontAtlas.addFontFromFileTTF("src/test/resources/Righteous-Regular.ttf", 14, fontConfig); + fontAtlas.addFontFromFileTTF("src/test/resources/Righteous-Regular.ttf", 16, fontConfig); - fontConfig.setRasterizerMultiply(1.2f); // This will make fonts a bit more readable - - // We can add new fonts directly from file - fontAtlas.addFontFromFileTTF("src/test/resources/DroidSans.ttf", 13, fontConfig); - fontAtlas.addFontFromFileTTF("src/test/resources/DroidSans.ttf", 14, fontConfig); - - // Or directly from memory - fontConfig.setName("Roboto-Regular.ttf, 13px"); // This name will be displayed in Style Editor - fontAtlas.addFontFromMemoryTTF(loadFromResources("Roboto-Regular.ttf"), 13, fontConfig); - fontConfig.setName("Roboto-Regular.ttf, 14px"); // We can apply a new config value every time we add a new font + // Or directly from the memory + fontConfig.setName("Roboto-Regular.ttf, 14px"); // This name will be displayed in Style Editor fontAtlas.addFontFromMemoryTTF(loadFromResources("Roboto-Regular.ttf"), 14, fontConfig); + fontConfig.setName("Roboto-Regular.ttf, 16px"); // We can apply a new config value every time we add a new font + fontAtlas.addFontFromMemoryTTF(loadFromResources("Roboto-Regular.ttf"), 16, fontConfig); fontConfig.destroy(); // After all fonts were added we don't need this config more + // ------------------------------------------------------------ + // Use freetype instead of stb_truetype to build a fonts texture + ImGuiFreeType.buildFontAtlas(fontAtlas, ImGuiFreeType.RasterizerFlags.LightHinting); + // Method initializes LWJGL3 renderer. // This method SHOULD be called after you've initialized your ImGui configuration (fonts and so on). // ImGui context should be created as well. @@ -283,7 +285,7 @@ public final class ImGuiGlfwExample { } // Main application loop - private void loop() throws Exception { + private void loop() { double time = 0; // to track our frame delta value // Run the rendering loop until the user has attempted to close the window @@ -295,7 +297,7 @@ public final class ImGuiGlfwExample { startFrame((float) deltaTime); - // Any Dear ImGui code SHOULD go between NewFrame()/Render() methods + // Any Dear ImGui code SHOULD go between ImGui.newFrame()/ImGui.render() methods ImGui.newFrame(); exampleUi.render(); ImGui.render(); @@ -309,32 +311,30 @@ public final class ImGuiGlfwExample { glClearColor(exampleUi.backgroundColor[0], exampleUi.backgroundColor[1], exampleUi.backgroundColor[2], 0.0f); glClear(GL_COLOR_BUFFER_BIT); - // Get window size properties and mouse position + // Get window properties and mouse position glfwGetWindowSize(windowPtr, winWidth, winHeight); glfwGetFramebufferSize(windowPtr, fbWidth, fbHeight); glfwGetCursorPos(windowPtr, mousePosX, mousePosY); - // We SHOULD call those methods to update ImGui state for current frame + // We SHOULD call those methods to update Dear ImGui state for the current frame final ImGuiIO io = ImGui.getIO(); io.setDisplaySize(winWidth[0], winHeight[0]); io.setDisplayFramebufferScale((float) fbWidth[0] / winWidth[0], (float) fbHeight[0] / winHeight[0]); io.setMousePos((float) mousePosX[0], (float) mousePosY[0]); io.setDeltaTime(deltaTime); - // Update mouse cursor + // Update the mouse cursor final int imguiCursor = ImGui.getMouseCursor(); glfwSetCursor(windowPtr, mouseCursors[imguiCursor]); glfwSetInputMode(windowPtr, GLFW_CURSOR, GLFW_CURSOR_NORMAL); } private void endFrame() { - // After Dear ImGui prepared a draw data, we use it in LWJGL3 renderer. + // After Dear ImGui prepared a draw data, we use it in the LWJGL3 renderer. // At that moment ImGui will be rendered to the current OpenGL context. imGuiGl3.render(ImGui.getDrawData()); - glfwSwapBuffers(windowPtr); // swap the color buffers - - // Poll for window events. The key callback above will only be invoked during this call. + glfwSwapBuffers(windowPtr); glfwPollEvents(); } diff --git a/imgui-lwjgl3/src/test/resources/DroidSans.ttf b/imgui-lwjgl3/src/test/resources/DroidSans.ttf deleted file mode 100644 index 767c63a..0000000 Binary files a/imgui-lwjgl3/src/test/resources/DroidSans.ttf and /dev/null differ diff --git a/imgui-lwjgl3/src/test/resources/Righteous-Regular.ttf b/imgui-lwjgl3/src/test/resources/Righteous-Regular.ttf new file mode 100644 index 0000000..fc9c0a8 Binary files /dev/null and b/imgui-lwjgl3/src/test/resources/Righteous-Regular.ttf differ