Last active
August 29, 2015 14:21
-
-
Save SimonJinaphant/c87019abd2dc2f7608c2 to your computer and use it in GitHub Desktop.
LWJGL - GLFW Notes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
GLFW LIBRARY | |
============ | |
GLFW is an alternative multi-platform context and windowing library for OpenGL | |
Unlike other libraries, it does not take control of the main loop | |
One notable feature is GLFWErrorCallback which provides meaningful error messages, | |
are not alavilible in older libraries like GLUT. This feature can be set before initalizing. | |
*/ | |
glfwSetErrorCallback(errorCallback = Callbacks.errorCallbacksPrint(System.err)); | |
/* | |
INITIALIZING GLFW AND CREATING A WINDOW | |
======================================= | |
All GLFW applications must initialize GLFW before doing anything else | |
We can confirm the intialization by checking it against GL_TRUE or GL_FALSE | |
To create a window we need a handler variable to keep track of the window reference | |
Note: Since Java doesn't allow pointers and GLFW's library is based in C, checking | |
for nullptr can be done via MemoryUtil.NULL, which is different from the standard null | |
Optionally, we can setup a keyboard response method to deal with user input | |
Once the window is created we need to link the OpenGL context in order to use OpenGL in that window | |
We also need to determine the refresh rate for the screen via glfwSwapIntervals(), and finally | |
display the window | |
*/ | |
int windowHandler; //Declare this in global scope | |
if(glfwInit() == GL_FALSE){ | |
//Handle initialization errors here... | |
throw new IllegalStateException("Something went wrong when initializing GLFW"); | |
} | |
//Give some instructions on how to create the window we want | |
glfwDefaultWindowHints(); | |
glfwWindowHint(GLFW_VISIBLE, GL_TRUE); | |
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); | |
//Some important things for OpenGL to work properly... | |
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); | |
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); | |
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); | |
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); | |
windowHandler = glfwCreateWindow(600, 480, "Window Title", NULL, NULL) | |
if(windowHandler == NULL){ | |
//Handle window craetion error here... | |
throw new RuntimeException("Something went wrong when creating the main window"); | |
} | |
glfwSetKeyCallback(windowHandler, keyCallback = new GLFWKeyCallback() { | |
@Override | |
public void invoke(long window, int key, int scancode, int action, int mods) { | |
if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE) | |
glfwSetWindowShouldClose(window, GL_TRUE); | |
} | |
}); | |
glfwMakeContextCurrent(windowHandler); | |
glfwSwapInterval(1); | |
glfwShowWindow(windowHandler); | |
/* | |
THE MAIN LOOP | |
============= | |
In preparation for the main loop: | |
Create an OpenGL context to enable OpenGL functions | |
Set the clear color for the screen | |
If we are rendering 3D objects, it is best to enable the depth buffer | |
to prevent our drawings from overlaping | |
GLFW uses double buffering, where each window has a FRONT and BACK buffer. | |
Only the FRONT is display on the screen, while the BACK is being rendered. | |
This prevents the window from showing incomplete drawing/drawing in progress | |
When we're finish render we MUST swap the buffers to show the new changes. | |
The glfwSwapInterval() we called previously controls the refresh rate for the buffers | |
Inside the loop: | |
Remember to clear the color buffer and the depth buffer every iteration | |
Only swap the buffers once the rendering is finished and poll for user | |
input if you've setup any input handling methods | |
*/ | |
GLContext.createFromCurrent(); | |
glClearColor(0, 0, 0, 1); | |
glEnable(GL11.GL_DEPTH_TEST); | |
while(glfwWindowShouldClose(windowID) == GL_FALSE){ | |
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |
//Render objects here... | |
glfwSwapBuffer(windowID); | |
glfwPollEvents(); | |
} | |
/* | |
Destroying GLFW objects | |
======================= | |
Remember to release any callback objects you've created, | |
this is why we've kept reference to those objects inside a variable | |
We destroy the window by passing in the windowHandler into glfwDestroyWindow and terminate | |
GLFW completely by glfwTerminate() | |
*/ | |
keyCallback.release(); | |
errorCallback.release(); | |
//Clear up any other OpenGL resources too (VAO, VBO, Shaders, etc...) | |
glfwDestroyWindow(windowHandler); | |
glfwTerminate(); | |
/* | |
FINAL NOTE | |
========== | |
Only on Mac OSX, LWJGL has to be executed with the JVM argument -XstartOnFirstThread | |
This consequently blocks Java's AWT and SWT threads from working properly, | |
thus making other libraries such as ImageIO hang without any error messages. | |
One trick to avoid this is to set -java.awt.headless to true inside a static block | |
*/ | |
static { | |
System.setProperty("java.awt.headless", "true"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment