From 9f018ff45fd233752d947dd2f142e8d8c4a5ffbc Mon Sep 17 00:00:00 2001 From: SpaiR Date: Tue, 11 Feb 2020 00:53:28 +0300 Subject: [PATCH] Add an example drawing an image to the window draw list --- .../src/test/java/ImGuiGlfwExample.java | 57 ++++++++++++++++-- .../src/test/resources/Duke_waving.png | Bin 0 -> 11674 bytes 2 files changed, 53 insertions(+), 4 deletions(-) create mode 100644 imgui-lwjgl3/src/test/resources/Duke_waving.png diff --git a/imgui-lwjgl3/src/test/java/ImGuiGlfwExample.java b/imgui-lwjgl3/src/test/java/ImGuiGlfwExample.java index 03ef41d..061a33d 100644 --- a/imgui-lwjgl3/src/test/java/ImGuiGlfwExample.java +++ b/imgui-lwjgl3/src/test/java/ImGuiGlfwExample.java @@ -4,6 +4,7 @@ import imgui.ImFontConfig; import imgui.ImGui; import imgui.ImGuiIO; import imgui.ImString; +import imgui.ImVec2; import imgui.callbacks.ImStrConsumer; import imgui.callbacks.ImStrSupplier; import imgui.enums.ImGuiBackendFlags; @@ -14,15 +15,20 @@ import imgui.enums.ImGuiInputTextFlags; import imgui.enums.ImGuiKey; import imgui.enums.ImGuiMouseCursor; import imgui.gl3.ImGuiImplGl3; +import org.lwjgl.BufferUtils; import org.lwjgl.glfw.GLFWErrorCallback; import org.lwjgl.glfw.GLFWVidMode; import org.lwjgl.opengl.GL; import org.lwjgl.system.MemoryStack; +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; +import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.UncheckedIOException; +import java.nio.ByteBuffer; import java.nio.IntBuffer; import java.util.Objects; @@ -63,8 +69,11 @@ public final class ImGuiGlfwExample { private int clickCount = 0; private final ImString resizableStr = new ImString(5); private final ImBool showDemoWindow = new ImBool(); + private int dukeTexture; + private ImVec2 windowSize = new ImVec2(); // Vector to store "Custom Window" size + private ImVec2 windowPos = new ImVec2(); // Vector to store "Custom Window" position - public void run() { + public void run() throws Exception { initGlfw(); initImGui(); loop(); @@ -271,7 +280,10 @@ public final class ImGuiGlfwExample { } // Main application loop - private void loop() { + private void loop() throws Exception { + // Load Duke image and convert it into OpenGL texture + dukeTexture = loadTexture(ImageIO.read(new File("imgui-lwjgl3/src/test/resources/Duke_waving.png"))); + double time = 0; // to track our frame delta value // Run the rendering loop until the user has attempted to close the window @@ -326,7 +338,14 @@ public final class ImGuiGlfwExample { ImGui.begin("Custom window"); // Start Custom window - // Simple text label + // Example of how to draw an image in the bottom-right corner of the window + ImGui.getWindowSize(windowSize); + ImGui.getWindowPos(windowPos); + float xPoint = windowPos.x + windowSize.x - 100; + float yPoint = windowPos.y + windowSize.y; + ImGui.getWindowDrawList().addImage(dukeTexture, xPoint, yPoint - 180, xPoint + 100, yPoint); + + // Simple checkbox to show demo window ImGui.checkbox("Show demo window", showDemoWindow); ImGui.separator(); @@ -430,7 +449,37 @@ public final class ImGuiGlfwExample { } } - public static void main(final String[] args) { + private int loadTexture(BufferedImage image) { + int[] pixels = new int[image.getWidth() * image.getHeight()]; + image.getRGB(0, 0, image.getWidth(), image.getHeight(), pixels, 0, image.getWidth()); + + ByteBuffer buffer = BufferUtils.createByteBuffer(image.getWidth() * image.getHeight() * 4); // 4 for RGBA, 3 for RGB + for (int y = 0; y < image.getHeight(); y++) { + for (int x = 0; x < image.getWidth(); x++) { + int pixel = pixels[y * image.getWidth() + x]; + buffer.put((byte) ((pixel >> 16) & 0xFF)); + buffer.put((byte) ((pixel >> 8) & 0xFF)); + buffer.put((byte) (pixel & 0xFF)); + buffer.put((byte) ((pixel >> 24) & 0xFF)); + } + } + buffer.flip(); + + int textureID = glGenTextures(); + glBindTexture(GL_TEXTURE_2D, textureID); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, image.getWidth(), image.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer); + + return textureID; + } + + public static void main(final String[] args) throws Exception { new ImGuiGlfwExample().run(); } } diff --git a/imgui-lwjgl3/src/test/resources/Duke_waving.png b/imgui-lwjgl3/src/test/resources/Duke_waving.png new file mode 100644 index 0000000000000000000000000000000000000000..5c396a184f9e95fd71094d56b38ea14580f84469 GIT binary patch literal 11674 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 literal 0 HcmV?d00001