[Example] Migrate example to the new module

This commit is contained in:
SpaiR committed 2021-01-24 22:20:37 +02:00
1 parent 46f74381aa
commit cf9e74b1d0
17 files changed
+489 -822

No files matched your search

+14 -1
View File
@@ -1,12 +1,25 @@
plugins {
id 'application'
id 'checkstyle'
}
repositories {
mavenCentral()
}
application {
mainClass = 'Main'
}
dependencies {
implementation project(':imgui-app')
}
task start(type: JavaExec, dependsOn: build) {
main = 'Main'
classpath = sourceSets.test.runtimeClasspath
jvmArgs = ["-Dimgui.library.path=${System.getProperty('libPath', '../bin')}"]
if (org.gradle.internal.os.OperatingSystem.current().isMacOsX()) {
jvmArgs += ['-XstartOnFirstThread', '-Djava.awt.headless=true']
}
}
@@ -0,0 +1,124 @@
import imgui.extension.nodeditor.NodeEditor;
import imgui.extension.nodeditor.NodeEditorConfig;
import imgui.extension.nodeditor.NodeEditorContext;
import imgui.extension.nodeditor.flag.NodeEditorPinKind;
import imgui.flag.ImGuiCond;
import imgui.internal.ImGui;
import imgui.type.ImBoolean;
import imgui.type.ImLong;
import java.awt.Desktop;
import java.net.URI;
public class ExampleImGuiNodeEditor {
private static final NodeEditorContext CONTEXT;
private static final String URL = "https://github.com/thedmd/imgui-node-editor/tree/687a72f940";
static {
NodeEditorConfig config = new NodeEditorConfig();
config.setSettingsFile(null);
CONTEXT = new NodeEditorContext(config);
}
public static void show(final ImBoolean showImNodeEditorWindow, final Graph graph) {
ImGui.setNextWindowSize(500, 400, ImGuiCond.Once);
ImGui.setNextWindowPos(ImGui.getMainViewport().getPosX() + 100, ImGui.getMainViewport().getPosY() + 200, ImGuiCond.Once);
if (ImGui.begin("imgui-node-editor Demo", showImNodeEditorWindow)) {
ImGui.text("This a demo graph editor for imgui-node-editor");
ImGui.alignTextToFramePadding();
ImGui.text("Repo:");
ImGui.sameLine();
if (ImGui.button(URL)) {
try {
Desktop.getDesktop().browse(new URI(URL));
} catch (Exception e) {
e.printStackTrace();
}
}
if (ImGui.button("Navigate to content")) {
NodeEditor.navigateToContent(1);
}
NodeEditor.setCurrentEditor(CONTEXT);
NodeEditor.begin("Node Editor");
for (Graph.GraphNode node : graph.nodes.values()) {
NodeEditor.beginNode(node.nodeId);
ImGui.text(node.getName());
NodeEditor.beginPin(node.getInputPinId(), NodeEditorPinKind.Input);
ImGui.text("-> In");
NodeEditor.endPin();
ImGui.sameLine();
NodeEditor.beginPin(node.getOutputPinId(), NodeEditorPinKind.Output);
ImGui.text("Out ->");
NodeEditor.endPin();
NodeEditor.endNode();
}
if (NodeEditor.beginCreate()) {
final ImLong a = new ImLong();
final ImLong b = new ImLong();
if (NodeEditor.queryNewLink(a, b)) {
final Graph.GraphNode source = graph.findByOutput(a.get());
final Graph.GraphNode target = graph.findByInput(b.get());
if (source != null && target != null && source.outputNodeId != target.nodeId && NodeEditor.acceptNewItem()) {
source.outputNodeId = target.nodeId;
}
}
}
NodeEditor.endCreate();
int uniqueLinkId = 1;
for (Graph.GraphNode node : graph.nodes.values()) {
if (graph.nodes.containsKey(node.outputNodeId)) {
NodeEditor.link(uniqueLinkId++, node.getOutputPinId(), graph.nodes.get(node.outputNodeId).getInputPinId());
}
}
NodeEditor.suspend();
final long nodeWithContextMenu = NodeEditor.getNodeWithContextMenu();
if (nodeWithContextMenu != -1) {
ImGui.openPopup("node_context");
ImGui.getStateStorage().setInt(ImGui.getID("delete_node_id"), (int) nodeWithContextMenu);
}
if (ImGui.isPopupOpen("node_context")) {
final int targetNode = ImGui.getStateStorage().getInt(ImGui.getID("delete_node_id"));
if (ImGui.beginPopup("node_context")) {
if (ImGui.button("Delete " + graph.nodes.get(targetNode).getName())) {
graph.nodes.remove(targetNode);
ImGui.closeCurrentPopup();
}
ImGui.endPopup();
}
}
if (NodeEditor.showBackgroundContextMenu()) {
ImGui.openPopup("node_editor_context");
}
if (ImGui.beginPopup("node_editor_context")) {
if (ImGui.button("Create New Node")) {
final Graph.GraphNode node = graph.createGraphNode();
final float canvasX = NodeEditor.toCanvasX(ImGui.getMousePosX());
final float canvasY = NodeEditor.toCanvasY(ImGui.getMousePosY());
NodeEditor.setNodePosition(node.nodeId, canvasX, canvasY);
ImGui.closeCurrentPopup();
}
ImGui.endPopup();
}
NodeEditor.resume();
NodeEditor.end();
}
ImGui.end();
}
}
+111
View File
@@ -0,0 +1,111 @@
import imgui.extension.imnodes.ImNodes;
import imgui.extension.imnodes.ImNodesContext;
import imgui.extension.imnodes.flag.ImNodesPinShape;
import imgui.flag.ImGuiCond;
import imgui.flag.ImGuiMouseButton;
import imgui.internal.ImGui;
import imgui.type.ImBoolean;
import imgui.type.ImInt;
import java.awt.Desktop;
import java.net.URI;
public class ExampleImNodes {
private static final ImNodesContext CONTEXT = new ImNodesContext();
private static final String URL = "https://github.com/Nelarius/imnodes/tree/5959729410";
private static final ImInt LINK_A = new ImInt();
private static final ImInt LINK_B = new ImInt();
public static void show(final ImBoolean showImNodesWindow, final Graph graph) {
ImGui.setNextWindowSize(500, 400, ImGuiCond.Once);
ImGui.setNextWindowPos(ImGui.getMainViewport().getPosX() + 100, ImGui.getMainViewport().getPosY() + 100, ImGuiCond.Once);
if (ImGui.begin("ImNodes Demo", showImNodesWindow)) {
ImGui.text("This a demo graph editor for ImNodes");
ImGui.alignTextToFramePadding();
ImGui.text("Repo:");
ImGui.sameLine();
if (ImGui.button(URL)) {
try {
Desktop.getDesktop().browse(new URI(URL));
} catch (Exception e) {
e.printStackTrace();
}
}
ImNodes.editorContextSet(CONTEXT);
ImNodes.beginNodeEditor();
for (Graph.GraphNode node : graph.nodes.values()) {
ImNodes.beginNode(node.nodeId);
ImNodes.beginNodeTitleBar();
ImGui.text(node.getName());
ImNodes.endNodeTitleBar();
ImNodes.beginInputAttribute(node.getInputPinId(), ImNodesPinShape.CircleFilled);
ImGui.text("In");
ImNodes.endInputAttribute();
ImGui.sameLine();
ImNodes.beginOutputAttribute(node.getOutputPinId());
ImGui.text("Out");
ImNodes.endOutputAttribute();
ImNodes.endNode();
}
int uniqueLinkId = 1;
for (Graph.GraphNode node : graph.nodes.values()) {
if (graph.nodes.containsKey(node.outputNodeId)) {
ImNodes.link(uniqueLinkId++, node.getOutputPinId(), graph.nodes.get(node.outputNodeId).getInputPinId());
}
}
final boolean isEditorHovered = ImNodes.isEditorHovered();
ImNodes.endNodeEditor();
if (ImNodes.isLinkCreated(LINK_A, LINK_B)) {
final Graph.GraphNode source = graph.findByOutput(LINK_A.get());
final Graph.GraphNode target = graph.findByInput(LINK_B.get());
if (source != null && target != null && source.outputNodeId != target.nodeId) {
source.outputNodeId = target.nodeId;
}
}
if (ImGui.isMouseClicked(ImGuiMouseButton.Right)) {
final int hoveredNode = ImNodes.getHoveredNode();
if (hoveredNode != -1) {
ImGui.openPopup("node_context");
ImGui.getStateStorage().setInt(ImGui.getID("delete_node_id"), hoveredNode);
} else if (isEditorHovered) {
ImGui.openPopup("node_editor_context");
}
}
if (ImGui.isPopupOpen("node_context")) {
final int targetNode = ImGui.getStateStorage().getInt(ImGui.getID("delete_node_id"));
if (ImGui.beginPopup("node_context")) {
if (ImGui.button("Delete " + graph.nodes.get(targetNode).getName())) {
graph.nodes.remove(targetNode);
ImGui.closeCurrentPopup();
}
ImGui.endPopup();
}
}
if (ImGui.beginPopup("node_editor_context")) {
if (ImGui.button("Create New Node")) {
final Graph.GraphNode node = graph.createGraphNode();
ImNodes.setNodeScreenSpacePos(node.nodeId, ImGui.getMousePosX(), ImGui.getMousePosY());
ImGui.closeCurrentPopup();
}
ImGui.endPopup();
}
}
ImGui.end();
}
}
+30
View File
@@ -0,0 +1,30 @@
import imgui.ImGui;
import imgui.app.Application;
import imgui.type.ImBoolean;
public class Extra {
private static final ImBoolean SHOW_DEMO_WINDOW = new ImBoolean(false);
private static final ImBoolean SHOW_IMNODES_DEMO_WINDOW = new ImBoolean(false);
private static final ImBoolean SHOW_IMGUI_NODE_EDITOR_DEMO_WINDOW = new ImBoolean(false);
private static final Graph GRAPH = new Graph();
public static void show(final Application app) {
ImGui.colorEdit3("Background Color", app.getColorBg().getData());
ImGui.checkbox("Show Demo Window", SHOW_DEMO_WINDOW);
ImGui.checkbox("Show ImNodes Demo Window", SHOW_IMNODES_DEMO_WINDOW);
ImGui.checkbox("Show imgui-node-editor Demo Window", SHOW_IMGUI_NODE_EDITOR_DEMO_WINDOW);
if (SHOW_DEMO_WINDOW.get()) {
ImGui.showDemoWindow(SHOW_DEMO_WINDOW);
}
if (SHOW_IMNODES_DEMO_WINDOW.get()) {
ExampleImNodes.show(SHOW_IMNODES_DEMO_WINDOW, GRAPH);
}
if (SHOW_IMGUI_NODE_EDITOR_DEMO_WINDOW.get()) {
ExampleImGuiNodeEditor.show(SHOW_IMGUI_NODE_EDITOR_DEMO_WINDOW, GRAPH);
}
}
}
+65
View File
@@ -0,0 +1,65 @@
import java.util.HashMap;
import java.util.Map;
public final class Graph {
public int nextNodeId = 1;
public int nextPinId = 100;
public final Map<Integer, GraphNode> nodes = new HashMap<>();
public Graph() {
final GraphNode first = createGraphNode();
final GraphNode second = createGraphNode();
first.outputNodeId = second.nodeId;
}
public GraphNode createGraphNode() {
final GraphNode node = new GraphNode(nextNodeId++, nextPinId++, nextPinId++);
this.nodes.put(node.nodeId, node);
return node;
}
public GraphNode findByInput(final long inputPinId) {
for (GraphNode node : nodes.values()) {
if (node.getInputPinId() == inputPinId) {
return node;
}
}
return null;
}
public GraphNode findByOutput(final long outputPinId) {
for (GraphNode node : nodes.values()) {
if (node.getOutputPinId() == outputPinId) {
return node;
}
}
return null;
}
public static final class GraphNode {
public final int nodeId;
public final int inputPinId;
public final int outputPinId;
public int outputNodeId = -1;
public GraphNode(final int nodeId, final int inputPinId, final int outputPintId) {
this.nodeId = nodeId;
this.inputPinId = inputPinId;
this.outputPinId = outputPintId;
}
public int getInputPinId() {
return inputPinId;
}
public int getOutputPinId() {
return outputPinId;
}
public String getName() {
return "Node " + (char) (64 + nodeId);
}
}
}
+27 -2
View File
@@ -2,9 +2,16 @@ import imgui.ImGui;
import imgui.ImGuiIO;
import imgui.app.Application;
import imgui.app.Configuration;
import imgui.extension.imnodes.ImNodes;
import imgui.flag.ImGuiConfigFlags;
import imgui.flag.ImGuiInputTextFlags;
import imgui.type.ImString;
public class Main extends Application {
private final ImString str = new ImString(5);
private final float[] flt = new float[1];
private int count = 0;
public final class Main extends Application {
@Override
protected void configure(final Configuration config) {
config.setTitle("Example Application");
@@ -20,11 +27,29 @@ public final class Main extends Application {
io.addConfigFlags(ImGuiConfigFlags.DockingEnable); // Enable Docking
io.addConfigFlags(ImGuiConfigFlags.ViewportsEnable); // Enable Multi-Viewport / Platform Windows
io.setConfigViewportsNoTaskBarIcon(true);
ImNodes.initialize();
}
@Override
protected void disposeImGui() {
ImNodes.shutdown();
super.disposeImGui();
}
@Override
public void process() {
ImGui.text("Hello, World");
ImGui.text("Hello, World!");
if (ImGui.button("Save")) {
count++;
}
ImGui.sameLine();
ImGui.text(String.valueOf(count));
ImGui.inputText("string", str, ImGuiInputTextFlags.CallbackResize);
ImGui.sliderFloat("float", flt, 0, 1);
ImGui.separator();
ImGui.text("Extra");
Extra.show(this);
}
public static void main(final String[] args) {
@@ -12,7 +12,11 @@ package imgui.app;
* <li>{@link #configure(Configuration)} It's called before window creation, so only basic application setups are expected.</li>
* <li>{@link #initWindow(Configuration)} Method creates application window.</li>
* <li>{@link #initImGui(Configuration)} Method initializes Dear ImGui context. Could be used to do Dear ImGui setup as well.</li>
* <li>{@link #preRun()} Method called once, before application loop.</li>
* <li>{@link #preProcess()} Method called every frame, before {@link #process()}.</li>
* <li>{@link #process()} Method is meant to be overridden with user application logic.</li>
* <li>{@link #postProcess()} Method called every frame, after {@link #process()}.</li>
* <li>{@link #postRun()} Method called once, after application loop.</li>
* <li>{@link #disposeImGui()} Destroys Dear ImGui context.</li>
* <li>{@link #disposeWindow()} Destroys application window.</li>
* </ol>
@@ -27,17 +31,11 @@ package imgui.app;
* <pre>{@code
* import imgui.ImGui;
* import imgui.app.Application;
* import imgui.app.Configuration;
*
* public class Main extends Application {
* @Override
* protected void configure(final Configuration config) {
* config.setTitle("Example Application");
* }
*
* @Override
* public void process() {
* ImGui.text("Hello, World");
* ImGui.text("Hello, World!");
* }
*
* public static void main(final String[] args) {
@@ -55,13 +53,25 @@ package imgui.app;
*/
public abstract class Application extends Window {
/**
* Method is called before window creation. Could be used to provide basic window information, like title name etc.
* Method called before window creation. Could be used to provide basic window information, like title name etc.
*
* @param config configuration object with basic window information
*/
protected void configure(final Configuration config) {
}
/**
* Method called once, before application run loop.
*/
protected void preRun() {
}
/**
* Method called once, after application run loop.
*/
protected void postRun() {
}
/**
* Entry point of any ImGui application. Use it to start the application loop.
*
@@ -69,7 +79,9 @@ public abstract class Application extends Window {
*/
public static void launch(final Application app) {
initialize(app);
app.preRun();
app.run();
app.postRun();
app.dispose();
}
@@ -0,0 +1,62 @@
package imgui.app;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* Object for color data.
*/
@Data
@NoArgsConstructor
public class Color implements Cloneable {
private final float[] data = new float[4];
public Color(final float[] color) {
set(color);
}
public Color(final float red, final float green, final float blue, final float alpha) {
data[0] = red;
data[1] = green;
data[2] = blue;
data[3] = alpha;
}
public final void set(final float red, final float green, final float blue, final float alpha) {
data[0] = red;
data[1] = green;
data[2] = blue;
data[3] = alpha;
}
public final void set(final float[] color) {
System.arraycopy(color, 0, data, 0, 4);
}
public final float getRed() {
return data[0];
}
public final float getGreen() {
return data[1];
}
public final float getBlue() {
return data[2];
}
public final float getAlpha() {
return data[3];
}
/**
* Method to clone Color instance.
*
* @return cloned Color instance
*/
@Override
@SuppressWarnings("MethodDoesntCallSuperMethod")
public Color clone() {
return new Color(data);
}
}
@@ -6,7 +6,7 @@ import lombok.Data;
* Data class to provide basic information about the window. Like, the title name etc.
*/
@Data
public final class Configuration {
public class Configuration {
/**
* Application title.
*/
+32 -7
View File
@@ -13,7 +13,6 @@ import org.lwjgl.opengl.GL32;
import org.lwjgl.system.MemoryStack;
import org.lwjgl.system.MemoryUtil;
import java.awt.Color;
import java.nio.IntBuffer;
import java.util.Objects;
@@ -29,13 +28,14 @@ public abstract class Window {
private String glslVersion = null;
/**
* Pointer to native GLFW window.
* Pointer to the native GLFW window.
*/
protected long handle;
/**
* Background color of the window.
*/
protected Color colorBg = Color.GRAY;
protected final Color colorBg = new Color(.5f, .5f, .5f, 1);
/**
* Method to initialize application.
@@ -126,13 +126,27 @@ public abstract class Window {
ImGui.createContext();
}
/**
* Method called every frame, before calling {@link #process()} method.
*/
protected void preProcess() {
}
/**
* Method called every frame, after calling {@link #process()} method.
*/
protected void postProcess() {
}
/**
* Main application loop.
*/
protected final void run() {
while (!GLFW.glfwWindowShouldClose(handle)) {
startFrame();
preProcess();
process();
postProcess();
endFrame();
}
}
@@ -143,10 +157,7 @@ public abstract class Window {
public abstract void process();
private void startFrame() {
if (colorBg != null) {
GL32.glClearColor(colorBg.getRed() / 255f, colorBg.getGreen() / 255f, colorBg.getBlue() / 255f, colorBg.getAlpha() / 255f);
}
GL32.glClearColor(colorBg.getRed(), colorBg.getGreen(), colorBg.getBlue(), colorBg.getAlpha());
GL32.glClear(GL32.GL_COLOR_BUFFER_BIT | GL32.GL_DEPTH_BUFFER_BIT);
imGuiGlfw.newFrame();
ImGui.newFrame();
@@ -183,4 +194,18 @@ public abstract class Window {
GLFW.glfwTerminate();
Objects.requireNonNull(GLFW.glfwSetErrorCallback(null)).free();
}
/**
* @return pointer to the native GLFW window
*/
public final long getHandle() {
return handle;
}
/**
* @return {@link Color} instance, which represents background color for the window
*/
public final Color getColorBg() {
return colorBg;
}
}
+3 -3
View File
@@ -45,10 +45,10 @@ public class ImGui {
final String extractedLibAbsPath = tryLoadFromClasspath(fullLibName);
if (extractedLibAbsPath != null) {
System.load(extractedLibAbsPath);
} else if (libPath != null) {
if (libPath != null) {
System.load(Paths.get(libPath).resolve(fullLibName).toFile().getAbsolutePath());
} else if (extractedLibAbsPath != null) {
System.load(extractedLibAbsPath);
} else {
System.loadLibrary(libName);
}
-512
View File
@@ -1,512 +0,0 @@
import imgui.ImGuiViewport;
import imgui.flag.ImGuiColorEditFlags;
import imgui.flag.ImGuiCond;
import imgui.flag.ImGuiDir;
import imgui.flag.ImGuiInputTextFlags;
import imgui.flag.ImGuiStyleVar;
import imgui.flag.ImGuiWindowFlags;
import imgui.extension.imnodes.ImNodes;
import imgui.extension.imnodes.ImNodesContext;
import imgui.extension.imnodes.flag.ImNodesPinShape;
import imgui.extension.nodeditor.NodeEditor;
import imgui.internal.ImGui;
import imgui.internal.flag.ImGuiDockNodeFlags;
import imgui.extension.nodeditor.NodeEditorConfig;
import imgui.extension.nodeditor.NodeEditorContext;
import imgui.extension.nodeditor.flag.NodeEditorPinKind;
import imgui.type.ImBoolean;
import imgui.ImColor;
import imgui.type.ImInt;
import imgui.type.ImLong;
import imgui.type.ImString;
import org.lwjgl.BufferUtils;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;
import static org.lwjgl.opengl.GL32.GL_CLAMP_TO_EDGE;
import static org.lwjgl.opengl.GL32.GL_LINEAR;
import static org.lwjgl.opengl.GL32.GL_RGBA;
import static org.lwjgl.opengl.GL32.GL_RGBA8;
import static org.lwjgl.opengl.GL32.GL_TEXTURE_2D;
import static org.lwjgl.opengl.GL32.GL_TEXTURE_MAG_FILTER;
import static org.lwjgl.opengl.GL32.GL_TEXTURE_MIN_FILTER;
import static org.lwjgl.opengl.GL32.GL_TEXTURE_WRAP_S;
import static org.lwjgl.opengl.GL32.GL_TEXTURE_WRAP_T;
import static org.lwjgl.opengl.GL32.GL_UNSIGNED_BYTE;
import static org.lwjgl.opengl.GL32.glBindTexture;
import static org.lwjgl.opengl.GL32.glGenTextures;
import static org.lwjgl.opengl.GL32.glTexImage2D;
import static org.lwjgl.opengl.GL32.glTexParameteri;
@SuppressWarnings({"MagicNumber", "VisibilityModifier"})
final class ExampleUi {
private static final String IMGUI_DEMO_LINK = "https://raw.githubusercontent.com/ocornut/imgui/05bc204/imgui_demo.cpp";
private static final int COLOR_DODGERBLUE = ImColor.rgbToColor("#1E90FF");
private static final int COLOR_CORAL = ImColor.rgbToColor("#FF7F50");
private static final int COLOR_LIMEGREEN = ImColor.rgbToColor("#32CD32");
// Test data for payload
private String dropTargetText = "Drop Here";
// Resizable input example
private final ImString resizableStr = new ImString(5);
// Toggles
private final ImBoolean showBottomDockedWindow = new ImBoolean(true);
private final ImBoolean showDemoWindow = new ImBoolean();
private final ImBoolean showImNodesWindow = new ImBoolean(false);
private final ImBoolean showImNodeEditorWindow = new ImBoolean(false);
// Attach image example
private int dukeTexture = 0;
private boolean isBottomDockedWindowInit = false;
// To modify background color dynamically
final float[] backgroundColor = new float[]{0.5f, 0, 0};
// Context for imnodes example
private ImNodesContext imNodesContext;
// Context for imgui-node-editor example
private NodeEditorContext nodeEditorContext;
// Graph used both for imnodes and imgui-node-editor demo
private final Graph graph = new Graph();
void render() throws Exception {
if (imNodesContext == null) {
imNodesContext = new ImNodesContext();
}
if (nodeEditorContext == null) {
final NodeEditorConfig config = new NodeEditorConfig();
config.setSettingsFile(null);
nodeEditorContext = new NodeEditorContext(config);
}
final int dockspaceId = ImGui.getID("MyDockSpace");
showDockSpace(dockspaceId);
setupBottomDockedWindow(dockspaceId);
showBottomDockedWindow();
final ImGuiViewport mainViewport = ImGui.getMainViewport();
ImGui.setNextWindowSize(600, 300, ImGuiCond.Once);
ImGui.setNextWindowPos(mainViewport.getWorkPosX() + 10, mainViewport.getWorkPosY() + 10, ImGuiCond.Once);
ImGui.begin("Custom window"); // Start Custom window
showWindowImage();
showToggles();
ImGui.separator();
showDragNDrop();
showBackgroundPicker();
ImGui.separator();
showResizableInput();
ImGui.separator();
ImGui.newLine();
showDemoLink();
ImGui.end(); // End Custom window
if (showDemoWindow.get()) {
ImGui.showDemoWindow(showDemoWindow);
}
if (showImNodesWindow.get()) {
showImNodesWindow();
}
if (showImNodeEditorWindow.get()) {
showImNodeEditorWindow();
}
}
private void showDockSpace(final int dockspaceId) {
final ImGuiViewport mainViewport = ImGui.getMainViewport();
final int windowFlags = ImGuiWindowFlags.NoTitleBar | ImGuiWindowFlags.NoCollapse | ImGuiWindowFlags.NoResize
| ImGuiWindowFlags.NoMove | ImGuiWindowFlags.NoBringToFrontOnFocus | ImGuiWindowFlags.NoNavFocus | ImGuiWindowFlags.NoBackground;
ImGui.setNextWindowPos(mainViewport.getWorkPosX(), mainViewport.getWorkPosY());
ImGui.setNextWindowSize(mainViewport.getWorkSizeX(), mainViewport.getWorkSizeY());
ImGui.setNextWindowViewport(mainViewport.getID());
ImGui.pushStyleVar(ImGuiStyleVar.WindowRounding, 0);
ImGui.pushStyleVar(ImGuiStyleVar.WindowBorderSize, 0);
ImGui.pushStyleVar(ImGuiStyleVar.WindowPadding, 0, 0);
ImGui.begin("Dockspace Demo", windowFlags);
ImGui.popStyleVar(3);
ImGui.dockSpace(dockspaceId, 0, 0, ImGuiDockNodeFlags.PassthruCentralNode);
ImGui.end();
}
private void setupBottomDockedWindow(final int dockspaceId) {
if (!isBottomDockedWindowInit) {
ImGui.dockBuilderRemoveNode(dockspaceId);
ImGui.dockBuilderAddNode(dockspaceId, ImGuiDockNodeFlags.DockSpace);
final int dockIdBottom = ImGui.dockBuilderSplitNode(dockspaceId, ImGuiDir.Down, .25f, null, null);
ImGui.dockBuilderDockWindow("Bottom Docked Window", dockIdBottom);
ImGui.dockBuilderSetNodeSize(dockIdBottom, 150f, 150f);
ImGui.dockBuilderFinish(dockspaceId);
isBottomDockedWindowInit = true;
}
}
private void showBottomDockedWindow() {
if (showBottomDockedWindow.get()) {
ImGui.begin("Bottom Docked Window", showBottomDockedWindow, ImGuiWindowFlags.AlwaysAutoResize);
ImGui.text("An example of how to create docked windows.");
ImGui.end();
}
}
private void showWindowImage() throws IOException {
if (dukeTexture == 0) {
dukeTexture = loadTexture(ImageIO.read(new File("src/test/resources/Duke_waving.png")));
}
// Draw an image in the bottom-right corner of the window
final float xPoint = ImGui.getWindowPosX() + ImGui.getWindowSizeX() - 100;
final float yPoint = ImGui.getWindowPosY() + ImGui.getWindowSizeY();
ImGui.getWindowDrawList().addImage(dukeTexture, xPoint, yPoint - 180, xPoint + 100, yPoint);
}
private void showToggles() {
ImGui.checkbox("Show Demo Window", showDemoWindow);
ImGui.checkbox("Show Bottom Docked Window", showBottomDockedWindow);
ImGui.checkbox("Show demo for imnodes", showImNodesWindow);
ImGui.checkbox("Show demo for imgui-node-editor", showImNodeEditorWindow);
if (ImGui.button("Reset Bottom Dock Window")) {
isBottomDockedWindowInit = false;
}
}
private void showDragNDrop() {
ImGui.button("Drag me");
if (ImGui.beginDragDropSource()) {
ImGui.setDragDropPayloadObject("payload_type", "Test Payload");
ImGui.text("Drag started");
ImGui.endDragDropSource();
}
ImGui.sameLine();
ImGui.text(dropTargetText);
if (ImGui.beginDragDropTarget()) {
final Object payload = ImGui.acceptDragDropPayloadObject("payload_type");
if (payload != null) {
dropTargetText = (String) payload;
}
ImGui.endDragDropTarget();
}
}
private void showBackgroundPicker() {
ImGui.alignTextToFramePadding();
ImGui.text("Background color:");
ImGui.sameLine();
ImGui.colorEdit3("##click_counter_col", backgroundColor, ImGuiColorEditFlags.NoInputs | ImGuiColorEditFlags.NoDragDrop);
}
private void showResizableInput() {
ImGui.text("You can use text inputs with auto-resizable strings!");
ImGui.inputText("Resizable input", resizableStr, ImGuiInputTextFlags.CallbackResize);
ImGui.text("text len:");
ImGui.sameLine();
ImGui.textColored(COLOR_DODGERBLUE, Integer.toString(resizableStr.getLength()));
ImGui.sameLine();
ImGui.text("| buffer size:");
ImGui.sameLine();
ImGui.textColored(COLOR_CORAL, Integer.toString(resizableStr.getBufferSize()));
}
private void showDemoLink() {
ImGui.text("Consider to look the original ImGui demo: ");
ImGui.setNextItemWidth(500);
ImGui.textColored(COLOR_LIMEGREEN, IMGUI_DEMO_LINK);
ImGui.sameLine();
if (ImGui.button("Copy")) {
ImGui.setClipboardText(IMGUI_DEMO_LINK);
}
}
private void showImNodesWindow() {
ImGui.setNextWindowSize(400F, 400F, ImGuiCond.Appearing);
ImGui.begin("Demo imnodes", showImNodesWindow);
ImGui.text("This a demo graph editor for ImNodes");
ImNodes.editorContextSet(imNodesContext);
ImNodes.beginNodeEditor();
for (Graph.GraphNode node : graph.nodes.values()) {
ImNodes.beginNode(node.nodeId);
ImNodes.beginNodeTitleBar();
ImGui.text(node.getName());
ImNodes.endNodeTitleBar();
ImNodes.beginInputAttribute(node.getInputPinId(), ImNodesPinShape.CircleFilled);
ImGui.text("In");
ImNodes.endInputAttribute();
ImGui.sameLine();
ImNodes.beginOutputAttribute(node.getOutputPinId());
ImGui.text("Out");
ImNodes.endOutputAttribute();
ImNodes.endNode();
}
int uniqueLinkId = 1;
for (Graph.GraphNode node : graph.nodes.values()) {
if (graph.nodes.containsKey(node.outputNodeId)) {
ImNodes.link(uniqueLinkId++, node.getOutputPinId(), graph.nodes.get(node.outputNodeId).getInputPinId());
}
}
final boolean isEditorHovered = ImNodes.isEditorHovered();
ImNodes.endNodeEditor();
final ImInt a = new ImInt();
final ImInt b = new ImInt();
if (ImNodes.isLinkCreated(a, b)) {
final Graph.GraphNode source = graph.findByOutput(a.get());
final Graph.GraphNode target = graph.findByInput(b.get());
if (source != null && target != null && source.outputNodeId != target.nodeId) {
source.outputNodeId = target.nodeId;
}
}
if (ImGui.isMouseClicked(1)) {
final int hoveredNode = ImNodes.getHoveredNode();
if (hoveredNode != -1) {
ImGui.openPopup("node-context");
ImGui.getStateStorage().setInt(ImGui.getID("delete-node-id"), hoveredNode);
} else if (isEditorHovered) {
ImGui.openPopup("node-editor-context");
}
}
if (ImGui.isPopupOpen("node-context")) {
final int targetNode = ImGui.getStateStorage().getInt(ImGui.getID("delete-node-id"));
if (ImGui.beginPopup("node-context")) {
if (ImGui.button("Delete " + graph.nodes.get(targetNode).getName())) {
graph.nodes.remove(targetNode);
ImGui.closeCurrentPopup();
}
ImGui.endPopup();
}
}
if (ImGui.beginPopup("node-editor-context")) {
if (ImGui.button("Create new node")) {
final Graph.GraphNode node = graph.createGraphNode();
ImNodes.setNodeScreenSpacePos(node.nodeId, ImGui.getMousePosX(), ImGui.getMousePosY());
ImGui.closeCurrentPopup();
}
ImGui.endPopup();
}
ImGui.end();
}
private void showImNodeEditorWindow() {
ImGui.setNextWindowSize(400F, 400F, ImGuiCond.Appearing);
ImGui.begin("Demo imgui-node-editor", showImNodeEditorWindow);
ImGui.text("This a demo graph editor for imgui-node-editor");
if (ImGui.button("Navigate to content")) {
NodeEditor.navigateToContent(1F);
}
NodeEditor.setCurrentEditor(nodeEditorContext);
NodeEditor.begin("Node Editor");
for (Graph.GraphNode node : graph.nodes.values()) {
NodeEditor.beginNode(node.nodeId);
ImGui.text(node.getName());
NodeEditor.beginPin(node.getInputPinId(), NodeEditorPinKind.Input);
ImGui.text("-> In");
NodeEditor.endPin();
ImGui.sameLine();
NodeEditor.beginPin(node.getOutputPinId(), NodeEditorPinKind.Output);
ImGui.text("Out ->");
NodeEditor.endPin();
NodeEditor.endNode();
}
if (NodeEditor.beginCreate()) {
final ImLong a = new ImLong();
final ImLong b = new ImLong();
if (NodeEditor.queryNewLink(a, b)) {
final Graph.GraphNode source = graph.findByOutput(a.get());
final Graph.GraphNode target = graph.findByInput(b.get());
if (source != null && target != null && source.outputNodeId != target.nodeId && NodeEditor.acceptNewItem()) {
source.outputNodeId = target.nodeId;
}
}
}
NodeEditor.endCreate();
int uniqueLinkId = 1;
for (Graph.GraphNode node : graph.nodes.values()) {
if (graph.nodes.containsKey(node.outputNodeId)) {
NodeEditor.link(uniqueLinkId++, node.getOutputPinId(), graph.nodes.get(node.outputNodeId).getInputPinId());
}
}
NodeEditor.suspend();
final long nodeWithContextMenu = NodeEditor.getNodeWithContextMenu();
if (nodeWithContextMenu != -1) {
ImGui.openPopup("node-context");
ImGui.getStateStorage().setInt(ImGui.getID("delete-node-id"), (int) nodeWithContextMenu);
}
if (ImGui.isPopupOpen("node-context")) {
final int targetNode = ImGui.getStateStorage().getInt(ImGui.getID("delete-node-id"));
if (ImGui.beginPopup("node-context")) {
if (ImGui.button("Delete " + graph.nodes.get(targetNode).getName())) {
graph.nodes.remove(targetNode);
ImGui.closeCurrentPopup();
}
ImGui.endPopup();
}
}
if (NodeEditor.showBackgroundContextMenu()) {
ImGui.openPopup("node-editor-context");
}
if (ImGui.beginPopup("node-editor-context")) {
if (ImGui.button("Create new node")) {
final Graph.GraphNode node = graph.createGraphNode();
final float canvasX = NodeEditor.toCanvasX(ImGui.getMousePosX());
final float canvasY = NodeEditor.toCanvasY(ImGui.getMousePosY());
NodeEditor.setNodePosition(node.nodeId, canvasX, canvasY);
ImGui.closeCurrentPopup();
}
ImGui.endPopup();
}
NodeEditor.resume();
NodeEditor.end();
ImGui.end();
}
private int loadTexture(final BufferedImage image) {
final int[] pixels = new int[image.getWidth() * image.getHeight()];
image.getRGB(0, 0, image.getWidth(), image.getHeight(), pixels, 0, image.getWidth());
final 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++) {
final 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();
final 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;
}
// Simple graph struct for both of node editors demos
private static final class Graph {
private int nextNodeId = 1;
private int nextPinId = 100;
final Map<Integer, GraphNode> nodes = new HashMap<>();
private Graph() {
final GraphNode first = createGraphNode();
final GraphNode second = createGraphNode();
first.outputNodeId = second.nodeId;
}
public GraphNode createGraphNode() {
final GraphNode node = new GraphNode(nextNodeId++, nextPinId++, nextPinId++);
this.nodes.put(node.nodeId, node);
return node;
}
public GraphNode findByInput(final long inputPinId) {
for (GraphNode node : nodes.values()) {
if (node.getInputPinId() == inputPinId) {
return node;
}
}
return null;
}
public GraphNode findByOutput(final long outputPinId) {
for (GraphNode node : nodes.values()) {
if (node.getOutputPinId() == outputPinId) {
return node;
}
}
return null;
}
private static final class GraphNode {
private final int nodeId;
private final int inputPinId;
private final int outputPinId;
public int outputNodeId = -1;
private GraphNode(final int nodeId, final int inputPinId, final int outputPintId) {
this.nodeId = nodeId;
this.inputPinId = inputPinId;
this.outputPinId = outputPintId;
}
public int getInputPinId() {
return inputPinId;
}
public int getOutputPinId() {
return outputPinId;
}
public String getName() {
return "Node " + (char) (64 + nodeId);
}
}
}
}
@@ -1,288 +0,0 @@
import static org.lwjgl.glfw.Callbacks.glfwFreeCallbacks;
import static org.lwjgl.glfw.GLFW.GLFW_CONTEXT_VERSION_MAJOR;
import static org.lwjgl.glfw.GLFW.GLFW_CONTEXT_VERSION_MINOR;
import static org.lwjgl.glfw.GLFW.GLFW_FALSE;
import static org.lwjgl.glfw.GLFW.GLFW_OPENGL_CORE_PROFILE;
import static org.lwjgl.glfw.GLFW.GLFW_OPENGL_FORWARD_COMPAT;
import static org.lwjgl.glfw.GLFW.GLFW_OPENGL_PROFILE;
import static org.lwjgl.glfw.GLFW.GLFW_TRUE;
import static org.lwjgl.glfw.GLFW.GLFW_VISIBLE;
import static org.lwjgl.glfw.GLFW.glfwCreateWindow;
import static org.lwjgl.glfw.GLFW.glfwDefaultWindowHints;
import static org.lwjgl.glfw.GLFW.glfwDestroyWindow;
import static org.lwjgl.glfw.GLFW.glfwGetCurrentContext;
import static org.lwjgl.glfw.GLFW.glfwGetPrimaryMonitor;
import static org.lwjgl.glfw.GLFW.glfwGetVideoMode;
import static org.lwjgl.glfw.GLFW.glfwGetWindowSize;
import static org.lwjgl.glfw.GLFW.glfwInit;
import static org.lwjgl.glfw.GLFW.glfwMakeContextCurrent;
import static org.lwjgl.glfw.GLFW.glfwPollEvents;
import static org.lwjgl.glfw.GLFW.glfwSetErrorCallback;
import static org.lwjgl.glfw.GLFW.glfwSetWindowPos;
import static org.lwjgl.glfw.GLFW.glfwShowWindow;
import static org.lwjgl.glfw.GLFW.glfwSwapBuffers;
import static org.lwjgl.glfw.GLFW.glfwSwapInterval;
import static org.lwjgl.glfw.GLFW.glfwTerminate;
import static org.lwjgl.glfw.GLFW.glfwWindowHint;
import static org.lwjgl.glfw.GLFW.glfwWindowShouldClose;
import static org.lwjgl.opengl.GL32.GL_COLOR_BUFFER_BIT;
import static org.lwjgl.opengl.GL32.GL_TRUE;
import static org.lwjgl.opengl.GL32.glClear;
import static org.lwjgl.opengl.GL32.glClearColor;
import static org.lwjgl.system.MemoryStack.stackPush;
import static org.lwjgl.system.MemoryUtil.NULL;
import imgui.ImFontAtlas;
import imgui.ImFontConfig;
import imgui.ImGui;
import imgui.ImGuiIO;
import imgui.ImGuiStyle;
import imgui.flag.ImGuiCol;
import imgui.flag.ImGuiConfigFlags;
import imgui.gl3.ImGuiImplGl3;
import imgui.glfw.ImGuiImplGlfw;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.nio.IntBuffer;
import java.util.Objects;
import imgui.extension.imnodes.ImNodes;
import org.lwjgl.glfw.GLFWErrorCallback;
import org.lwjgl.glfw.GLFWVidMode;
import org.lwjgl.opengl.GL;
import org.lwjgl.system.MemoryStack;
@SuppressWarnings("MagicNumber")
public final class ImGuiGlfwExample {
private long windowPtr; // pointer to the current GLFW window
// LWJGJ3 window backend
private final ImGuiImplGlfw imGuiGlfw = new ImGuiImplGlfw();
// LWJGL3 renderer (SHOULD be initialized)
private final ImGuiImplGl3 imGuiGl3 = new ImGuiImplGl3();
private String glslVersion = null; // We can initialize our renderer with different versions of the GLSL
// User UI to render
private final ExampleUi exampleUi = new ExampleUi();
public void run() throws Exception {
setupGlfw();
setupImGui();
// Method initializes GLFW backend.
// This method SHOULD be called after you've setup GLFW.
// ImGui context should be created as well.
imGuiGlfw.init(windowPtr, true);
// 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.
imGuiGl3.init(glslVersion);
loop();
// You should clean up after yourself in reverse order.
imGuiGl3.dispose();
imGuiGlfw.dispose();
ImNodes.shutdown();
ImGui.destroyContext();
disposeWindow();
}
// 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 setupGlfw() {
// Setup an error callback. The default implementation
// will print the error message in System.err.
GLFWErrorCallback.createPrint(System.err).set();
// Initialize GLFW. Most GLFW functions will not work before doing this.
if (!glfwInit()) {
throw new IllegalStateException("Unable to initialize GLFW");
}
// Configure GLFW
glfwDefaultWindowHints(); // optional, the current window hints are already the default
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); // the window will stay hidden after creation
decideGlGlslVersions();
windowPtr = glfwCreateWindow(1280, 768, "Dear ImGui+LWJGL Example", NULL, NULL);
if (windowPtr == NULL) {
throw new RuntimeException("Failed to create the GLFW window");
}
// Get the thread stack and push a new frame
try (MemoryStack stack = stackPush()) {
final IntBuffer pWidth = stack.mallocInt(1); // int*
final IntBuffer pHeight = stack.mallocInt(1); // int*
// Get the window size passed to glfwCreateWindow
glfwGetWindowSize(windowPtr, pWidth, pHeight);
// Get the resolution of the primary monitor
final GLFWVidMode vidmode = Objects.requireNonNull(glfwGetVideoMode(glfwGetPrimaryMonitor()));
// Center the window
glfwSetWindowPos(windowPtr, (vidmode.width() - pWidth.get(0)) / 2, (vidmode.height() - pHeight.get(0)) / 2);
} // the stack frame is popped automatically
glfwMakeContextCurrent(windowPtr); // Make the OpenGL context current
glfwSwapInterval(GLFW_TRUE); // Enable v-sync
glfwShowWindow(windowPtr); // Make the window visible
// IMPORTANT!!
// This line is critical for LWJGL's interoperation with GLFW's
// OpenGL context, or any context that is managed externally.
// LWJGL detects the context that is current in the current thread,
// creates the GLCapabilities instance and makes the OpenGL
// bindings available for use.
GL.createCapabilities();
}
private void decideGlGlslVersions() {
final boolean isMac = System.getProperty("os.name").toLowerCase().contains("mac");
if (isMac) {
glslVersion = "#version 150";
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 3.2+ only
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // Required on Mac
} else {
glslVersion = "#version 130";
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
}
}
// Initialize Dear ImGui.
private void setupImGui() {
// IMPORTANT!!
// This line is critical for Dear ImGui to work.
ImGui.createContext();
ImNodes.initialize();
// ------------------------------------------------------------
// Initialize ImGuiIO config
final ImGuiIO io = ImGui.getIO();
io.setIniFilename(null); // We don't want to save .ini file
io.addConfigFlags(ImGuiConfigFlags.NavEnableKeyboard); // Enable Keyboard Controls
io.addConfigFlags(ImGuiConfigFlags.DockingEnable); // Enable Docking
io.addConfigFlags(ImGuiConfigFlags.ViewportsEnable); // Enable Multi-Viewport / Platform Windows
io.setConfigViewportsNoTaskBarIcon(true);
// ------------------------------------------------------------
// Fonts configuration
// 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
// 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();
// 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);
fontAtlas.addFontFromMemoryTTF(loadFromResources("basis33.ttf"), 16, fontConfig);
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);
// 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
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
if (io.hasConfigFlags(ImGuiConfigFlags.ViewportsEnable)) {
final ImGuiStyle style = ImGui.getStyle();
style.setWindowRounding(0.0f);
style.setColor(ImGuiCol.WindowBg, ImGui.getColorU32(ImGuiCol.WindowBg, 1));
}
}
// Main application loop
private void loop() throws Exception {
// Run the rendering loop until the user has attempted to close the window
while (!glfwWindowShouldClose(windowPtr)) {
startFrame();
// Any Dear ImGui code SHOULD go between ImGui.newFrame()/ImGui.render() methods
imGuiGlfw.newFrame();
ImGui.newFrame();
exampleUi.render();
ImGui.render();
endFrame();
}
}
private void startFrame() {
// Set the clear color and clear the window
glClearColor(exampleUi.backgroundColor[0], exampleUi.backgroundColor[1], exampleUi.backgroundColor[2], 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
}
private void endFrame() {
// 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.renderDrawData(ImGui.getDrawData());
if (ImGui.getIO().hasConfigFlags(ImGuiConfigFlags.ViewportsEnable)) {
final long backupWindowPtr = glfwGetCurrentContext();
ImGui.updatePlatformWindows();
ImGui.renderPlatformWindowsDefault();
glfwMakeContextCurrent(backupWindowPtr);
}
glfwSwapBuffers(windowPtr);
glfwPollEvents();
}
private void disposeWindow() {
glfwFreeCallbacks(windowPtr);
glfwDestroyWindow(windowPtr);
glfwTerminate();
Objects.requireNonNull(glfwSetErrorCallback(null)).free();
}
private byte[] loadFromResources(final String fileName) {
try (InputStream is = Objects.requireNonNull(getClass().getClassLoader().getResourceAsStream(fileName));
ByteArrayOutputStream buffer = new ByteArrayOutputStream()) {
final byte[] data = new byte[16384];
int nRead;
while ((nRead = is.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
}
return buffer.toByteArray();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
public static void main(final String[] args) throws Exception {
new ImGuiGlfwExample().run();
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.
Binary file not shown.