aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/makamys/neodymium/renderer/ChunkMesh.java
diff options
context:
space:
mode:
authormakamys <makamys@outlook.com>2022-07-11 22:55:20 +0200
committermakamys <makamys@outlook.com>2022-07-11 22:56:53 +0200
commitacdc0adecd3c8d649cad97c6932fb7ba418721e6 (patch)
tree9606d944818016067c1709825c92977323b6bb48 /src/main/java/makamys/neodymium/renderer/ChunkMesh.java
parentf26762ca0c6b7c1977f71ae24b3b011a658d7e53 (diff)
downloadNeodymium-acdc0adecd3c8d649cad97c6932fb7ba418721e6.tar.gz
Neodymium-acdc0adecd3c8d649cad97c6932fb7ba418721e6.tar.bz2
Neodymium-acdc0adecd3c8d649cad97c6932fb7ba418721e6.zip
Be able to capture chunk meshes consisting of multiple tessellations
Start of fix for #5
Diffstat (limited to 'src/main/java/makamys/neodymium/renderer/ChunkMesh.java')
-rw-r--r--src/main/java/makamys/neodymium/renderer/ChunkMesh.java74
1 files changed, 46 insertions, 28 deletions
diff --git a/src/main/java/makamys/neodymium/renderer/ChunkMesh.java b/src/main/java/makamys/neodymium/renderer/ChunkMesh.java
index c4956eb..a574765 100644
--- a/src/main/java/makamys/neodymium/renderer/ChunkMesh.java
+++ b/src/main/java/makamys/neodymium/renderer/ChunkMesh.java
@@ -1,5 +1,7 @@
package makamys.neodymium.renderer;
+import static makamys.neodymium.Neodymium.LOGGER;
+
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
@@ -8,6 +10,7 @@ import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import org.lwjgl.BufferUtils;
+import org.lwjgl.opengl.GL11;
import makamys.neodymium.config.Config;
import makamys.neodymium.ducks.IWorldRenderer;
@@ -22,7 +25,6 @@ import net.minecraft.tileentity.TileEntity;
/** A mesh for a 16x16x16 region of the world. */
public class ChunkMesh extends Mesh {
- Flags flags;
WorldRenderer wr;
private int[] subMeshStart = new int[NORMAL_ORDER.length];
@@ -32,10 +34,14 @@ public class ChunkMesh extends Mesh {
private static RecyclingList<MeshQuad> quadBuf = new RecyclingList<>(() -> new MeshQuad());
+ private static ChunkMesh meshCaptureTarget;
+
private static final QuadNormal[] NORMAL_ORDER = new QuadNormal[] {QuadNormal.NONE, QuadNormal.POSITIVE_Y, QuadNormal.POSITIVE_X, QuadNormal.POSITIVE_Z, QuadNormal.NEGATIVE_X, QuadNormal.NEGATIVE_Z, QuadNormal.NEGATIVE_Y};
private static final Comparator<MeshQuad> MESH_QUAD_RENDER_COMPARATOR = new MeshQuadRenderOrderComparator();
private static final int[] QUAD_NORMAL_TO_NORMAL_ORDER;
+ private static final Flags FLAGS = new Flags(true, true, true, false);
+
static {
QUAD_NORMAL_TO_NORMAL_ORDER = new int[QuadNormal.values().length];
for(int i = 0; i < QuadNormal.values().length; i++) {
@@ -47,39 +53,52 @@ public class ChunkMesh extends Mesh {
}
}
- public ChunkMesh(WorldRenderer wr, Flags flags, int quadCount, List<MeshQuad> quads, int pass) {
+ public ChunkMesh(WorldRenderer wr, int pass) {
this.x = wr.posX / 16;
this.y = wr.posY / 16;
this.z = wr.posZ / 16;
this.wr = wr;
- this.flags = flags;
- this.quadCount = quadCount;
this.pass = pass;
Arrays.fill(subMeshStart, -1);
- buffer = createBuffer(quads, quadCount);
- usedRAM += buffer.limit();
instances++;
+
+ if(!quadBuf.getAsList().isEmpty()) {
+ LOGGER.error("Invalid state: tried to construct a chunk mesh before the previous one has finished constructing!");
+ }
}
- public static ChunkMesh fromTessellator(int pass, WorldRenderer wr, Tessellator t) {
- if(t.vertexCount % 4 != 0) {
- System.out.println("Error: Vertex count is not a multiple of 4");
- return null;
+ public static void preTessellatorDraw(Tessellator t) {
+ if(meshCaptureTarget != null) {
+ meshCaptureTarget.addTessellatorData(t);
}
+ }
+
+ private void addTessellatorData(Tessellator t) {
+ // TODO triangle support
- int xOffset = wr.posX;
- int yOffset = wr.posY;
- int zOffset = wr.posZ;
-
- ChunkMesh.Flags flags = new ChunkMesh.Flags(t.hasTexture, t.hasBrightness, t.hasColor, t.hasNormals);
-
- quadBuf.reset();
+ if(t.vertexCount == 0) {
+ // Sometimes the tessellator has no vertices and weird flags. Don't warn in this case, just silently return.
+ return;
+ }
+ if(t.vertexCount % 4 != 0) {
+ LOGGER.error("Error: Vertex count is not a multiple of 4");
+ return;
+ }
+ if(t.drawMode != GL11.GL_QUADS) {
+ LOGGER.error("Error: Unsupported draw mode: " + t.drawMode);
+ }
+ if(!t.hasTexture || !t.hasBrightness || !t.hasColor || t.hasNormals) {
+ LOGGER.error("Error: Unsupported tessellator flags");
+ return;
+ }
for(int quadI = 0; quadI < t.vertexCount / 4; quadI++) {
- quadBuf.next().setState(t.rawBuffer, quadI * 32, flags, (float)-t.xOffset, (float)-t.yOffset, (float)-t.zOffset);
+ quadBuf.next().setState(t.rawBuffer, quadI * 32, FLAGS, (float)-t.xOffset, (float)-t.yOffset, (float)-t.zOffset);
}
-
+ }
+
+ public void finishConstruction() {
List<MeshQuad> quads = quadBuf.getAsList();
if(Config.simplifyChunkMeshes) {
@@ -110,16 +129,11 @@ public class ChunkMesh extends Mesh {
}
}
- int quadCount = countValidQuads(quads);
+ quadCount = countValidQuads(quads);
+ buffer = createBuffer(quads, quadCount);
+ usedRAM += buffer.limit();
- if(quadCount > 0) {
- return new ChunkMesh(
- wr,
- new ChunkMesh.Flags(t.hasTexture, t.hasBrightness, t.hasColor, t.hasNormals),
- quadCount, quads, pass);
- } else {
- return null;
- }
+ quadBuf.reset();
}
private static void simplifyPlane(List<MeshQuad> planeQuads) {
@@ -300,6 +314,10 @@ public class ChunkMesh extends Mesh {
return player.getDistanceSq(centerX, centerY, centerZ);
}
+ public static void setCaptureTarget(ChunkMesh cm) {
+ meshCaptureTarget = cm;
+ }
+
public static class Flags {
boolean hasTexture;
boolean hasBrightness;