Skip to content

Instantly share code, notes, and snippets.

@Unh0lyTigg
Created November 21, 2014 00:42
Show Gist options
  • Save Unh0lyTigg/cd301e502094b287d4ad to your computer and use it in GitHub Desktop.
Save Unh0lyTigg/cd301e502094b287d4ad to your computer and use it in GitHub Desktop.
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.system.MemoryUtil.NULL;
import static org.lwjgl.system.glfw.GLFW.*;
import java.awt.Dimension;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Point;
import java.nio.ByteBuffer;
//import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.lwjgl.PointerBuffer;
import org.lwjgl.opengl.GL;
import org.lwjgl.opengl.GLContext;
//import org.lwjgl.system.MemoryUtil;
import org.lwjgl.system.glfw.ErrorCallback;
import org.lwjgl.system.glfw.GLFWvidmode;
import org.lwjgl.system.glfw.WindowCallback;
import org.lwjgl.system.glfw.WindowCallbackAdapter;
public class Window {
private long windowId;
private String title;
private Callback callback = new Callback(this);
private int width, height;
private int x, y;
private boolean visible = false;
private static boolean isSetup = false;
public static void setupGLFW() {
if (isSetup)
return;
glfwSetErrorCallback(ErrorCallback.Util.getDefault());
if (glfwInit() != GL_TRUE)
throw new IllegalStateException("Unable to initialize GLFW");
glfwDefaultWindowHints();
glfwWindowHint(GLFW_VISIBLE, GL_FALSE);
glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);
}
public static void setupGlOrtho(int width, int height) {
if (GL.getCurrent() == null)
return;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, width, height, 0, 1, -1);
glMatrixMode(GL_MODELVIEW);
}
public Window(String title, int width, int height) {
windowId = glfwCreateWindow(width, height, title, NULL, NULL);
if (windowId == NULL)
throw new IllegalStateException("Failed to create GLFW window");
WindowCallback.set(windowId, callback);
this.width = width;
this.height = height;
this.title = title;
}
public void setSwapInterval(int interval) {
glfwSwapInterval(interval);
}
public void swapBuffers() {
glfwSwapBuffers(windowId);
}
public boolean isClosedRequested() {
return glfwWindowShouldClose(windowId) == GL_TRUE;
}
public GLContext setCurrentContext() {
glfwMakeContextCurrent(windowId);
return GLContext.createFromCurrent();
}
public boolean isResizable() {
return glfwGetWindowAttrib(windowId, GLFW_RESIZABLE) == GL_TRUE;
}
public void setSize(int width, int height) {
glfwSetWindowSize(windowId, width, height);
}
public void setSize(Dimension size) {
setSize(size.width, size.height);
}
public Dimension getSize() {
return new Dimension(width, height);
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
public Point getLocation() {
return new Point(x, y);
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public void setLocation(int x, int y) {
glfwSetWindowPos(windowId, x, y);
}
public void setLocation(Point p) {
setLocation(p.x, p.y);
}
public void setVisible(boolean visible) {
if (visible)
glfwShowWindow(windowId);
else
glfwHideWindow(windowId);
this.visible = visible;
}
public boolean isVisible() {
return visible;
}
public void setTitle(String title) {
this.title = title;
glfwSetWindowTitle(windowId, title);
}
public String getTitle() {
return title;
}
public void addRefreshCallback(RefreshCallback callback) {
if (callback == null)
return;
this.callback.add(callback);
}
public void addPositionCallback(PositionCallback callback) {
if (callback == null)
return;
this.callback.add(callback);
}
public void addWindowStateCallback(WindowStateCallback callback) {
if (callback == null)
return;
this.callback.add(callback);
}
public void addMouseCallback(MouseCallback callback) {
if (callback == null)
return;
this.callback.add(callback);
}
public void addKeyCallback(KeyCallback callback) {
if (callback == null)
return;
this.callback.add(callback);
}
public void destroy() {
glfwDestroyWindow(windowId);
}
public void centerOnMonitor(int monitorIndex) {
GraphicsEnvironment e = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[] devices = e.getScreenDevices();
PointerBuffer monitors = glfwGetMonitors();
long monitor = monitors.get(monitorIndex);
ByteBuffer vidmode = glfwGetVideoMode(monitor);
GraphicsConfiguration config = devices[monitorIndex].getDefaultConfiguration();
int xInt = config.getBounds().x;
int yInt = config.getBounds().y;
int xPos = xInt + ((GLFWvidmode.width(vidmode) - width) / 2);
int yPos = yInt + ((GLFWvidmode.height(vidmode) - height) / 2);
glfwSetWindowPos(windowId, xPos, yPos);
}
private class Callback extends WindowCallbackAdapter {
private Window window;
private boolean focused = false;
private boolean shouldCallDragIfMove = false;
private Object lock = new Object();
private List<RefreshCallback> refreshers = new ArrayList<RefreshCallback>();
private List<PositionCallback> posCallbacks = new ArrayList<PositionCallback>();
private List<WindowStateCallback> wsCallbacks = new ArrayList<WindowStateCallback>();
private List<MouseCallback> mouseCallbacks = new ArrayList<MouseCallback>();
private List<KeyCallback> keyCallbacks = new ArrayList<KeyCallback>();
protected void add(RefreshCallback callback) {
synchronized(lock) {
refreshers.add(callback);
}
}
protected void add(PositionCallback callback) {
synchronized(lock) {
posCallbacks.add(callback);
}
}
protected void add(WindowStateCallback callback) {
synchronized(lock) {
wsCallbacks.add(callback);
}
}
protected void add(MouseCallback callback) {
synchronized(lock) {
mouseCallbacks.add(callback);
}
}
protected void add(KeyCallback callback) {
synchronized(lock) {
keyCallbacks.add(callback);
}
}
protected Callback(Window window) {
this.window = window;
}
@Override
public void windowSize(long window, int width, int height) {
if (window != this.window.windowId)
return;
this.window.width = width;
this.window.height = height;
synchronized(lock) {
for (WindowStateCallback c : wsCallbacks)
c.windowResized(this.window, width, height);
}
}
@Override
public void cursorEnter(long window, int entered) {
if (window != this.window.windowId)
return;
synchronized(lock) {
if (entered == GL_TRUE) {
for (MouseCallback c : mouseCallbacks)
c.mouseEntered(this.window);
} else if (entered == GL_FALSE) {
for (MouseCallback c : mouseCallbacks)
c.mouseExited(this.window);
}
}
}
@Override
public void cursorPos(long window, double xpos, double ypos) {
if (window != this.window.windowId)
return;
synchronized(lock) {
for (MouseCallback c : mouseCallbacks)
c.mouseMoved(this.window, xpos, ypos, shouldCallDragIfMove);
}
}
@Override
public void key(long window, int key, int scancode, int action, int mods) {
if (window != this.window.windowId)
return;
synchronized(lock) {
if (action == GLFW_PRESS) {
for (KeyCallback c : keyCallbacks)
c.keyPressed(this.window, key, scancode, mods);
} else if (action == GLFW_RELEASE) {
for (KeyCallback c : keyCallbacks)
c.keyReleased(this.window, key, scancode, mods);
} else if (action == GLFW_REPEAT) {
for (KeyCallback c : keyCallbacks)
c.keyRepeated(this.window, key, scancode, mods);
}
}
}
@Override
public void mouseButton(long window, int button, int action, int mods) {
if (window != this.window.windowId)
return;
boolean synth = !focused && (action == GLFW_RELEASE);
synchronized(lock) {
if (action == GLFW_PRESS) {
shouldCallDragIfMove = true;
for (MouseCallback c : mouseCallbacks)
c.mouseButtonPressed(this.window, button, mods);
} else if (action == GLFW_RELEASE) {
shouldCallDragIfMove = false;
for (MouseCallback c : mouseCallbacks)
c.mouseButtonReleased(this.window, button, mods, synth);
}
}
}
// @Override
// public void drop(long window, int count, long names) {
// if (window != this.window.windowId)
// return;
// synchronized(lock) {
//
// }
// }
@Override
public void scroll(long window, double xoffset, double yoffset) {
if (window != this.window.windowId)
return;
synchronized(lock) {
for (MouseCallback c : mouseCallbacks)
c.mouseScrolled(this.window, xoffset, yoffset);
}
}
@Override
public void windowClose(long window) {
if (window != this.window.windowId)
return;
synchronized(lock) {
for (WindowStateCallback c : wsCallbacks)
c.windowClosed(this.window);
}
}
@Override
public void windowFocus(long window, int focused) {
if (window != this.window.windowId)
return;
synchronized(lock) {
if (focused == GL_FALSE) {
this.focused = false;
for (WindowStateCallback c : wsCallbacks)
c.windowFocusLost(this.window);
} else if (focused == GL_TRUE) {
this.focused = true;
for (WindowStateCallback c : wsCallbacks)
c.windowFocusGained(this.window);
}
}
}
@Override
public void windowIconify(long window, int iconified) {
if (window != this.window.windowId)
return;
synchronized(lock) {
if (iconified == GL_FALSE) {
for (WindowStateCallback c : wsCallbacks)
c.windowIconified(this.window);
} else if (iconified == GL_TRUE) {
for (WindowStateCallback c : wsCallbacks)
c.windowRestored(this.window);
}
}
}
@Override
public void windowPos(long window, int xpos, int ypos) {
if (window != this.window.windowId)
return;
synchronized(lock) {
for (PositionCallback c : posCallbacks)
c.windowPositionChanged(this.window, xpos, ypos);
}
}
@Override
public void windowRefresh(long window) {
if (window != this.window.windowId)
return;
synchronized(lock) {
for (RefreshCallback c : refreshers)
c.windowRefreshed(this.window);
}
}
}
public static interface RefreshCallback {
public static class Adapter implements RefreshCallback {
public void windowRefreshed(Window window) {}
}
public void windowRefreshed(Window window);
}
public static interface PositionCallback {
public static class Adapter implements PositionCallback {
public void windowPositionChanged(Window window, int x, int y) {}
}
public void windowPositionChanged(Window window, int x, int y);
}
public static interface WindowStateCallback {
public static class Adapter implements WindowStateCallback {
public void windowIconified(Window window) {}
public void windowRestored(Window window) {}
public void windowFocusGained(Window window) {}
public void windowFocusLost(Window window) {}
public void windowClosed(Window window) {}
public void windowResized(Window window, int width, int height) {}
}
public static WindowStateCallback GL_RELOAD_ORTHO = new Adapter() {
@Override
public void windowResized(Window window, int width, int height) {
setupGlOrtho(width, height);
}
};
public void windowIconified(Window window);
public void windowRestored(Window window);
public void windowFocusGained(Window window);
public void windowFocusLost(Window window);
public void windowClosed(Window window);
public void windowResized(Window window, int width, int height);
}
public static interface MouseCallback {
public static class Adapter implements MouseCallback {
public void mouseEntered(Window window) {}
public void mouseExited(Window window) {}
public void mouseMoved(Window window, double x, double y, boolean dragged) {}
public void mouseButtonPressed(Window window, int button, int mods) {}
public void mouseButtonReleased(Window window, int button, int mods, boolean synth) {}
public void mouseScrolled(Window window, double xOffset, double yOffset) {}
}
public void mouseEntered(Window window);
public void mouseExited(Window window);
public void mouseMoved(Window window, double x, double y, boolean dragged);
public void mouseButtonPressed(Window window, int button, int mods);
public void mouseButtonReleased(Window window, int button, int mods, boolean synth);
public void mouseScrolled(Window window, double xOffset, double yOffset);
}
public static interface KeyCallback {
public static class Adapter implements KeyCallback {
public void keyPressed(Window window, int key, int scancode, int mods) {}
public void keyReleased(Window window, int key, int scancode, int mods) {}
public void keyRepeated(Window window, int key, int scancode, int mods) {}
}
public static KeyCallback ESC_CLOSES_WINDOW = new Adapter() {
@Override
public void keyReleased(Window window, int key, int scancode, int mods) {
if (key == GLFW_KEY_ESCAPE)
glfwSetWindowShouldClose(window.windowId, GL_TRUE);
}
};
public void keyPressed(Window window, int key, int scancode, int mods);
public void keyReleased(Window window, int key, int scancode, int mods);
public void keyRepeated(Window window, int key, int scancode, int mods);
}
// // Currently not used, dev needs to understand how to get Strings from raw memory (through ByteBuffer and MemoryUtil) first.
// public static interface FileDropCallback {
// public void filesDropped(Window window, File[] files);
// }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment