Add example for GLFW

This commit is contained in:
SpaiR committed 2019-12-29 23:59:35 +03:00
1 parent dc59810566
commit 3e7c50296c
13 files changed
+2606 -2561

No files matched your search

@@ -1,125 +0,0 @@
import org.lwjgl.glfw.GLFWKeyCallback;
import org.lwjgl.glfw.GLFWMouseButtonCallback;
import static org.lwjgl.glfw.GLFW.*;
public class InputHandler {
private static long window;
private static final int KEYBOARD_SIZE = 512;
private static final int MOUSE_SIZE = 16;
private static int[] keyStates = new int[KEYBOARD_SIZE];
private static boolean[] activeKeys = new boolean[KEYBOARD_SIZE];
private static int[] mouseButtonStates = new int[MOUSE_SIZE];
private static boolean[] activeMouseButtons = new boolean[MOUSE_SIZE];
private static long lastMouseNS = 0;
private static long mouseDoubleClickPeriodNS = 1000000000 / 5; //5th of a second for double click.
private static int NO_STATE = -1;
protected static GLFWKeyCallback keyboard = new GLFWKeyCallback()
{
@Override
public void invoke(long window, int key, int scancode, int action, int mods)
{
activeKeys[key] = action != GLFW_RELEASE;
keyStates[key] = action;
}
};
protected static GLFWMouseButtonCallback mouse = new GLFWMouseButtonCallback()
{
@Override
public void invoke(long window, int button, int action, int mods)
{
activeMouseButtons[button] = action != GLFW_RELEASE;
mouseButtonStates[button] = action;
}
};
protected static void init(long window)
{
InputHandler.window = window;
resetKeyboard();
resetMouse();
}
protected static void update()
{
resetKeyboard();
resetMouse();
}
private static void resetKeyboard()
{
for (int i = 0; i < keyStates.length; i++)
{
keyStates[i] = NO_STATE;
}
}
private static void resetMouse()
{
for (int i = 0; i < mouseButtonStates.length; i++)
{
mouseButtonStates[i] = NO_STATE;
}
long now = System.nanoTime();
if (now - lastMouseNS > mouseDoubleClickPeriodNS)
lastMouseNS = 0;
}
public static boolean keyDown(int key)
{
return activeKeys[key];
}
public static boolean keyPressed(int key)
{
return keyStates[key] == GLFW_PRESS;
}
public static boolean keyReleased(int key)
{
return keyStates[key] == GLFW_RELEASE;
}
public static boolean mouseButtonDown(int button)
{
return activeMouseButtons[button];
}
public static boolean mouseButtonPressed(int button)
{
return mouseButtonStates[button] == GLFW_RELEASE;
}
public static boolean mouseButtonReleased(int button)
{
boolean flag = mouseButtonStates[button] == GLFW_RELEASE;
if (flag)
lastMouseNS = System.nanoTime();
return flag;
}
public static boolean mouseButtonDoubleClicked(int button)
{
long last = lastMouseNS;
boolean flag = mouseButtonReleased(button);
long now = System.nanoTime();
if (flag && now - last < mouseDoubleClickPeriodNS)
{
lastMouseNS = 0;
return true;
}
return false;
}
}
-156
View File
@@ -1,156 +0,0 @@
import imgui.DrawData;
import imgui.ImGui;
import imgui.gl3.ImGuiImplGl3;
import org.lwjgl.BufferUtils;
import org.lwjgl.Version;
import org.lwjgl.glfw.GLFWErrorCallback;
import org.lwjgl.glfw.GLFWVidMode;
import org.lwjgl.opengl.GL;
import org.lwjgl.system.MemoryStack;
import java.nio.DoubleBuffer;
import java.nio.IntBuffer;
import static org.lwjgl.glfw.Callbacks.glfwFreeCallbacks;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.system.MemoryStack.stackPush;
import static org.lwjgl.system.MemoryUtil.NULL;
public class Main {
// The window handle
private long window;
private ImGuiImplGl3 imGuiGl = new ImGuiImplGl3();
public void run() {
System.out.println("Hello LWJGL " + Version.getVersion() + "!");
init();
loop();
// Free the window callbacks and destroy the window
glfwFreeCallbacks(window);
glfwDestroyWindow(window);
// Terminate GLFW and free the error callback
glfwTerminate();
glfwSetErrorCallback(null).free();
}
private void init() {
// 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
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); // the window will be resizable
// Create the window
window = glfwCreateWindow(1024, 768, "Hello World!", NULL, NULL);
if (window == NULL)
throw new RuntimeException("Failed to create the GLFW window");
// Setup a key callback. It will be called every time a key is pressed, repeated or released.
glfwSetKeyCallback(window, (window, key, scancode, action, mods) -> {
if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE)
glfwSetWindowShouldClose(window, true); // We will detect this in the rendering loop
});
glfwSetMouseButtonCallback(window, InputHandler.mouse);
// Get the thread stack and push a new frame
try (MemoryStack stack = stackPush()) {
IntBuffer pWidth = stack.mallocInt(1); // int*
IntBuffer pHeight = stack.mallocInt(1); // int*
// Get the window size passed to glfwCreateWindow
glfwGetWindowSize(window, pWidth, pHeight);
// Get the resolution of the primary monitor
GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
// Center the window
glfwSetWindowPos(
window,
(vidmode.width() - pWidth.get(0)) / 2,
(vidmode.height() - pHeight.get(0)) / 2
);
} // the stack frame is popped automatically
// Make the OpenGL context current
glfwMakeContextCurrent(window);
// Enable v-sync
glfwSwapInterval(1);
InputHandler.init(window);
// Make the window visible
glfwShowWindow(window);
}
long lastFrame = System.nanoTime();
public float getDelta() {
long time = System.nanoTime();
int delta_time = (int) ((time - lastFrame) / 1000000);
lastFrame = time;
return delta_time;
}
private void loop() {
// 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();
ImGui.init();
imGuiGl.init();
// Set the clear color
glClearColor(.5f, 0.0f, 0f, 0.0f);
int[] win_width = new int[1], win_height = new int[1];
int[] width = new int[1], height = new int[1];
DoubleBuffer xBuffer = BufferUtils.createDoubleBuffer(1);
DoubleBuffer yBuffer = BufferUtils.createDoubleBuffer(1);
// Run the rendering loop until the user has attempted to close
// the window or has pressed the ESCAPE key.
while (!glfwWindowShouldClose(window)) {
xBuffer.clear();
yBuffer.clear();
InputHandler.update();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the framebuffer
glfwGetWindowSize(window, win_width, win_height);
glfwGetFramebufferSize(window, width, height);
glfwGetCursorPos(window, xBuffer, yBuffer);
int mX = (int) xBuffer.get();
int mY = (int) yBuffer.get();
ImGui.UpdateDisplayAndInputAndFrame(getDelta(), win_width[0], win_height[0], width[0], height[0], mX, mY, InputHandler.mouseButtonDown(0), false, false);
ImGui.ShowDemoWindow();
ImGui.Render();
imGuiGl.render(ImGui.GetDrawData());
glfwSwapBuffers(window); // swap the color buffers
// Poll for window events. The key callback above will only be
// invoked during this call.
glfwPollEvents();
}
}
public static void main(String[] args) {
new Main().run();
}
}
@@ -10,10 +10,10 @@ import java.util.Objects;
import static org.lwjgl.opengl.GL30.*;
/**
* This class mostly a straightforward port of the https://raw.githubusercontent.com/ocornut/imgui/v1.74/examples/imgui_impl_opengl3.cpp adapted to Java and LWJGL realms.
* This class mostly a straightforward port of the https://raw.githubusercontent.com/ocornut/imgui/v1.74/examples/imgui_impl_opengl3.cpp adapted for Java and LWJGL realms.
* <p>
* It do support a backup of the current GL state before rendering and restoring of its initial state after.
* But some specific state variables may be missed (all which are hidden under '#ifdef' macros in the original imgui file).
* But some specific state variables may be missed (all which are hidden under '#ifdef' macros in the original 'imgui_impl_opengl3.cpp' file).
* <p>
* By default this implementation uses shaders with 130 version of GLSL (OpenGL 3.0).
* You can provide your own shaders into the {@link ImGuiImplGl3#init(CharSequence, CharSequence)} method.
@@ -55,7 +55,7 @@ public class ImGuiImplGl3 {
/**
* This method SHOULD be called before calling of {@link ImGuiImplGl3#render(DrawData)} method.
* By using this method shaders with 130 version of GLSL will be used for render.
* By using this method shaders with 130 version of GLSL (OpenGL 3.0) will be used for render.
*/
public void init() {
final CharSequence fragShaderSource = readFromResources("default.frag");
@@ -86,8 +86,8 @@ public class ImGuiImplGl3 {
}
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
int fbWidth = (int) (drawData.displaySizeX * drawData.framebufferScaleX);
int fbHeight = (int) (drawData.displaySizeY * drawData.framebufferScaleY);
final int fbWidth = (int) (drawData.displaySizeX * drawData.framebufferScaleX);
final int fbHeight = (int) (drawData.displaySizeY * drawData.framebufferScaleY);
if (fbWidth <= 0 || fbHeight <= 0) {
return;
@@ -169,7 +169,7 @@ public class ImGuiImplGl3 {
}
/**
* Call this method in the end of your app working state to clear used resources.
* Call this method in the end of your app working state to dispose resources.
*/
public void dispose() {
glDeleteTextures(gFontTexture);
@@ -196,7 +196,7 @@ public class ImGuiImplGl3 {
}
private void prepareFont() {
TexDataRGBA32 texData = new TexDataRGBA32();
final TexDataRGBA32 texData = new TexDataRGBA32();
ImGui.GetTexDataAsRGBA32(texData, texData.pixelBuffer);
gFontTexture = glGenTextures();
@@ -314,20 +314,23 @@ public class ImGuiImplGl3 {
}
private int loadAndCompileShader(final int type, final CharSequence source) {
int id = glCreateShader(type);
final int id = glCreateShader(type);
glShaderSource(id, source);
glCompileShader(id);
if (glGetShaderi(id, GL_COMPILE_STATUS) != GL_TRUE) {
throw new IllegalStateException(glGetShaderInfoLog(id));
}
return id;
}
private CharSequence readFromResources(final String path) {
StringBuilder builder = new StringBuilder();
final StringBuilder builder = new StringBuilder();
try (InputStream in = getClass().getClassLoader().getResourceAsStream(path);
BufferedReader reader = new BufferedReader(new InputStreamReader(Objects.requireNonNull(in)))) {
try (final InputStream in = getClass().getClassLoader().getResourceAsStream(path);
final BufferedReader reader = new BufferedReader(new InputStreamReader(Objects.requireNonNull(in)))) {
String line;
while ((line = reader.readLine()) != null) {
builder.append(line).append('\n');