From 141e89951ab1edcfd914c83c6f1268c8e2df2eae Mon Sep 17 00:00:00 2001 From: Andrew Lalis Date: Tue, 5 Jul 2022 17:15:43 +0200 Subject: [PATCH] Improved window stuff with fullscreen. --- .../nl/andrewl/aos2_client/Aos2Client.java | 27 ++++++++++--------- .../andrewl/aos2_client/render/ChunkMesh.java | 10 +++++++ .../aos2_client/render/ChunkRenderer.java | 10 +++++-- .../aos2_client/render/WindowInfo.java | 7 +++++ .../java/nl/andrewl/aos_core/model/Chunk.java | 8 +++++- 5 files changed, 46 insertions(+), 16 deletions(-) create mode 100644 client/src/main/java/nl/andrewl/aos2_client/render/WindowInfo.java diff --git a/client/src/main/java/nl/andrewl/aos2_client/Aos2Client.java b/client/src/main/java/nl/andrewl/aos2_client/Aos2Client.java index 88f11d9..b840338 100644 --- a/client/src/main/java/nl/andrewl/aos2_client/Aos2Client.java +++ b/client/src/main/java/nl/andrewl/aos2_client/Aos2Client.java @@ -2,14 +2,12 @@ package nl.andrewl.aos2_client; import nl.andrewl.aos2_client.render.ChunkMesh; import nl.andrewl.aos2_client.render.ChunkRenderer; +import nl.andrewl.aos2_client.render.WindowInfo; import nl.andrewl.aos_core.model.Chunk; import org.joml.Vector3i; -import org.lwjgl.Version; import org.lwjgl.glfw.Callbacks; import org.lwjgl.glfw.GLFWErrorCallback; import org.lwjgl.opengl.GL; -import org.lwjgl.opengl.GLUtil; -import org.lwjgl.system.MemoryUtil; import java.util.Random; @@ -18,7 +16,8 @@ import static org.lwjgl.opengl.GL46.*; public class Aos2Client { public static void main(String[] args) { - long windowHandle = initUI(); + var windowInfo = initUI(); + long windowHandle = windowInfo.windowHandle(); Camera cam = new Camera(); cam.setOrientationDegrees(90, 90); @@ -30,7 +29,7 @@ public class Aos2Client { Chunk chunk3 = Chunk.random(new Vector3i(1, 0, 1), new Random(1)); Chunk chunk4 = Chunk.random(new Vector3i(0, 0, 1), new Random(1)); -// chunk.setBlockAt(0, 0, 0, (byte) 0); + chunk.setBlockAt(0, 0, 0, (byte) 0); for (int x = 0; x < Chunk.SIZE; x++) { for (int z = 0; z < Chunk.SIZE; z++) { @@ -38,7 +37,7 @@ public class Aos2Client { } } - ChunkRenderer chunkRenderer = new ChunkRenderer(); + ChunkRenderer chunkRenderer = new ChunkRenderer(windowInfo.width(), windowInfo.height()); chunkRenderer.addChunkMesh(new ChunkMesh(chunk)); chunkRenderer.addChunkMesh(new ChunkMesh(chunk2)); chunkRenderer.addChunkMesh(new ChunkMesh(chunk3)); @@ -68,16 +67,18 @@ public class Aos2Client { glfwSetErrorCallback(null).free(); } - private static long initUI() { - System.out.println("LWJGL Version: " + Version.getVersion()); + private static WindowInfo initUI() { GLFWErrorCallback.createPrint(System.err).set(); - if (!glfwInit()) throw new IllegalStateException("Could not initialize GLFW"); + if (!glfwInit()) throw new IllegalStateException("Could not initialize GLFW."); glfwDefaultWindowHints(); glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); - long windowHandle = glfwCreateWindow(800, 600, "Ace of Shades 2", MemoryUtil.NULL, MemoryUtil.NULL); - if (windowHandle == MemoryUtil.NULL) throw new RuntimeException("Failed to create GLFW window."); + var vidMode = glfwGetVideoMode(glfwGetPrimaryMonitor()); + if (vidMode == null) throw new IllegalStateException("Could not get information about the primary monitory."); + long windowHandle = glfwCreateWindow(vidMode.width(), vidMode.height(), "Ace of Shades 2", 0, 0); + if (windowHandle == 0) throw new RuntimeException("Failed to create GLFW window."); + glfwSetKeyCallback(windowHandle, (window, key, scancode, action, mods) -> { if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE) { glfwSetWindowShouldClose(windowHandle, true); @@ -87,7 +88,7 @@ public class Aos2Client { glfwSetInputMode(windowHandle, GLFW_CURSOR, GLFW_CURSOR_DISABLED); glfwSetInputMode(windowHandle, GLFW_RAW_MOUSE_MOTION, GLFW_TRUE); - glfwSetWindowPos(windowHandle, 50, 50); + glfwSetWindowPos(windowHandle, 0, 0); glfwSetCursorPos(windowHandle, 0, 0); glfwMakeContextCurrent(windowHandle); @@ -101,6 +102,6 @@ public class Aos2Client { glEnable(GL_DEPTH_TEST); glCullFace(GL_BACK); - return windowHandle; + return new WindowInfo(windowHandle, vidMode.width(), vidMode.height()); } } diff --git a/client/src/main/java/nl/andrewl/aos2_client/render/ChunkMesh.java b/client/src/main/java/nl/andrewl/aos2_client/render/ChunkMesh.java index 0a2def4..a852e30 100644 --- a/client/src/main/java/nl/andrewl/aos2_client/render/ChunkMesh.java +++ b/client/src/main/java/nl/andrewl/aos2_client/render/ChunkMesh.java @@ -38,8 +38,18 @@ public class ChunkMesh { * Generates and loads this chunk's mesh into the allocated OpenGL buffers. */ private void loadMesh() { + long start = System.nanoTime(); var meshData = ChunkMeshGenerator.generateMesh(chunk); + double dur = (System.nanoTime() - start) / 1_000_000.0; this.indiciesCount = meshData.indexBuffer().limit(); + // Print some debug information. + System.out.printf( + "Generated mesh for chunk (%d, %d, %d) in %.3f ms. %d vertices, %d indices.%n", + chunk.getPosition().x, chunk.getPosition().y, chunk.getPosition().z, + dur, + meshData.vertexBuffer().limit() / 9, + indiciesCount + ); glBindBuffer(GL_ARRAY_BUFFER, vboId); glBufferData(GL_ARRAY_BUFFER, meshData.vertexBuffer(), GL_STATIC_DRAW); diff --git a/client/src/main/java/nl/andrewl/aos2_client/render/ChunkRenderer.java b/client/src/main/java/nl/andrewl/aos2_client/render/ChunkRenderer.java index bebfae4..3839b86 100644 --- a/client/src/main/java/nl/andrewl/aos2_client/render/ChunkRenderer.java +++ b/client/src/main/java/nl/andrewl/aos2_client/render/ChunkRenderer.java @@ -9,6 +9,11 @@ import java.util.List; import static org.lwjgl.opengl.GL46.*; +/** + * The chunk renderer is responsible for managing the shader program, uniforms, + * and all currently loaded chunk meshes, so that the set of loaded chunks can + * be rendered each frame. + */ public class ChunkRenderer { private final ShaderProgram shaderProgram; private final int projectionTransformUniform; @@ -17,11 +22,12 @@ public class ChunkRenderer { private final int chunkPositionUniform; private final int chunkSizeUniform; - private final Matrix4f projectionTransform = new Matrix4f().perspective(70, 800 / 600.0f, 0.01f, 100.0f); + private final Matrix4f projectionTransform; private final List chunkMeshes = new ArrayList<>(); - public ChunkRenderer() { + public ChunkRenderer(int windowWidth, int windowHeight) { + this.projectionTransform = new Matrix4f().perspective(70, (float) windowWidth / (float) windowHeight, 0.01f, 100.0f); this.shaderProgram = new ShaderProgram.Builder() .withShader("shader/chunk/vertex.glsl", GL_VERTEX_SHADER) .withShader("shader/chunk/fragment.glsl", GL_FRAGMENT_SHADER) diff --git a/client/src/main/java/nl/andrewl/aos2_client/render/WindowInfo.java b/client/src/main/java/nl/andrewl/aos2_client/render/WindowInfo.java new file mode 100644 index 0000000..6c56a8c --- /dev/null +++ b/client/src/main/java/nl/andrewl/aos2_client/render/WindowInfo.java @@ -0,0 +1,7 @@ +package nl.andrewl.aos2_client.render; + +public record WindowInfo( + long windowHandle, + int width, + int height +) {} diff --git a/core/src/main/java/nl/andrewl/aos_core/model/Chunk.java b/core/src/main/java/nl/andrewl/aos_core/model/Chunk.java index 5eba16b..d3dc5a5 100644 --- a/core/src/main/java/nl/andrewl/aos_core/model/Chunk.java +++ b/core/src/main/java/nl/andrewl/aos_core/model/Chunk.java @@ -6,13 +6,19 @@ import org.joml.Vector3i; import java.util.Random; /** - * Holds information about a uniform "chunk" of the voxel world. + * Holds information about a uniform "chunk" of the voxel world, with a cubic + * shape. Each chunk contains a flattened 1-dimensional array that holds the + * information about each "block" in the chunk. */ public class Chunk { /** * The size of a chunk, in terms of the number of blocks on one axis of the cube. */ public static final int SIZE = 16; + + /** + * The total size of the chunk's {@link Chunk#blocks} array. + */ public static final int TOTAL_SIZE = SIZE * SIZE * SIZE; private final byte[] blocks = new byte[TOTAL_SIZE];