Added camera and introduced lighting.
This commit is contained in:
		
							parent
							
								
									26881c1520
								
							
						
					
					
						commit
						c541e4e054
					
				| 
						 | 
					@ -13,12 +13,13 @@ import org.lwjgl.opengl.GLUtil;
 | 
				
			||||||
import org.lwjgl.system.MemoryUtil;
 | 
					import org.lwjgl.system.MemoryUtil;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.io.IOException;
 | 
					import java.io.IOException;
 | 
				
			||||||
 | 
					import java.util.Random;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import static org.lwjgl.glfw.GLFW.*;
 | 
					import static org.lwjgl.glfw.GLFW.*;
 | 
				
			||||||
import static org.lwjgl.opengl.GL46.*;
 | 
					import static org.lwjgl.opengl.GL46.*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class Aos2Client {
 | 
					public class Aos2Client {
 | 
				
			||||||
	public static void main(String[] args) throws IOException {
 | 
						public static void main(String[] args) throws IOException, InterruptedException {
 | 
				
			||||||
		System.out.println("LWJGL Version: " + Version.getVersion());
 | 
							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");
 | 
				
			||||||
| 
						 | 
					@ -34,7 +35,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, 50, 50);
 | 
				
			||||||
| 
						 | 
					@ -51,10 +52,15 @@ public class Aos2Client {
 | 
				
			||||||
		glEnable(GL_DEPTH_TEST);
 | 
							glEnable(GL_DEPTH_TEST);
 | 
				
			||||||
		glCullFace(GL_BACK);
 | 
							glCullFace(GL_BACK);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Chunk chunk = Chunk.of((byte) 64);
 | 
							Chunk chunk = Chunk.random(new Random(1));
 | 
				
			||||||
 | 
							Camera cam = new Camera();
 | 
				
			||||||
 | 
							cam.setPosition(0, 3, 0);
 | 
				
			||||||
 | 
							float angle = 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);
 | 
				
			||||||
		Matrix4f projectionTransform = new Matrix4f().perspective(70, 800 / 600.0f, 0.01f, 100.0f);
 | 
							Matrix4f projectionTransform = new Matrix4f().perspective(70, 800 / 600.0f, 0.01f, 100.0f);
 | 
				
			||||||
		Matrix4f viewTransform = new Matrix4f()
 | 
					 | 
				
			||||||
				.lookAt(new Vector3f(-5, 50, -10), new Vector3f(8, 0, 8), new Vector3f(0, 1, 0));
 | 
					 | 
				
			||||||
		ChunkMesh mesh = new ChunkMesh(chunk);
 | 
							ChunkMesh mesh = new ChunkMesh(chunk);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		int shaderProgram = createShaderProgram();
 | 
							int shaderProgram = createShaderProgram();
 | 
				
			||||||
| 
						 | 
					@ -66,12 +72,15 @@ public class Aos2Client {
 | 
				
			||||||
		while (!glfwWindowShouldClose(windowHandle)) {
 | 
							while (!glfwWindowShouldClose(windowHandle)) {
 | 
				
			||||||
			glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 | 
								glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			glUniformMatrix4fv(viewTransformUniform, false, viewTransform.get(new float[16]));
 | 
								glUniformMatrix4fv(viewTransformUniform, false, cam.getViewTransformData());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			mesh.draw();
 | 
								mesh.draw();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			glfwSwapBuffers(windowHandle);
 | 
								glfwSwapBuffers(windowHandle);
 | 
				
			||||||
			glfwPollEvents();
 | 
								glfwPollEvents();
 | 
				
			||||||
 | 
								angle += Math.PI / 48;
 | 
				
			||||||
 | 
								Thread.sleep(40);
 | 
				
			||||||
 | 
								cam.setOrientation((float) (Math.PI), 0);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Callbacks.glfwFreeCallbacks(windowHandle);
 | 
							Callbacks.glfwFreeCallbacks(windowHandle);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,9 @@
 | 
				
			||||||
 | 
					package nl.andrewl.aos2_client;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import org.joml.Vector3f;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public record BlockVertexData(
 | 
				
			||||||
 | 
							Vector3f position,
 | 
				
			||||||
 | 
							Vector3f color,
 | 
				
			||||||
 | 
							Vector3f normal
 | 
				
			||||||
 | 
					) {}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,41 @@
 | 
				
			||||||
 | 
					package nl.andrewl.aos2_client;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import nl.andrewl.aos_core.MathUtils;
 | 
				
			||||||
 | 
					import org.joml.Matrix4f;
 | 
				
			||||||
 | 
					import org.joml.Vector2f;
 | 
				
			||||||
 | 
					import org.joml.Vector3f;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class Camera {
 | 
				
			||||||
 | 
						private final Vector3f position;
 | 
				
			||||||
 | 
						private final Vector2f orientation;
 | 
				
			||||||
 | 
						private final Matrix4f viewTransform;
 | 
				
			||||||
 | 
						private final float[] viewTransformData = new float[16];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public Camera() {
 | 
				
			||||||
 | 
							this.position = new Vector3f();
 | 
				
			||||||
 | 
							this.orientation = new Vector2f();
 | 
				
			||||||
 | 
							this.viewTransform = new Matrix4f();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public float[] getViewTransformData() {
 | 
				
			||||||
 | 
							return viewTransformData;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public void setPosition(float x, float y, float z) {
 | 
				
			||||||
 | 
							position.set(x, y, z);
 | 
				
			||||||
 | 
							updateViewTransform();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public void setOrientation(float x, float y) {
 | 
				
			||||||
 | 
							orientation.set(MathUtils.normalize(x, 0, Math.PI * 2), MathUtils.normalize(y, 0, Math.PI * 2));
 | 
				
			||||||
 | 
							updateViewTransform();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private void updateViewTransform() {
 | 
				
			||||||
 | 
							viewTransform.identity();
 | 
				
			||||||
 | 
							viewTransform.rotate(-orientation.x, new Vector3f(1, 0, 0));
 | 
				
			||||||
 | 
							viewTransform.rotate(-orientation.y, new Vector3f(0, 1, 0));
 | 
				
			||||||
 | 
							viewTransform.translate(position.x, position.y, position.z);
 | 
				
			||||||
 | 
							viewTransform.get(viewTransformData);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1,10 +1,12 @@
 | 
				
			||||||
package nl.andrewl.aos2_client;
 | 
					package nl.andrewl.aos2_client;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import nl.andrewl.aos_core.Pair;
 | 
				
			||||||
import nl.andrewl.aos_core.model.Chunk;
 | 
					import nl.andrewl.aos_core.model.Chunk;
 | 
				
			||||||
import org.lwjgl.BufferUtils;
 | 
					import org.joml.Vector3f;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.nio.FloatBuffer;
 | 
					import java.util.ArrayList;
 | 
				
			||||||
import java.nio.IntBuffer;
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					import java.util.stream.Stream;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import static org.lwjgl.opengl.GL46.*;
 | 
					import static org.lwjgl.opengl.GL46.*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,31 +22,130 @@ public class ChunkMesh {
 | 
				
			||||||
		this.vaoId = glGenVertexArrays();
 | 
							this.vaoId = glGenVertexArrays();
 | 
				
			||||||
		this.eboId = glGenBuffers();
 | 
							this.eboId = glGenBuffers();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		var meshData = chunk.generateMesh();
 | 
							long start = System.currentTimeMillis();
 | 
				
			||||||
		System.out.println(meshData.first().size());
 | 
							var meshData = generateMesh(chunk);
 | 
				
			||||||
		FloatBuffer vertexBuffer = BufferUtils.createFloatBuffer(3 * meshData.first().size());
 | 
							long dur = System.currentTimeMillis() - start;
 | 
				
			||||||
		for (var vertex : meshData.first()) {
 | 
							System.out.println("Generated chunk mesh in " + dur + " ms");
 | 
				
			||||||
			vertexBuffer.put(vertex.x);
 | 
							this.indiciesCount = meshData.second().length;
 | 
				
			||||||
			vertexBuffer.put(vertex.y);
 | 
					 | 
				
			||||||
			vertexBuffer.put(vertex.z);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		vertexBuffer.flip();
 | 
					 | 
				
			||||||
		IntBuffer indexBuffer = BufferUtils.createIntBuffer(meshData.second().size());
 | 
					 | 
				
			||||||
		for (var index : meshData.second()) {
 | 
					 | 
				
			||||||
			indexBuffer.put(index);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		indexBuffer.flip();
 | 
					 | 
				
			||||||
		this.indiciesCount = meshData.second().size();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		glBindBuffer(GL_ARRAY_BUFFER, vboId);
 | 
							glBindBuffer(GL_ARRAY_BUFFER, vboId);
 | 
				
			||||||
		glBufferData(GL_ARRAY_BUFFER, vertexBuffer, GL_STATIC_DRAW);
 | 
							glBufferData(GL_ARRAY_BUFFER, meshData.first(), GL_STATIC_DRAW);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, eboId);
 | 
							glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, eboId);
 | 
				
			||||||
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexBuffer, GL_STATIC_DRAW);
 | 
							glBufferData(GL_ELEMENT_ARRAY_BUFFER, meshData.second(), GL_STATIC_DRAW);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		glBindVertexArray(vaoId);
 | 
							glBindVertexArray(vaoId);
 | 
				
			||||||
 | 
							// Vertex position floats.
 | 
				
			||||||
		glEnableVertexAttribArray(0);
 | 
							glEnableVertexAttribArray(0);
 | 
				
			||||||
		glVertexAttribPointer(0, 3, GL_FLOAT, false, 3 * Float.BYTES, 0);
 | 
							glVertexAttribPointer(0, 3, GL_FLOAT, false, 9 * Float.BYTES, 0);
 | 
				
			||||||
 | 
							// Vertex color floats.
 | 
				
			||||||
 | 
							glEnableVertexAttribArray(1);
 | 
				
			||||||
 | 
							glVertexAttribPointer(1, 3, GL_FLOAT, false, 9 * Float.BYTES, 3 * Float.BYTES);
 | 
				
			||||||
 | 
							// Vertex normal floats.
 | 
				
			||||||
 | 
							glEnableVertexAttribArray(2);
 | 
				
			||||||
 | 
							glVertexAttribPointer(2, 3, GL_FLOAT, false, 9 * Float.BYTES, 6 * Float.BYTES);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private Pair<float[], int[]> generateMesh(Chunk c) {
 | 
				
			||||||
 | 
							List<BlockVertexData> vertexList = new ArrayList<>();
 | 
				
			||||||
 | 
							List<Integer> indexList = new ArrayList<>();
 | 
				
			||||||
 | 
							int idx = 0;
 | 
				
			||||||
 | 
							for (int x = 0; x < Chunk.SIZE; x++) {
 | 
				
			||||||
 | 
								for (int y = 0; y < Chunk.SIZE; y++) {
 | 
				
			||||||
 | 
									for (int z = 0; z < Chunk.SIZE; z++) {
 | 
				
			||||||
 | 
										byte block = c.getBlockAt(x, y, z);
 | 
				
			||||||
 | 
										if (block == 0) continue;
 | 
				
			||||||
 | 
										Vector3f color = Chunk.getColor(block);
 | 
				
			||||||
 | 
										var A = new Vector3f(x, y + 1, z);
 | 
				
			||||||
 | 
										var B = new Vector3f(x, y + 1, z + 1);
 | 
				
			||||||
 | 
										var C = new Vector3f(x + 1, y + 1, z + 1);
 | 
				
			||||||
 | 
										var D = new Vector3f(x + 1, y + 1, z);
 | 
				
			||||||
 | 
										var E = new Vector3f(x, y, z);
 | 
				
			||||||
 | 
										var F = new Vector3f(x, y, z + 1);
 | 
				
			||||||
 | 
										var G = new Vector3f(x + 1, y, z + 1);
 | 
				
			||||||
 | 
										var H = new Vector3f(x + 1, y, z);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										// Top
 | 
				
			||||||
 | 
										if (c.getBlockAt(x, y + 1, z) == 0) {
 | 
				
			||||||
 | 
											var norm = new Vector3f(0, 1, 0);
 | 
				
			||||||
 | 
											vertexList.addAll(Stream.of(A, B, C, D).map(v -> new BlockVertexData(v, color, norm)).toList());
 | 
				
			||||||
 | 
											indexList.addAll(List.of(
 | 
				
			||||||
 | 
													idx, idx + 1, idx + 3,
 | 
				
			||||||
 | 
													idx + 3, idx + 1, idx + 2
 | 
				
			||||||
 | 
											));
 | 
				
			||||||
 | 
											idx += 4;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										// Bottom
 | 
				
			||||||
 | 
										if (c.getBlockAt(x, y - 1, z) == 0) {
 | 
				
			||||||
 | 
											var norm = new Vector3f(0, -1, 0);
 | 
				
			||||||
 | 
											vertexList.addAll(Stream.of(E, F, G, H).map(v -> new BlockVertexData(v, color, norm)).toList());
 | 
				
			||||||
 | 
											indexList.addAll(List.of(
 | 
				
			||||||
 | 
													idx + 3, idx + 1, idx,
 | 
				
			||||||
 | 
													idx + 1, idx + 3, idx + 2
 | 
				
			||||||
 | 
											));
 | 
				
			||||||
 | 
											idx += 4;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										// Positive z
 | 
				
			||||||
 | 
										if (c.getBlockAt(x, y, z + 1) == 0) {
 | 
				
			||||||
 | 
											var norm = new Vector3f(0, 0, 1);
 | 
				
			||||||
 | 
											vertexList.addAll(Stream.of(B, F, G, C).map(v -> new BlockVertexData(v, color, norm)).toList());
 | 
				
			||||||
 | 
											indexList.addAll(List.of(
 | 
				
			||||||
 | 
													idx + 3, idx, idx + 1,
 | 
				
			||||||
 | 
													idx + 3, idx + 1, idx + 2
 | 
				
			||||||
 | 
											));
 | 
				
			||||||
 | 
											idx += 4;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										// Negative z
 | 
				
			||||||
 | 
										if (c.getBlockAt(x, y, z - 1) == 0) {
 | 
				
			||||||
 | 
											var norm = new Vector3f(0, 0, -1);
 | 
				
			||||||
 | 
											vertexList.addAll(Stream.of(A, E, H, D).map(v -> new BlockVertexData(v, color, norm)).toList());
 | 
				
			||||||
 | 
											indexList.addAll(List.of(
 | 
				
			||||||
 | 
													idx, idx + 3, idx + 2,
 | 
				
			||||||
 | 
													idx + 2, idx + 1, idx
 | 
				
			||||||
 | 
											));
 | 
				
			||||||
 | 
											idx += 4;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										// Positive x
 | 
				
			||||||
 | 
										if (c.getBlockAt(x + 1, y, z) == 0) {
 | 
				
			||||||
 | 
											var norm = new Vector3f(1, 0, 0);
 | 
				
			||||||
 | 
											vertexList.addAll(Stream.of(C, G, H, D).map(v -> new BlockVertexData(v, color, norm)).toList());
 | 
				
			||||||
 | 
											indexList.addAll(List.of(
 | 
				
			||||||
 | 
													idx + 3, idx, idx + 1,
 | 
				
			||||||
 | 
													idx + 3, idx + 1, idx + 2
 | 
				
			||||||
 | 
											));
 | 
				
			||||||
 | 
											idx += 4;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										// Negative x
 | 
				
			||||||
 | 
										if (c.getBlockAt(x - 1, y, z) == 0) {
 | 
				
			||||||
 | 
											var norm = new Vector3f(-1, 0, 0);
 | 
				
			||||||
 | 
											vertexList.addAll(Stream.of(A, E, F, B).map(v -> new BlockVertexData(v, color, norm)).toList());
 | 
				
			||||||
 | 
											indexList.addAll(List.of(
 | 
				
			||||||
 | 
													idx + 3, idx, idx + 1,
 | 
				
			||||||
 | 
													idx + 3, idx + 1, idx + 2
 | 
				
			||||||
 | 
											));
 | 
				
			||||||
 | 
											idx += 4;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							float[] vertexData = new float[9 * vertexList.size()];
 | 
				
			||||||
 | 
							int vertexDataIdx = 0;
 | 
				
			||||||
 | 
							for (var vertex : vertexList) {
 | 
				
			||||||
 | 
								vertexData[vertexDataIdx++] = vertex.position().x;
 | 
				
			||||||
 | 
								vertexData[vertexDataIdx++] = vertex.position().y;
 | 
				
			||||||
 | 
								vertexData[vertexDataIdx++] = vertex.position().z;
 | 
				
			||||||
 | 
								vertexData[vertexDataIdx++] = vertex.color().x;
 | 
				
			||||||
 | 
								vertexData[vertexDataIdx++] = vertex.color().y;
 | 
				
			||||||
 | 
								vertexData[vertexDataIdx++] = vertex.color().z;
 | 
				
			||||||
 | 
								vertexData[vertexDataIdx++] = vertex.normal().x;
 | 
				
			||||||
 | 
								vertexData[vertexDataIdx++] = vertex.normal().y;
 | 
				
			||||||
 | 
								vertexData[vertexDataIdx++] = vertex.normal().z;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							int[] indexData = indexList.stream().mapToInt(v -> v).toArray();
 | 
				
			||||||
 | 
							System.out.printf("Generated chunk mesh: %d vertices, %d indexes%n", vertexList.size(), indexData.length);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return new Pair<>(vertexData, indexData);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public void draw() {
 | 
						public void draw() {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,9 +2,18 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
in vec3 vertexPosition;
 | 
					in vec3 vertexPosition;
 | 
				
			||||||
in vec3 vertexColor;
 | 
					in vec3 vertexColor;
 | 
				
			||||||
 | 
					in vec3 vertexNormal;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
out vec4 fragmentColor;
 | 
					out vec4 fragmentColor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void main() {
 | 
					void main() {
 | 
				
			||||||
    fragmentColor = vec4(vertexColor, 1.0);
 | 
					    vec3 lightDirection = vec3(0.0, -1.0, -0.5);// TODO: Add this via a uniform.
 | 
				
			||||||
 | 
					    vec3 lightColor = vec3(1.0, 1.0, 0.9); // TODO: Add this via a uniform.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    vec3 ambientComponent = vec3(0.1, 0.1, 0.1);
 | 
				
			||||||
 | 
					    vec3 diffuseComponent = max(dot(vertexNormal, lightDirection), 0.0) * lightColor;
 | 
				
			||||||
 | 
					    // No specular component.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fragmentColor = vec4((ambientComponent + diffuseComponent) * vertexColor, 1.0);
 | 
				
			||||||
 | 
					    //fragmentColor = vec4((vertexNormal + 1) / 2.0, 1.0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1,15 +1,20 @@
 | 
				
			||||||
#version 460 core
 | 
					#version 460 core
 | 
				
			||||||
 | 
					
 | 
				
			||||||
layout (location = 0) in vec3 vertexPositionIn;
 | 
					layout (location = 0) in vec3 vertexPositionIn;
 | 
				
			||||||
 | 
					layout (location = 1) in vec3 vertexColorIn;
 | 
				
			||||||
 | 
					layout (location = 2) in vec3 vertexNormalIn;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
uniform mat4 projectionTransform;
 | 
					uniform mat4 projectionTransform;
 | 
				
			||||||
uniform mat4 viewTransform;
 | 
					uniform mat4 viewTransform;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
out vec3 vertexPosition;
 | 
					out vec3 vertexPosition;
 | 
				
			||||||
out vec3 vertexColor;
 | 
					out vec3 vertexColor;
 | 
				
			||||||
 | 
					out vec3 vertexNormal;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void main() {
 | 
					void main() {
 | 
				
			||||||
 | 
					    // TODO: Add model transform uniform.
 | 
				
			||||||
    gl_Position = projectionTransform * viewTransform * vec4(vertexPositionIn, 1.0);
 | 
					    gl_Position = projectionTransform * viewTransform * vec4(vertexPositionIn, 1.0);
 | 
				
			||||||
    vertexPosition = vertexPositionIn;
 | 
					    vertexPosition = vertexPositionIn;
 | 
				
			||||||
    vertexColor = vec3(1.0, 0.5, 0.5);
 | 
					    vertexColor = vertexColorIn;
 | 
				
			||||||
 | 
					    vertexNormal = vertexNormalIn;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,9 @@
 | 
				
			||||||
 | 
					package nl.andrewl.aos_core;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class MathUtils {
 | 
				
			||||||
 | 
						public static double normalize(double value, double start, double end) {
 | 
				
			||||||
 | 
							final double width = end - start;
 | 
				
			||||||
 | 
							final double offsetValue = value - start;
 | 
				
			||||||
 | 
							return offsetValue - (Math.floor(offsetValue / width) * width) + start;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1,87 +1,53 @@
 | 
				
			||||||
package nl.andrewl.aos_core.model;
 | 
					package nl.andrewl.aos_core.model;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import nl.andrewl.aos_core.Pair;
 | 
					 | 
				
			||||||
import org.joml.Vector3f;
 | 
					import org.joml.Vector3f;
 | 
				
			||||||
import org.joml.Vector3i;
 | 
					import org.joml.Vector3i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.ArrayList;
 | 
					 | 
				
			||||||
import java.util.Arrays;
 | 
					import java.util.Arrays;
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.Random;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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 byte SIZE = 16;
 | 
						public static final int SIZE = 16;
 | 
				
			||||||
 | 
						public static final int TOTAL_SIZE = SIZE * SIZE * SIZE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private final byte[] blocks = new byte[SIZE * SIZE * SIZE];
 | 
						private final byte[] blocks = new byte[TOTAL_SIZE];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public byte getBlockAt(int x, int y, int z) {
 | 
						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;
 | 
							int idx = x * SIZE * SIZE + y * SIZE + z;
 | 
				
			||||||
		if (idx < 0 || idx >= SIZE * SIZE * SIZE) return 0;
 | 
							return blocks[idx];
 | 
				
			||||||
		return blocks[x * SIZE * SIZE + y * SIZE + z];
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public byte getBlockAt(Vector3i localPosition) {
 | 
						public byte getBlockAt(Vector3i localPosition) {
 | 
				
			||||||
		return getBlockAt(localPosition.x, localPosition.y, localPosition.z);
 | 
							return getBlockAt(localPosition.x, localPosition.y, localPosition.z);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public void setBlockAt(int x, int y, int z, byte value) {
 | 
				
			||||||
 | 
							if (x < 0 || x >= SIZE || y < 0 || y >= SIZE || z < 0 || z >= SIZE) return;
 | 
				
			||||||
 | 
							int idx = x * SIZE * SIZE + y * SIZE + z;
 | 
				
			||||||
 | 
							blocks[idx] = value;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public byte[] getBlocks() {
 | 
						public byte[] getBlocks() {
 | 
				
			||||||
		return blocks;
 | 
							return blocks;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public Pair<List<Vector3f>, List<Integer>> generateMesh() {
 | 
						@Override
 | 
				
			||||||
		List<Vector3f> vertexList = new ArrayList<>();
 | 
						public String toString() {
 | 
				
			||||||
		List<Integer> indexList = new ArrayList<>();
 | 
							StringBuilder sb = new StringBuilder();
 | 
				
			||||||
		int elementIdx = 0;
 | 
							for (int y = 0; y < SIZE; y++) {
 | 
				
			||||||
		for (int x = 0; x < SIZE; x++) {
 | 
								sb.append("y=").append(y).append('\n');
 | 
				
			||||||
			for (int y = 0; y < SIZE; y++) {
 | 
								for (int z = 0; z < SIZE; z++) {
 | 
				
			||||||
				for (int z = 0; z < SIZE; z++) {
 | 
									for (int x = 0; x < SIZE; x++) {
 | 
				
			||||||
					byte block = getBlockAt(x, y, z);
 | 
										sb.append(String.format("%02X ", getBlockAt(x, y, z)));
 | 
				
			||||||
					if (block == 0) continue;
 | 
					 | 
				
			||||||
					// Top
 | 
					 | 
				
			||||||
					if (getBlockAt(x, y + 1, z) == 0) {
 | 
					 | 
				
			||||||
						vertexList.add(new Vector3f(x + 1, y, z));       // 0
 | 
					 | 
				
			||||||
						vertexList.add(new Vector3f(x, y, z));              // 1
 | 
					 | 
				
			||||||
						vertexList.add(new Vector3f(x, y, z + 1));       // 2
 | 
					 | 
				
			||||||
						vertexList.add(new Vector3f(x + 1, y, z + 1));// 3
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
						indexList.add(elementIdx);
 | 
					 | 
				
			||||||
						indexList.add(elementIdx + 1);
 | 
					 | 
				
			||||||
						indexList.add(elementIdx + 2);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
						indexList.add(elementIdx + 2);
 | 
					 | 
				
			||||||
						indexList.add(elementIdx + 3);
 | 
					 | 
				
			||||||
						indexList.add(elementIdx);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
						elementIdx += 4;
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
					// Bottom
 | 
					 | 
				
			||||||
					if (getBlockAt(x, y - 1, z) == 0) {
 | 
					 | 
				
			||||||
						vertexList.add(new Vector3f(x + 1, y - 1, z));       // 0
 | 
					 | 
				
			||||||
						vertexList.add(new Vector3f(x, y - 1, z));              // 1
 | 
					 | 
				
			||||||
						vertexList.add(new Vector3f(x, y - 1, z + 1));       // 2
 | 
					 | 
				
			||||||
						vertexList.add(new Vector3f(x + 1, y - 1, z + 1));// 3
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
						indexList.add(elementIdx);
 | 
					 | 
				
			||||||
						indexList.add(elementIdx + 2);
 | 
					 | 
				
			||||||
						indexList.add(elementIdx + 1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
						indexList.add(elementIdx);
 | 
					 | 
				
			||||||
						indexList.add(elementIdx + 3);
 | 
					 | 
				
			||||||
						indexList.add(elementIdx + 2);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
						elementIdx += 4;
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
					// Positive z
 | 
					 | 
				
			||||||
					// Negative z
 | 
					 | 
				
			||||||
					// Positive x
 | 
					 | 
				
			||||||
					// Negative x
 | 
					 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
									sb.append('\n');
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							return sb.toString();
 | 
				
			||||||
		return new Pair<>(vertexList, indexList);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public static Chunk of(byte value) {
 | 
						public static Chunk of(byte value) {
 | 
				
			||||||
| 
						 | 
					@ -90,8 +56,16 @@ public class Chunk {
 | 
				
			||||||
		return c;
 | 
							return c;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public static Chunk random(Random rand) {
 | 
				
			||||||
 | 
							Chunk c = new Chunk();
 | 
				
			||||||
 | 
							for (int i = 0; i < TOTAL_SIZE; i++) {
 | 
				
			||||||
 | 
								c.blocks[i] = (byte) rand.nextInt(1, 128);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return c;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public static Vector3f getColor(byte blockValue) {
 | 
						public static Vector3f getColor(byte blockValue) {
 | 
				
			||||||
		float v = blockValue / 128.0f;
 | 
							float v = blockValue / 127.0f;
 | 
				
			||||||
		return new Vector3f(v);
 | 
							return new Vector3f(v);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue