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 53d2d27..d8e0869 100644 --- a/client/src/main/java/nl/andrewl/aos2_client/Aos2Client.java +++ b/client/src/main/java/nl/andrewl/aos2_client/Aos2Client.java @@ -18,24 +18,30 @@ public class Aos2Client { public static void main(String[] args) { long windowHandle = initUI(); - Chunk chunk = Chunk.random(new Vector3i(0, 0, 0), new Random(1)); Camera cam = new Camera(); glfwSetCursorPosCallback(windowHandle, cam); + Chunk chunk = Chunk.random(new Vector3i(0, 0, 0), new Random(1)); for (int i = 0; i < 16; i++) { chunk.setBlockAt(i, 0, 0, (byte) 8); chunk.setBlockAt(0, i, 0, (byte) 40); chunk.setBlockAt(0, 0, i, (byte) 120); } - chunk.setBlockAt(0, 15, 0, (byte) 0); - chunk.setBlockAt(1, 15, 0, (byte) 0); - chunk.setBlockAt(2, 15, 0, (byte) 0); - chunk.setBlockAt(2, 15, 1, (byte) 0); - chunk.setBlockAt(0, 0, 0, (byte) 0); +// chunk.setBlockAt(0, 15, 0, (byte) 0); +// chunk.setBlockAt(1, 15, 0, (byte) 0); +// chunk.setBlockAt(2, 15, 0, (byte) 0); +// chunk.setBlockAt(2, 15, 1, (byte) 0); +// chunk.setBlockAt(0, 0, 0, (byte) 0); + Chunk chunk2 = Chunk.random(new Vector3i(1, 0, 0), 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)); ChunkRenderer chunkRenderer = new ChunkRenderer(); - ChunkMesh mesh = new ChunkMesh(chunk); - chunkRenderer.addChunkMesh(mesh); + + chunkRenderer.addChunkMesh(new ChunkMesh(chunk2)); + chunkRenderer.addChunkMesh(new ChunkMesh(chunk3)); + chunkRenderer.addChunkMesh(new ChunkMesh(chunk4)); + chunkRenderer.addChunkMesh(new ChunkMesh(chunk)); while (!glfwWindowShouldClose(windowHandle)) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); diff --git a/client/src/main/java/nl/andrewl/aos2_client/ChunkMesh.java b/client/src/main/java/nl/andrewl/aos2_client/ChunkMesh.java index 73ef676..e14f44f 100644 --- a/client/src/main/java/nl/andrewl/aos2_client/ChunkMesh.java +++ b/client/src/main/java/nl/andrewl/aos2_client/ChunkMesh.java @@ -3,6 +3,7 @@ package nl.andrewl.aos2_client; import nl.andrewl.aos_core.Pair; import nl.andrewl.aos_core.model.Chunk; import org.joml.Vector3f; +import org.joml.Vector3i; import java.util.ArrayList; import java.util.List; @@ -10,14 +11,20 @@ import java.util.stream.Stream; import static org.lwjgl.opengl.GL46.*; +/** + * Represents a 3d mesh for a chunk. + */ public class ChunkMesh { private final int vboId; private final int vaoId; private final int eboId; - private final int indiciesCount; + private int indiciesCount; + + private final int[] positionData; public ChunkMesh(Chunk chunk) { + this.positionData = new int[]{chunk.getPosition().x, chunk.getPosition().y, chunk.getPosition().z}; this.vboId = glGenBuffers(); this.vaoId = glGenVertexArrays(); this.eboId = glGenBuffers(); @@ -148,6 +155,10 @@ public class ChunkMesh { return new Pair<>(vertexData, indexData); } + public int[] getPositionData() { + return positionData; + } + public void draw() { // Bind elements. glBindBuffer(GL_ARRAY_BUFFER, vboId); diff --git a/client/src/main/java/nl/andrewl/aos2_client/ChunkRenderer.java b/client/src/main/java/nl/andrewl/aos2_client/ChunkRenderer.java index c7eb9a4..5c96f41 100644 --- a/client/src/main/java/nl/andrewl/aos2_client/ChunkRenderer.java +++ b/client/src/main/java/nl/andrewl/aos2_client/ChunkRenderer.java @@ -13,6 +13,7 @@ public class ChunkRenderer { private final int projectionTransformUniform; private final int viewTransformUniform; private final int normalTransformUniform; + private final int chunkPositionUniform; private final Matrix4f projectionTransform = new Matrix4f().perspective(70, 800 / 600.0f, 0.01f, 100.0f); @@ -27,6 +28,7 @@ public class ChunkRenderer { this.projectionTransformUniform = shaderProgram.getUniform("projectionTransform"); this.viewTransformUniform = shaderProgram.getUniform("viewTransform"); this.normalTransformUniform = shaderProgram.getUniform("normalTransform"); + this.chunkPositionUniform = shaderProgram.getUniform("chunkPosition"); // Preemptively load projection transform, which doesn't change much. glUniformMatrix4fv(projectionTransformUniform, false, projectionTransform.get(new float[16])); @@ -42,7 +44,11 @@ public class ChunkRenderer { glUniformMatrix3fv(normalTransformUniform, false, normalTransform.get(new float[9])); shaderProgram.use(); - for (var mesh : chunkMeshes) mesh.draw(); + for (var mesh : chunkMeshes) { + // For each chunk, specify its position so that the shaders can draw it offset. + glUniform3iv(chunkPositionUniform, mesh.getPositionData()); + mesh.draw(); + } } public void free() { diff --git a/client/src/main/resources/shader/chunk/vertex.glsl b/client/src/main/resources/shader/chunk/vertex.glsl index fc0580c..0aa5b5d 100644 --- a/client/src/main/resources/shader/chunk/vertex.glsl +++ b/client/src/main/resources/shader/chunk/vertex.glsl @@ -7,15 +7,17 @@ layout (location = 2) in vec3 vertexNormalIn; uniform mat4 projectionTransform; uniform mat4 viewTransform; uniform mat3 normalTransform; +uniform ivec3 chunkPosition; out vec3 vertexPosition; out vec3 vertexColor; out vec3 vertexNormal; void main() { - // TODO: Add model transform uniform. - gl_Position = projectionTransform * viewTransform * vec4(vertexPositionIn, 1.0); - vertexPosition = vertexPositionIn; + vec3 realVertexPosition = vertexPositionIn + (chunkPosition * 16); + + gl_Position = projectionTransform * viewTransform * vec4(realVertexPosition, 1.0); + vertexPosition = realVertexPosition; vertexColor = vertexColorIn; vertexNormal = normalize(normalTransform * vertexNormalIn); } 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 024ab46..3773fe4 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 @@ -3,7 +3,6 @@ package nl.andrewl.aos_core.model; import org.joml.Vector3f; import org.joml.Vector3i; -import java.util.Arrays; import java.util.Random; /** @@ -32,6 +31,10 @@ public class Chunk { System.arraycopy(other.blocks, 0, this.blocks, 0, TOTAL_SIZE); } + public Vector3i getPosition() { + return position; + } + public byte getBlockAt(int x, int y, int z) { if (x < 0 || x >= SIZE || y < 0 || y >= SIZE || z < 0 || z >= SIZE) return 0; int idx = x * SIZE * SIZE + y * SIZE + z;