From f16672b80a1e399b801d669c930d88555db09c1a Mon Sep 17 00:00:00 2001 From: SpaiR Date: Mon, 3 Feb 2020 23:51:26 +0300 Subject: [PATCH] [fonts] Initial fonts support commit --- config/checkstyle/checkstyle.xml | 4 - .../src/main/java/imgui/ImDestroyable.java | 9 + .../src/main/java/imgui/ImDrawData.java | 1 + .../src/main/java/imgui/ImFontAtlas.java | 142 +++++++++ .../src/main/java/imgui/ImFontConfig.java | 273 ++++++++++++++++++ imgui-binding/src/main/java/imgui/ImGui.java | 22 +- .../src/main/java/imgui/ImGuiIO.java | 39 ++- .../src/main/java/imgui/TexDataRGBA32.java | 48 --- .../src/main/java/imgui/gl3/ImGuiImplGl3.java | 15 +- .../src/test/java/ImGuiGlfwExample.java | 7 +- 10 files changed, 491 insertions(+), 69 deletions(-) create mode 100644 imgui-binding/src/main/java/imgui/ImDestroyable.java create mode 100644 imgui-binding/src/main/java/imgui/ImFontAtlas.java create mode 100644 imgui-binding/src/main/java/imgui/ImFontConfig.java delete mode 100644 imgui-binding/src/main/java/imgui/TexDataRGBA32.java diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml index 882f0e1..2c05670 100644 --- a/config/checkstyle/checkstyle.xml +++ b/config/checkstyle/checkstyle.xml @@ -164,10 +164,6 @@ - - - - diff --git a/imgui-binding/src/main/java/imgui/ImDestroyable.java b/imgui-binding/src/main/java/imgui/ImDestroyable.java new file mode 100644 index 0000000..71c1ae7 --- /dev/null +++ b/imgui-binding/src/main/java/imgui/ImDestroyable.java @@ -0,0 +1,9 @@ +package imgui; + +/** + * While implementing this interface, class could be manually destroyed (free allocated memory on the JNI side). + * Read javadoc and "BINDING NOTICE" for specific cases. + */ +interface ImDestroyable { + void destroy(); +} diff --git a/imgui-binding/src/main/java/imgui/ImDrawData.java b/imgui-binding/src/main/java/imgui/ImDrawData.java index c4e22f7..4176da8 100644 --- a/imgui-binding/src/main/java/imgui/ImDrawData.java +++ b/imgui-binding/src/main/java/imgui/ImDrawData.java @@ -6,6 +6,7 @@ import java.nio.ByteOrder; /** * All draw data to render a Dear ImGui frame. + *

* BINDING NOTICE: DO NOT TRY TO MODIFY FIELDS OF THIS CLASS MANUALLY! You should only access their values after {@link ImGui#render()} call. */ public final class ImDrawData { diff --git a/imgui-binding/src/main/java/imgui/ImFontAtlas.java b/imgui-binding/src/main/java/imgui/ImFontAtlas.java new file mode 100644 index 0000000..882c0a2 --- /dev/null +++ b/imgui-binding/src/main/java/imgui/ImFontAtlas.java @@ -0,0 +1,142 @@ +package imgui; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +/** + * Load and rasterize multiple TTF/OTF fonts into a same texture. The font atlas will build a single texture holding: + * - One or more fonts. + * - Custom graphics data needed to render the shapes needed by Dear ImGui. + * - Mouse cursor shapes for software cursor rendering (unless setting 'Flags |= ImFontAtlasFlags_NoMouseCursors' in the font atlas). + * It is the user-code responsibility to setup/build the atlas, then upload the pixel data into a texture accessible by your graphics api. + * - Optionally, call any of the AddFont*** functions. If you don't call any, the default font embedded in the code will be loaded for you. + * - Call GetTexDataAsAlpha8() or GetTexDataAsRGBA32() to build and retrieve pixels data. + * - Upload the pixels data into a texture within your graphics system (see imgui_impl_xxxx.cpp examples) + * - Call SetTexID(my_tex_id); and pass the pointer/identifier to your texture in a format natural to your graphics API. + * This value will be passed back to you during rendering to identify the texture. Read FAQ entry about ImTextureID for more details. + * Common pitfalls: + * - If you pass a 'glyph_ranges' array to AddFont*** functions, you need to make sure that your array persist up until the + * atlas is build (when calling GetTexData*** or Build()). We only copy the pointer, not the data. + * - Important: By default, AddFontFromMemoryTTF() takes ownership of the data. Even though we are not writing to it, we will free the pointer on destruction. + * You can set font_cfg->FontDataOwnedByAtlas=false to keep ownership of your data and it won't be freed, + * - Even though many functions are suffixed with "TTF", OTF data is supported just as well. + * - This is an old API and it is currently awkward for those and and various other reasons! We will address them in the future! + */ +public final class ImFontAtlas implements ImDestroyable { + final long ptr; + + /** + * This class will create a native structure. + * Call {@link #destroy()} method to manually free used memory. + */ + public ImFontAtlas() { + ImGui.touch(); + ptr = nCreate(); + } + + ImFontAtlas(final long ptr) { + this.ptr = ptr; + } + + @Override + public void destroy() { + nDestroy(ptr); + } + + /*JNI + #include + + jfieldID imFontAtlasPtrID; + + #define IM_FONT_ATLAS ((ImFontAtlas*)env->GetLongField(object, imFontAtlasPtrID)) + */ + + static native void nInit(); /* + jclass jImFontAtlasClass = env->FindClass("imgui/ImFontAtlas"); + imFontAtlasPtrID = env->GetFieldID(jImFontAtlasClass, "ptr", "J"); + */ + + private native long nCreate(); /* + ImFontAtlas* imFontAtlas = new ImFontAtlas(); + return (long)imFontAtlas; + */ + + private native void nDestroy(long ptr); /* + delete (ImFontAtlas*)ptr; + */ + + // Build atlas, retrieve pixel data. + // User is in charge of copying the pixels into graphics memory (e.g. create a texture with your engine). Then store your texture handle with SetTexID(). + // The pitch is always = Width * BytesPerPixels (1 or 4) + // Building in RGBA32 format is provided for convenience and compatibility, but note that unless you manually manipulate or copy color data into + // the texture (e.g. when using the AddCustomRect*** api), then the RGB pixels emitted will always be white (~75% of memory/bandwidth waste. + + /** + * Build pixels data. This is called automatically for you by the GetTexData*** functions. + */ + public native boolean build(); /* + return IM_FONT_ATLAS->Build(); + */ + + /** + * 1 byte-per-pixel + */ + public ByteBuffer getTexDataAsAlpha8(final ImInt outWidth, final ImInt outHeight) { + return getTexDataAsAlpha8(outWidth, outHeight, new ImInt()); + } + + /** + * 1 byte-per-pixel + */ + public ByteBuffer getTexDataAsAlpha8(final ImInt outWidth, final ImInt outHeight, final ImInt outBytesPerPixel) { + final byte[] tmpBuff = getTexDataAsAlpha8(outWidth.data, outHeight.data, outBytesPerPixel.data); + final ByteBuffer buffer = ByteBuffer.allocateDirect(tmpBuff.length).order(ByteOrder.nativeOrder()); + buffer.put(tmpBuff); + buffer.flip(); + return buffer; + } + + private native byte[] getTexDataAsAlpha8(int[] outWidth, int[] outHeight, int[] outBytesPerPixel); /* + unsigned char* pixels; + IM_FONT_ATLAS->GetTexDataAsAlpha8(&pixels, &outWidth[0], &outHeight[0], &outBytesPerPixel[0]); + int size = outWidth[0] * outHeight[0] * outBytesPerPixel[0]; + jbyteArray jBytes = env->NewByteArray(size); + env->SetByteArrayRegion(jBytes, 0, size, (jbyte*)pixels); + return jBytes; + */ + + /** + * 4 bytes-per-pixel + */ + public ByteBuffer getTexDataAsRGBA32(final ImInt outWidth, final ImInt outHeight) { + return getTexDataAsRGBA32(outWidth, outHeight, new ImInt()); + } + + /** + * 4 bytes-per-pixel + */ + public ByteBuffer getTexDataAsRGBA32(final ImInt outWidth, final ImInt outHeight, final ImInt outBytesPerPixel) { + final byte[] tmpBuff = nGetTexDataAsRGBA32(outWidth.data, outHeight.data, outBytesPerPixel.data); + final ByteBuffer buffer = ByteBuffer.allocateDirect(tmpBuff.length).order(ByteOrder.nativeOrder()); + buffer.put(tmpBuff); + buffer.flip(); + return buffer; + } + + private native byte[] nGetTexDataAsRGBA32(int[] outWidth, int[] outHeight, int[] outBytesPerPixel); /* + unsigned char* pixels; + IM_FONT_ATLAS->GetTexDataAsRGBA32(&pixels, &outWidth[0], &outHeight[0], &outBytesPerPixel[0]); + int size = outWidth[0] * outHeight[0] * outBytesPerPixel[0]; + jbyteArray jBytes = env->NewByteArray(size); + env->SetByteArrayRegion(jBytes, 0, size, (jbyte*)pixels); + return jBytes; + */ + + public native boolean isBuilt(); /* + return IM_FONT_ATLAS->IsBuilt(); + */ + + public native void setTexID(int imTextureId); /* + IM_FONT_ATLAS->SetTexID((ImTextureID)imTextureId); + */ +} diff --git a/imgui-binding/src/main/java/imgui/ImFontConfig.java b/imgui-binding/src/main/java/imgui/ImFontConfig.java new file mode 100644 index 0000000..8686cb7 --- /dev/null +++ b/imgui-binding/src/main/java/imgui/ImFontConfig.java @@ -0,0 +1,273 @@ +package imgui; + +public final class ImFontConfig implements ImDestroyable { + final long ptr; + + private short[] glyphRanges; + + /** + * This class will create a native structure. + * Call {@link #destroy()} method to manually free used memory. + */ + public ImFontConfig() { + ImGui.touch(); + ptr = nCreate(); + } + + ImFontConfig(final long ptr) { + this.ptr = ptr; + } + + @Override + public void destroy() { + nDestroy(ptr); + } + + /*JNI + #include + #include "jni_common.h" + + jfieldID imFontConfigPtrID; + + #define IM_FONT_CONFIG ((ImFontConfig*)env->GetLongField(object, imFontConfigPtrID)) + */ + + static native void nInit(); /* + jclass jImFontConfigClass = env->FindClass("imgui/ImFontConfig"); + imFontConfigPtrID = env->GetFieldID(jImFontConfigClass, "ptr", "J"); + */ + + private native long nCreate(); /* + ImFontConfig* imFontConfig = new ImFontConfig(); + return (long)imFontConfig; + */ + + private native void nDestroy(long ptr); /* + delete (ImFontConfig*)ptr; + */ + + /** + * TTF/OTF data ownership taken by the container ImFontAtlas (will delete memory itself). + */ + public native boolean getFontDataOwnedByAtlas(); /* + return IM_FONT_CONFIG->FontDataOwnedByAtlas; + */ + + /** + * TTF/OTF data ownership taken by the container ImFontAtlas (will delete memory itself). + */ + public native void setFontDataOwnedByAtlas(boolean isFontDataOwnedByAtlas); /* + IM_FONT_CONFIG->FontDataOwnedByAtlas = isFontDataOwnedByAtlas; + */ + + /** + * Index of font within TTF/OTF file + */ + public native int getFontNo(); /* + return IM_FONT_CONFIG->FontNo; + */ + + /** + * Index of font within TTF/OTF file + */ + public native void setFontNo(int fontNo); /* + IM_FONT_CONFIG->FontNo = fontNo; + */ + + /** + * Size in pixels for rasterizer (more or less maps to the resulting font height). + */ + public native float getSizePixels(); /* + return IM_FONT_CONFIG->SizePixels; + */ + + /** + * Size in pixels for rasterizer (more or less maps to the resulting font height). + */ + public native void setSizePixels(float sizePixels); /* + IM_FONT_CONFIG->SizePixels = sizePixels; + */ + + /** + * Rasterize at higher quality for sub-pixel positioning. + * Read https://github.com/nothings/stb/blob/master/tests/oversample/README.md for details. + */ + public native int getOversampleH(); /* + return IM_FONT_CONFIG->OversampleH; + */ + + /** + * Rasterize at higher quality for sub-pixel positioning. + * Read https://github.com/nothings/stb/blob/master/tests/oversample/README.md for details. + */ + public native void setOversampleH(int oversampleH); /* + IM_FONT_CONFIG->OversampleH = oversampleH; + */ + + /** + * Rasterize at higher quality for sub-pixel positioning. + * We don't use sub-pixel positions on the Y axis. + */ + public native int getOversampleV(); /* + return IM_FONT_CONFIG->OversampleV; + */ + + /** + * Rasterize at higher quality for sub-pixel positioning. + * We don't use sub-pixel positions on the Y axis. + */ + public native void setOversampleV(int oversampleV); /* + IM_FONT_CONFIG->OversampleV = oversampleV; + */ + + /** + * Align every glyph to pixel boundary. Useful e.g. if you are merging a non-pixel aligned font with the default font. + * If enabled, you can set OversampleH/V to 1. + */ + public native boolean getPixelSnapH(); /* + return IM_FONT_CONFIG->PixelSnapH; + */ + + /** + * Align every glyph to pixel boundary. Useful e.g. if you are merging a non-pixel aligned font with the default font. + * If enabled, you can set OversampleH/V to 1. + */ + public native void setPixelSnapH(boolean isPixelSnapH); /* + IM_FONT_CONFIG->PixelSnapH = isPixelSnapH; + */ + + /** + * Extra spacing (in pixels) between glyphs. Only X axis is supported for now. + */ + public native void getGlyphExtraSpacing(ImVec2 dstImVec2); /* + Jni::ImVec2Cpy(env, &IM_FONT_CONFIG->GlyphExtraSpacing, dstImVec2); + */ + + /** + * Extra spacing (in pixels) between glyphs. Only X axis is supported for now. + */ + public native void setGlyphExtraSpacing(float x, float y); /* + IM_FONT_CONFIG->GlyphExtraSpacing.x = x; + IM_FONT_CONFIG->GlyphExtraSpacing.y = y; + */ + + /** + * Offset all glyphs from this font input. + */ + public native void getGlyphOffset(ImVec2 dstImVec2); /* + Jni::ImVec2Cpy(env, &IM_FONT_CONFIG->GlyphOffset, dstImVec2); + */ + + /** + * Offset all glyphs from this font input. + */ + public native void setGlyphOffset(float x, float y); /* + IM_FONT_CONFIG->GlyphOffset.x = x; + IM_FONT_CONFIG->GlyphOffset.y = y; + */ + + /** + * Pointer to a user-provided list of Unicode range (2 value per range, values are inclusive, zero-terminated list). + * THE ARRAY DATA NEEDS TO PERSIST AS LONG AS THE FONT IS ALIVE. + */ + public short[] getGlyphRanges() { + return glyphRanges; + } + + /** + * Pointer to a user-provided list of Unicode range (2 value per range, values are inclusive, zero-terminated list). + * THE ARRAY DATA NEEDS TO PERSIST AS LONG AS THE FONT IS ALIVE. + */ + public void setGlyphRanges(final short[] glyphRanges) { + this.glyphRanges = glyphRanges; + nSetGlyphRanges(glyphRanges); + } + + private native void nSetGlyphRanges(short[] glyphRanges); /* + IM_FONT_CONFIG->GlyphRanges = glyphRanges != NULL ? (ImWchar*)&glyphRanges[0] : NULL; + */ + + /** + * Minimum AdvanceX for glyphs, set Min to align font icons, set both Min/Max to enforce mono-space font + */ + public native float getGlyphMinAdvanceX(); /* + return IM_FONT_CONFIG->GlyphMinAdvanceX; + */ + + /** + * Minimum AdvanceX for glyphs, set Min to align font icons, set both Min/Max to enforce mono-space font + */ + public native void setGlyphMinAdvanceX(float glyphMinAdvanceX); /* + IM_FONT_CONFIG->GlyphMinAdvanceX = glyphMinAdvanceX; + */ + + /** + * Maximum AdvanceX for glyphs + */ + public native float getGlyphMaxAdvanceX(); /* + return IM_FONT_CONFIG->GlyphMaxAdvanceX; + */ + + /** + * Maximum AdvanceX for glyphs + */ + public native void setGlyphMaxAdvanceX(float glyphMaxAdvanceX); /* + IM_FONT_CONFIG->GlyphMaxAdvanceX = glyphMaxAdvanceX; + */ + + /** + * Merge into previous ImFont, so you can combine multiple inputs font into one ImFont (e.g. ASCII font + icons + Japanese glyphs). You may want to use GlyphOffset.y when merge font of different heights. + */ + public native boolean getMergeMode(); /* + return IM_FONT_CONFIG->MergeMode; + */ + + /** + * Merge into previous ImFont, so you can combine multiple inputs font into one ImFont (e.g. ASCII font + icons + Japanese glyphs). You may want to use GlyphOffset.y when merge font of different heights. + */ + public native void setMergeMode(boolean mergeMode); /* + IM_FONT_CONFIG->MergeMode = mergeMode; + */ + + /** + * Settings for custom font rasterizer (e.g. ImGuiFreeType). Leave as zero if you aren't using one. + */ + public native int getRasterizerFlags(); /* + return IM_FONT_CONFIG->RasterizerFlags; + */ + + /** + * Settings for custom font rasterizer (e.g. ImGuiFreeType). Leave as zero if you aren't using one. + */ + public native void setRasterizerFlags(int rasterizerFlags); /* + IM_FONT_CONFIG->RasterizerFlags = (unsigned int)rasterizerFlags; + */ + + /** + * Brighten (>1.0f) or darken (<1.0f) font output. Brightening small fonts may be a good workaround to make them more readable. + */ + public native float getRasterizerMultiply(); /* + return IM_FONT_CONFIG->RasterizerMultiply; + */ + + /** + * Brighten (>1.0f) or darken (<1.0f) font output. Brightening small fonts may be a good workaround to make them more readable. + */ + public native void setRasterizerMultiply(float rasterizerMultiply); /* + IM_FONT_CONFIG->RasterizerMultiply = rasterizerMultiply; + */ + + /** + * Explicitly specify unicode codepoint of ellipsis character. When fonts are being merged first specified ellipsis will be used. + */ + public native short getEllipsisChar(); /* + return (short)IM_FONT_CONFIG->EllipsisChar; + */ + + /** + * Explicitly specify unicode codepoint of ellipsis character. When fonts are being merged first specified ellipsis will be used. + */ + public native void setEllipsisChar(short ellipsisChar); /* + IM_FONT_CONFIG->EllipsisChar = (ImWchar)ellipsisChar; + */ +} diff --git a/imgui-binding/src/main/java/imgui/ImGui.java b/imgui-binding/src/main/java/imgui/ImGui.java index 276ab6d..574e696 100644 --- a/imgui-binding/src/main/java/imgui/ImGui.java +++ b/imgui-binding/src/main/java/imgui/ImGui.java @@ -17,9 +17,9 @@ public final class ImGui { private static final String LIB_NAME_DEFAULT = System.getProperty("os.arch").contains("64") ? "imgui-java64" : "imgui-java"; private static final String LIB_TMP_DIR_PREFIX = "imgui-java-bin_" + System.getProperty("user.name", "user"); - private static final ImDrawData DRAW_DATA = new ImDrawData(100_000, 100_000, 1000); - private static final ImGuiIO IMGUI_IO = new ImGuiIO(); - private static final ImGuiStyle IMGUI_STYLE = new ImGuiStyle(); + private static final ImDrawData DRAW_DATA; + private static final ImGuiIO IMGUI_IO; + private static final ImGuiStyle IMGUI_STYLE; private static final ImDrawList IM_DRAW_LIST_WINDOW = new ImDrawList(ImDrawList.TYPE_WINDOW); private static final ImDrawList IM_DRAW_LIST_BACKGROUND = new ImDrawList(ImDrawList.TYPE_BACKGROUND); @@ -40,9 +40,15 @@ public final class ImGui { System.loadLibrary(libName); } + DRAW_DATA = new ImDrawData(100_000, 100_000, 1000); + IMGUI_IO = new ImGuiIO(); + IMGUI_STYLE = new ImGuiStyle(); + nInitJni(); ImDrawList.nInit(); ImDrawData.nInit(); + ImFontAtlas.nInit(); + ImFontConfig.nInit(); nInitInputTextData(); } @@ -81,6 +87,14 @@ public final class ImGui { } } + /** + * For internal usage. + * Method is used to initiate static instantiation (loading of the native libraries etc.). + * Otherwise native libraries will be loaded on demand and natively mapped objects won't work. + */ + static void touch() { + } + private ImGui() { } @@ -854,6 +868,7 @@ public final class ImGui { /** * Retrieve given color with style alpha applied + *

* BINDING NOTICE: Since {@link #getColorU32(int)} has the same signature, this specific method has an 'i' suffix. */ public static native int getColorU32i(int col); /* @@ -1196,6 +1211,7 @@ public final class ImGui { /** * Formatted text + *

* BINDING NOTICE: Since all text formatting could be done on Java side, this call is equal to {@link ImGui#textUnformatted(String)}. */ public static native void text(String text); /* diff --git a/imgui-binding/src/main/java/imgui/ImGuiIO.java b/imgui-binding/src/main/java/imgui/ImGuiIO.java index a4746fa..3935a3e 100644 --- a/imgui-binding/src/main/java/imgui/ImGuiIO.java +++ b/imgui-binding/src/main/java/imgui/ImGuiIO.java @@ -8,6 +8,8 @@ import imgui.callbacks.ImStrSupplier; * Access via ImGui::GetIO(). Read 'Programmer guide' section in .cpp file for general usage. */ public final class ImGuiIO { + private ImFontAtlas imFontAtlas; + ImGuiIO() { } @@ -17,6 +19,10 @@ public final class ImGuiIO { #include "jni_callbacks.h" */ + private native long nGetFontsPtr(); /* + return (long)ImGui::GetIO().Fonts; + */ + //------------------------------------------------------------------ // Configuration (fill once) //------------------------------------------------------------------ @@ -152,12 +158,32 @@ public final class ImGuiIO { ImGui::GetIO().KeyRepeatRate = keyRepeatRate; */ - // TODO fonts configuration + /** + * Font atlas: load, rasterize and pack one or more fonts into a single texture. + */ + public ImFontAtlas getFonts() { + // on demand instantiation + // will throw native exception if Dear ImGui context isn't created (like in the original library) + if (imFontAtlas == null) { + imFontAtlas = new ImFontAtlas(nGetFontsPtr()); + } + return imFontAtlas; + } - // BINDING NOTICE: this is a stub to pass important for ImGui info - public native void setFontsTexID(int id); /* - ImGui::GetIO().Fonts->TexID = (ImTextureID)id; - */ + /** + * Font atlas: load, rasterize and pack one or more fonts into a single texture. + *

+ * BINDING NOTICE: You should manually destroy previously used ImFontAtlas: + *

+     *     io.getFonts().destroy();
+     *     io.setFonts(newImFontAtlas);
+     * 
+ */ + public void setFonts(final ImFontAtlas imFontAtlas) { + this.imFontAtlas = imFontAtlas; + } + + // TODO fonts configuration // Miscellaneous options @@ -626,8 +652,7 @@ public final class ImGuiIO { * Queue new character input. */ public native void addInputCharacter(int c); /* - if (c > 0 && c < 0x10000) - ImGui::GetIO().AddInputCharacter((unsigned short)c); + ImGui::GetIO().AddInputCharacter((unsigned int)c); */ /** diff --git a/imgui-binding/src/main/java/imgui/TexDataRGBA32.java b/imgui-binding/src/main/java/imgui/TexDataRGBA32.java deleted file mode 100644 index 1ac57a4..0000000 --- a/imgui-binding/src/main/java/imgui/TexDataRGBA32.java +++ /dev/null @@ -1,48 +0,0 @@ -package imgui; - -import java.nio.Buffer; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -public final class TexDataRGBA32 { - public int width; - public int height; - - public ByteBuffer pixelBuffer; - - private TexDataRGBA32() { - final int pixelMax = 131072; - pixelBuffer = ByteBuffer.allocateDirect(pixelMax).order(ByteOrder.nativeOrder()); - } - - public static TexDataRGBA32 create() { - final TexDataRGBA32 data = new TexDataRGBA32(); - data.nFillData(data.pixelBuffer); - return data; - } - - /*JNI - #include - */ - - private native void nFillData(Buffer pixelBuf); /* - jclass jTexDataClass = env->GetObjectClass(object); - - if(jTexDataClass == NULL) - return; - - jfieldID widthID = env->GetFieldID(jTexDataClass, "width", "I"); - jfieldID heightID = env->GetFieldID(jTexDataClass, "height", "I"); - - unsigned char* pixels; - int width, height; - - ImGuiIO& io = ImGui::GetIO(); - io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); - - env->SetIntField(object, widthID, width); - env->SetIntField(object, heightID, height); - - memcpy(pixelBuf, pixels, width * height * 4); - */ -} diff --git a/imgui-lwjgl3/src/main/java/imgui/gl3/ImGuiImplGl3.java b/imgui-lwjgl3/src/main/java/imgui/gl3/ImGuiImplGl3.java index 71434a8..eeed6f1 100644 --- a/imgui-lwjgl3/src/main/java/imgui/gl3/ImGuiImplGl3.java +++ b/imgui-lwjgl3/src/main/java/imgui/gl3/ImGuiImplGl3.java @@ -1,14 +1,16 @@ package imgui.gl3; import imgui.ImDrawData; +import imgui.ImFontAtlas; import imgui.ImGui; -import imgui.TexDataRGBA32; +import imgui.ImInt; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.UncheckedIOException; +import java.nio.ByteBuffer; import java.util.Objects; import static org.lwjgl.opengl.GL30.*; @@ -191,18 +193,21 @@ public final class ImGuiImplGl3 { } private void prepareFont() { - final TexDataRGBA32 texData = TexDataRGBA32.create(); - gFontTexture = glGenTextures(); + final ImFontAtlas fontAtlas = ImGui.getIO().getFonts(); + final ImInt width = new ImInt(); + final ImInt height = new ImInt(); + final ByteBuffer buffer = fontAtlas.getTexDataAsRGBA32(width, height); + glBindTexture(GL_TEXTURE_2D, gFontTexture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texData.width, texData.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData.pixelBuffer); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width.get(), height.get(), 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer); - ImGui.getIO().setFontsTexID(gFontTexture); + fontAtlas.setTexID(gFontTexture); } private void backupGlState() { diff --git a/imgui-lwjgl3/src/test/java/ImGuiGlfwExample.java b/imgui-lwjgl3/src/test/java/ImGuiGlfwExample.java index 5cd85ff..d641ec4 100644 --- a/imgui-lwjgl3/src/test/java/ImGuiGlfwExample.java +++ b/imgui-lwjgl3/src/test/java/ImGuiGlfwExample.java @@ -122,7 +122,7 @@ public final class ImGuiGlfwExample { // Here we will initialize ImGui stuff. private void initImGui() { // IMPORTANT!! - // This line is critical for ImGui to work. + // This line is critical for Dear ImGui to work. ImGui.createContext(); // ImGui provides three different color schemas for styling. We will use the classic one here. @@ -230,7 +230,10 @@ public final class ImGuiGlfwExample { } }); - // Initialize renderer itself + // IMPORTANT!!! + // Method initializes renderer itself. + // This method SHOULD be called after you've initialized your ImGui configuration (fonts and so on). + // ImGui context should be created as well. imGuiGl3.init(); }