Improved window stuff with fullscreen.

This commit is contained in:
Andrew Lalis 2022-07-05 17:15:43 +02:00
parent be6832c6a4
commit 141e89951a
5 changed files with 46 additions and 16 deletions

View File

@ -2,14 +2,12 @@ package nl.andrewl.aos2_client;
import nl.andrewl.aos2_client.render.ChunkMesh; import nl.andrewl.aos2_client.render.ChunkMesh;
import nl.andrewl.aos2_client.render.ChunkRenderer; import nl.andrewl.aos2_client.render.ChunkRenderer;
import nl.andrewl.aos2_client.render.WindowInfo;
import nl.andrewl.aos_core.model.Chunk; import nl.andrewl.aos_core.model.Chunk;
import org.joml.Vector3i; import org.joml.Vector3i;
import org.lwjgl.Version;
import org.lwjgl.glfw.Callbacks; import org.lwjgl.glfw.Callbacks;
import org.lwjgl.glfw.GLFWErrorCallback; import org.lwjgl.glfw.GLFWErrorCallback;
import org.lwjgl.opengl.GL; import org.lwjgl.opengl.GL;
import org.lwjgl.opengl.GLUtil;
import org.lwjgl.system.MemoryUtil;
import java.util.Random; import java.util.Random;
@ -18,7 +16,8 @@ import static org.lwjgl.opengl.GL46.*;
public class Aos2Client { public class Aos2Client {
public static void main(String[] args) { public static void main(String[] args) {
long windowHandle = initUI(); var windowInfo = initUI();
long windowHandle = windowInfo.windowHandle();
Camera cam = new Camera(); Camera cam = new Camera();
cam.setOrientationDegrees(90, 90); cam.setOrientationDegrees(90, 90);
@ -30,7 +29,7 @@ public class Aos2Client {
Chunk chunk3 = Chunk.random(new Vector3i(1, 0, 1), new Random(1)); 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 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 x = 0; x < Chunk.SIZE; x++) {
for (int z = 0; z < Chunk.SIZE; z++) { 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(chunk));
chunkRenderer.addChunkMesh(new ChunkMesh(chunk2)); chunkRenderer.addChunkMesh(new ChunkMesh(chunk2));
chunkRenderer.addChunkMesh(new ChunkMesh(chunk3)); chunkRenderer.addChunkMesh(new ChunkMesh(chunk3));
@ -68,16 +67,18 @@ public class Aos2Client {
glfwSetErrorCallback(null).free(); glfwSetErrorCallback(null).free();
} }
private static long initUI() { private static WindowInfo initUI() {
System.out.println("LWJGL Version: " + Version.getVersion());
GLFWErrorCallback.createPrint(System.err).set(); GLFWErrorCallback.createPrint(System.err).set();
if (!glfwInit()) throw new IllegalStateException("Could not initialize GLFW"); if (!glfwInit()) throw new IllegalStateException("Could not initialize GLFW.");
glfwDefaultWindowHints(); glfwDefaultWindowHints();
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
long windowHandle = glfwCreateWindow(800, 600, "Ace of Shades 2", MemoryUtil.NULL, MemoryUtil.NULL); var vidMode = glfwGetVideoMode(glfwGetPrimaryMonitor());
if (windowHandle == MemoryUtil.NULL) throw new RuntimeException("Failed to create GLFW window."); 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) -> { glfwSetKeyCallback(windowHandle, (window, key, scancode, action, mods) -> {
if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE) { if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE) {
glfwSetWindowShouldClose(windowHandle, true); glfwSetWindowShouldClose(windowHandle, true);
@ -87,7 +88,7 @@ public class Aos2Client {
glfwSetInputMode(windowHandle, GLFW_CURSOR, GLFW_CURSOR_DISABLED); glfwSetInputMode(windowHandle, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
glfwSetInputMode(windowHandle, GLFW_RAW_MOUSE_MOTION, GLFW_TRUE); glfwSetInputMode(windowHandle, GLFW_RAW_MOUSE_MOTION, GLFW_TRUE);
glfwSetWindowPos(windowHandle, 50, 50); glfwSetWindowPos(windowHandle, 0, 0);
glfwSetCursorPos(windowHandle, 0, 0); glfwSetCursorPos(windowHandle, 0, 0);
glfwMakeContextCurrent(windowHandle); glfwMakeContextCurrent(windowHandle);
@ -101,6 +102,6 @@ public class Aos2Client {
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
glCullFace(GL_BACK); glCullFace(GL_BACK);
return windowHandle; return new WindowInfo(windowHandle, vidMode.width(), vidMode.height());
} }
} }

View File

@ -38,8 +38,18 @@ public class ChunkMesh {
* Generates and loads this chunk's mesh into the allocated OpenGL buffers. * Generates and loads this chunk's mesh into the allocated OpenGL buffers.
*/ */
private void loadMesh() { private void loadMesh() {
long start = System.nanoTime();
var meshData = ChunkMeshGenerator.generateMesh(chunk); var meshData = ChunkMeshGenerator.generateMesh(chunk);
double dur = (System.nanoTime() - start) / 1_000_000.0;
this.indiciesCount = meshData.indexBuffer().limit(); 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); glBindBuffer(GL_ARRAY_BUFFER, vboId);
glBufferData(GL_ARRAY_BUFFER, meshData.vertexBuffer(), GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, meshData.vertexBuffer(), GL_STATIC_DRAW);

View File

@ -9,6 +9,11 @@ import java.util.List;
import static org.lwjgl.opengl.GL46.*; 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 { public class ChunkRenderer {
private final ShaderProgram shaderProgram; private final ShaderProgram shaderProgram;
private final int projectionTransformUniform; private final int projectionTransformUniform;
@ -17,11 +22,12 @@ public class ChunkRenderer {
private final int chunkPositionUniform; private final int chunkPositionUniform;
private final int chunkSizeUniform; 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<ChunkMesh> chunkMeshes = new ArrayList<>(); private final List<ChunkMesh> 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() this.shaderProgram = new ShaderProgram.Builder()
.withShader("shader/chunk/vertex.glsl", GL_VERTEX_SHADER) .withShader("shader/chunk/vertex.glsl", GL_VERTEX_SHADER)
.withShader("shader/chunk/fragment.glsl", GL_FRAGMENT_SHADER) .withShader("shader/chunk/fragment.glsl", GL_FRAGMENT_SHADER)

View File

@ -0,0 +1,7 @@
package nl.andrewl.aos2_client.render;
public record WindowInfo(
long windowHandle,
int width,
int height
) {}

View File

@ -6,13 +6,19 @@ import org.joml.Vector3i;
import java.util.Random; 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 { public class Chunk {
/** /**
* The size of a chunk, in terms of the number of blocks on one axis of the cube. * The size of a chunk, in terms of the number of blocks on one axis of the cube.
*/ */
public static final int SIZE = 16; 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; public static final int TOTAL_SIZE = SIZE * SIZE * SIZE;
private final byte[] blocks = new byte[TOTAL_SIZE]; private final byte[] blocks = new byte[TOTAL_SIZE];