Skip to content

Instantly share code, notes, and snippets.

@yevgenko
Last active May 6, 2024 21:08
Show Gist options
  • Save yevgenko/b77beaf9893bed74a970bfdc9e63bf28 to your computer and use it in GitHub Desktop.
Save yevgenko/b77beaf9893bed74a970bfdc9e63bf28 to your computer and use it in GitHub Desktop.
Minimal Java OpenGL example with LWJGL: displays window with red background
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