1import org.lwjgl.*;
2import org.lwjgl.glfw.*;
3import org.lwjgl.opengl.*;
4import org.lwjgl.system.*;
5
6import java.nio.*;
7
8import static org.lwjgl.glfw.Callbacks.*;
9import static org.lwjgl.glfw.GLFW.*;
10import static org.lwjgl.opengl.GL11.*;
11import static org.lwjgl.system.MemoryStack.*;
12import static org.lwjgl.system.MemoryUtil.*;
13
14public class HelloWorld {
15
16 // The window handle
17 private long window;
18
19 public void run() {
20 System.out.println("Hello LWJGL " + Version.getVersion() + "!");
21
22 init();
23 loop();
24
25 // Free the window callbacks and destroy the window
26 glfwFreeCallbacks(window);
27 glfwDestroyWindow(window);
28
29 // Terminate GLFW and free the error callback
30 glfwTerminate();
31 glfwSetErrorCallback(null).free();
32 }
33
34 private void init() {
35 // Setup an error callback. The default implementation
36 // will print the error message in System.err.
37 GLFWErrorCallback.createPrint(System.err).set();
38
39 // Initialize GLFW. Most GLFW functions will not work before doing this.
40 if ( !glfwInit() )
41 throw new IllegalStateException("Unable to initialize GLFW");
42
43 // Configure GLFW
44 glfwDefaultWindowHints(); // optional, the current window hints are already the default
45 glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); // the window will stay hidden after creation
46 glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); // the window will be resizable
47
48 // Create the window
49 window = glfwCreateWindow(300, 300, "Hello World!", NULL, NULL);
50 if ( window == NULL )
51 throw new RuntimeException("Failed to create the GLFW window");
52
53 // Setup a key callback. It will be called every time a key is pressed, repeated or released.
54 glfwSetKeyCallback(window, (window, key, scancode, action, mods) -> {
55 if ( key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE )
56 glfwSetWindowShouldClose(window, true); // We will detect this in the rendering loop
57 });
58
59 // Get the thread stack and push a new frame
60 try ( MemoryStack stack = stackPush() ) {
61 IntBuffer pWidth = stack.mallocInt(1); // int*
62 IntBuffer pHeight = stack.mallocInt(1); // int*
63
64 // Get the window size passed to glfwCreateWindow
65 glfwGetWindowSize(window, pWidth, pHeight);
66
67 // Get the resolution of the primary monitor
68 GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
69
70 // Center the window
71 glfwSetWindowPos(
72 window,
73 (vidmode.width() - pWidth.get(0)) / 2,
74 (vidmode.height() - pHeight.get(0)) / 2
75 );
76 } // the stack frame is popped automatically
77
78 // Make the OpenGL context current
79 glfwMakeContextCurrent(window);
80 // Enable v-sync
81 glfwSwapInterval(1);
82
83 // Make the window visible
84 glfwShowWindow(window);
85 }
86
87 private void loop() {
88 // This line is critical for LWJGL's interoperation with GLFW's
89 // OpenGL context, or any context that is managed externally.
90 // LWJGL detects the context that is current in the current thread,
91 // creates the GLCapabilities instance and makes the OpenGL
92 // bindings available for use.
93 GL.createCapabilities();
94
95 // Set the clear color
96 glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
97
98 // Run the rendering loop until the user has attempted to close
99 // the window or has pressed the ESCAPE key.
100 while ( !glfwWindowShouldClose(window) ) {
101 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the framebuffer
102
103 glfwSwapBuffers(window); // swap the color buffers
104
105 // Poll for window events. The key callback above will only be
106 // invoked during this call.
107 glfwPollEvents();
108 }
109 }
110
111 public static void main(String[] args) {
112 new HelloWorld().run();
113 }
114
115}