|
@@ -0,0 +1,178 @@
|
|
|
+package me.hammerle.snuviengine.api;
|
|
|
+
|
|
|
+import java.io.IOException;
|
|
|
+import java.nio.FloatBuffer;
|
|
|
+import me.hammerle.snuviengine.util.WrappedInputStream;
|
|
|
+import me.hammerle.snuviengine.util.WrappedOutputStream;
|
|
|
+import org.lwjgl.BufferUtils;
|
|
|
+import static org.lwjgl.opengl.GL11.*;
|
|
|
+import static org.lwjgl.opengl.GL15.*;
|
|
|
+import static org.lwjgl.opengl.GL20.*;
|
|
|
+import static org.lwjgl.opengl.GL30.*;
|
|
|
+
|
|
|
+public class Chunk
|
|
|
+{
|
|
|
+ public final static int CHUNK_SIZE = 8;
|
|
|
+ public final static int TILE_SIZE = 16;
|
|
|
+ public final static int LAYERS = 4;
|
|
|
+ public final static int LAST_BACK_LAYER = 1;
|
|
|
+
|
|
|
+ private final short[][][] data = new short[LAYERS][CHUNK_SIZE][CHUNK_SIZE];
|
|
|
+ private final int chunkX;
|
|
|
+ private final int chunkY;
|
|
|
+
|
|
|
+ private int vao;
|
|
|
+ private int vbo;
|
|
|
+
|
|
|
+ private final FloatBuffer buffer = BufferUtils.createFloatBuffer(CHUNK_SIZE * CHUNK_SIZE * 24);
|
|
|
+
|
|
|
+ private boolean[] dirty = new boolean[LAYERS];
|
|
|
+
|
|
|
+ public Chunk(int x, int y)
|
|
|
+ {
|
|
|
+ this.chunkX = x;
|
|
|
+ this.chunkY = y;
|
|
|
+
|
|
|
+ for(int i = 0; i < LAYERS; i++)
|
|
|
+ {
|
|
|
+ dirty[i] = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ Shader.addTask(() ->
|
|
|
+ {
|
|
|
+ vao = glGenVertexArrays();
|
|
|
+ vbo = glGenBuffers();
|
|
|
+
|
|
|
+ GLHelper.glBindVertexArray(vao);
|
|
|
+ GLHelper.glBindBuffer(vbo);
|
|
|
+
|
|
|
+ glEnableVertexAttribArray(0);
|
|
|
+ glVertexAttribPointer(0, 2, GL_FLOAT, false, 16, 0);
|
|
|
+
|
|
|
+ glEnableVertexAttribArray(1);
|
|
|
+ glVertexAttribPointer(1, 2, GL_FLOAT, false, 16, 8);
|
|
|
+
|
|
|
+ glBufferData(GL_ARRAY_BUFFER, CHUNK_SIZE * CHUNK_SIZE * 96 * LAYERS, GL_STATIC_DRAW);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ public void read(WrappedInputStream in) throws IOException
|
|
|
+ {
|
|
|
+ for(int l = 0; l < LAYERS; l++)
|
|
|
+ {
|
|
|
+ for(int x = 0; x < CHUNK_SIZE; x++)
|
|
|
+ {
|
|
|
+ for(int y = 0; y < CHUNK_SIZE; y++)
|
|
|
+ {
|
|
|
+ data[l][x][y] = in.readShort();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void write(WrappedOutputStream out) throws IOException
|
|
|
+ {
|
|
|
+ for(int l = 0; l < LAYERS; l++)
|
|
|
+ {
|
|
|
+ for(int x = 0; x < CHUNK_SIZE; x++)
|
|
|
+ {
|
|
|
+ for(int y = 0; y < CHUNK_SIZE; y++)
|
|
|
+ {
|
|
|
+ out.writeShort(data[l][x][y]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void rebuild(int layer)
|
|
|
+ {
|
|
|
+ for(int x = 0; x < CHUNK_SIZE; x++)
|
|
|
+ {
|
|
|
+ for(int y = 0; y < CHUNK_SIZE; y++)
|
|
|
+ {
|
|
|
+ short tile = data[layer][x][y];
|
|
|
+ float minX = x * TILE_SIZE;
|
|
|
+ float minY = y * TILE_SIZE;
|
|
|
+ float maxX = minX + TILE_SIZE;
|
|
|
+ float maxY = minY + TILE_SIZE;
|
|
|
+ float tMinX = (tile % 8) * 0.125f;
|
|
|
+ float tMinY = (tile / 8) * 0.0108695652f;
|
|
|
+ float tMaxX = tMinX + 0.125f;
|
|
|
+ float tMaxY = tMinY + 0.0108695652f;
|
|
|
+
|
|
|
+ buffer.put(minX);
|
|
|
+ buffer.put(maxY);
|
|
|
+ buffer.put(tMinX);
|
|
|
+ buffer.put(tMaxY);
|
|
|
+
|
|
|
+ buffer.put(minX);
|
|
|
+ buffer.put(minY);
|
|
|
+ buffer.put(tMinX);
|
|
|
+ buffer.put(tMinY);
|
|
|
+
|
|
|
+ buffer.put(maxX);
|
|
|
+ buffer.put(maxY);
|
|
|
+ buffer.put(tMaxX);
|
|
|
+ buffer.put(tMaxY);
|
|
|
+
|
|
|
+ buffer.put(maxX);
|
|
|
+ buffer.put(maxY);
|
|
|
+ buffer.put(tMaxX);
|
|
|
+ buffer.put(tMaxY);
|
|
|
+
|
|
|
+ buffer.put(minX);
|
|
|
+ buffer.put(minY);
|
|
|
+ buffer.put(tMinX);
|
|
|
+ buffer.put(tMinY);
|
|
|
+
|
|
|
+ buffer.put(maxX);
|
|
|
+ buffer.put(minY);
|
|
|
+ buffer.put(tMaxX);
|
|
|
+ buffer.put(tMinY);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ buffer.flip();
|
|
|
+ GLHelper.glBindVertexArray(vao);
|
|
|
+ GLHelper.glBindBuffer(vbo);
|
|
|
+ glBufferSubData(GL_ARRAY_BUFFER, CHUNK_SIZE * CHUNK_SIZE * 96 * layer, buffer);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void drawBackground()
|
|
|
+ {
|
|
|
+ for(int i = 0; i <= LAST_BACK_LAYER; i++)
|
|
|
+ {
|
|
|
+ if(dirty[i])
|
|
|
+ {
|
|
|
+ rebuild(i);
|
|
|
+ dirty[i] = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ GLHelper.glBindVertexArray(vao);
|
|
|
+ GLHelper.glBindBuffer(vbo);
|
|
|
+ Shader.pushMatrix();
|
|
|
+ Shader.translate(chunkX * CHUNK_SIZE * TILE_SIZE, chunkY * CHUNK_SIZE * TILE_SIZE);
|
|
|
+ Shader.updateMatrix();
|
|
|
+ Shader.popMatrix();
|
|
|
+ glDrawArrays(GL_TRIANGLES, 0, CHUNK_SIZE * CHUNK_SIZE * 6 * (LAST_BACK_LAYER + 1));
|
|
|
+ }
|
|
|
+
|
|
|
+ public void drawForeground()
|
|
|
+ {
|
|
|
+ for(int i = LAST_BACK_LAYER + 1; i < LAYERS; i++)
|
|
|
+ {
|
|
|
+ if(dirty[i])
|
|
|
+ {
|
|
|
+ rebuild(i);
|
|
|
+ dirty[i] = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ GLHelper.glBindVertexArray(vao);
|
|
|
+ GLHelper.glBindBuffer(vbo);
|
|
|
+ Shader.pushMatrix();
|
|
|
+ Shader.translate(chunkX * CHUNK_SIZE * TILE_SIZE, chunkY * CHUNK_SIZE * TILE_SIZE);
|
|
|
+ Shader.updateMatrix();
|
|
|
+ Shader.popMatrix();
|
|
|
+ glDrawArrays(GL_TRIANGLES, CHUNK_SIZE * CHUNK_SIZE * 6 * (LAST_BACK_LAYER + 1), CHUNK_SIZE * CHUNK_SIZE * 6 * (LAYERS - LAST_BACK_LAYER - 1));
|
|
|
+ }
|
|
|
+}
|