Last active
May 6, 2024 21:08
-
-
Save yevgenko/b77beaf9893bed74a970bfdc9e63bf28 to your computer and use it in GitHub Desktop.
Minimal Java OpenGL example with LWJGL: displays window with red background
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
import org.lwjgl.Version; | |
import org.lwjgl.opengl.GL; | |
import static org.lwjgl.glfw.Callbacks.glfwFreeCallbacks; | |
// glfwCreateWindow, etc. | |
import static org.lwjgl.glfw.GLFW.*; | |
// GL_COLOR_BUFFER_BIT, etc. | |
import static org.lwjgl.opengl.GL11.*; | |
import static org.lwjgl.system.MemoryUtil.NULL; | |
// java -XstartOnFirstThread -cp lwjgl-release-3.3.3-custom/lwjgl.jar:lwjgl-release-3.3.3-custom/lwjgl-natives-macos.jar:lwjgl-release-3.3.3-custom/lwjgl-glfw.jar:lwjgl-release-3.3.3-custom/lwjgl-glfw-natives-macos.jar:lwjgl-release-3.3.3-custom/lwjgl-opengl.jar:lwjgl-release-3.3.3-custom/lwjgl-opengl-natives-macos.jar MyGame.java | |
// | |
// https://www.lwjgl.org/customize | |
// * ZIP Bundle | |
// * Minimal OpenGL | |
// * macOS x64 | |
// | |
// See also https://github.com/LWJGL/lwjgl3-demos/tree/main/src/org/lwjgl/demo/intro | |
// Provides justification for every compontent in basic example | |
public class MyGame { | |
public static void main(String[] args) { | |
System.out.println("Hello LWJGL " + Version.getVersion() + "!"); | |
if (!glfwInit()) | |
throw new IllegalStateException("Unable to initialize GLFW"); | |
long window = glfwCreateWindow(300, 300, "Hello World!", NULL, NULL); | |
if (window == NULL) | |
throw new RuntimeException("Failed to create the GLFW window"); | |
glfwMakeContextCurrent(window); | |
glfwSwapInterval(1); | |
glfwShowWindow(window); | |
GL.createCapabilities(); | |
glClearColor(1.0f, 0.0f, 0.0f, 0.0f); | |
int x = 0; | |
int delta = 1; | |
// game loop | |
while (!glfwWindowShouldClose(window)) { | |
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |
/* | |
glBegin(GL_QUADS); | |
glVertex2f(-0.5f, 0.5f); | |
glVertex2f(0.5f, 0.5f); | |
glVertex2f(0.5f, -0.5f); | |
glVertex2f(-0.5f, -0.5f); | |
glEnd(); | |
*/ | |
if (x > 290) | |
delta = -1; | |
if (x < 0) | |
delta = 1; | |
x += delta; | |
glColor3f(100, 100, 100); | |
drawRectangle(x, 0, 10, 10); | |
glColor3f(0, 155, 155); | |
drawRectangle(100, 100, 10, 10); | |
glfwSwapBuffers(window); | |
glfwPollEvents(); | |
} | |
glfwFreeCallbacks(window); | |
glfwTerminate(); | |
} | |
/** | |
* How to test? | |
* | |
* Unit: | |
* - glVertex2f called expected number of times, in order with expected arguments | |
* | |
* Integration: | |
* - draw rectangle using glVertex2f based method | |
* - draw the same rectangle using drawRectangle method | |
* - compare metrices (should match) or sutract matrices and assert result is 0 | |
* | |
* Alternatively: Change Design to make testing easier | |
* - static Vertex2f[] rectangleVertices(int x, int y, int width, int height); | |
* - returns list of points (tuples) | |
* - static void drawVertices(Vertex2f[] vertices, GL_QUADS); | |
* - humble object pattern (loop over vertices and draws the quad) | |
* | |
*/ | |
private static void drawRectangle(int x, int y, int width, int height) { | |
glBegin(GL_QUADS); | |
pixelVertex2i(x, y); | |
pixelVertex2i(x + width, y); | |
pixelVertex2i(x + width, y + height); | |
pixelVertex2i(x, y + height); | |
glEnd(); | |
} | |
private static void pixelVertex2i(int x, int y) { | |
glVertex2f(pixelPos2Gl(x), pixelPos2Gl(y)); | |
} | |
private static float pixelPos2Gl(int i) { | |
return -1.0f + (float) i * (2.0f / 300.0f) + (1.0f / 300.0f); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment