aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authormakamys <makamys@outlook.com>2022-06-06 23:13:42 +0200
committermakamys <makamys@outlook.com>2022-06-07 01:24:22 +0200
commit9886fb39669fd7b4fe2a6f109897be2244813586 (patch)
treeaafda6ebadba60f580c16f3bf982403e3623bf0a /src/main/java
parentfd1ab256fc8a88affaacb71095e55318f0289036 (diff)
downloadNeodymium-9886fb39669fd7b4fe2a6f109897be2244813586.tar.gz
Neodymium-9886fb39669fd7b4fe2a6f109897be2244813586.tar.bz2
Neodymium-9886fb39669fd7b4fe2a6f109897be2244813586.zip
Don't use MeshQuads when mesh optimization is disabled
Fixes some rendering issues (like cacti on chunk corners, and missing bottom faces) and improves performance, when optimization is not enabled.
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/makamys/lodmod/LODMod.java4
-rw-r--r--src/main/java/makamys/lodmod/renderer/ChunkMesh.java147
-rw-r--r--src/main/java/makamys/lodmod/util/BufferWriter.java46
-rw-r--r--src/main/java/makamys/lodmod/util/Util.java6
4 files changed, 147 insertions, 56 deletions
diff --git a/src/main/java/makamys/lodmod/LODMod.java b/src/main/java/makamys/lodmod/LODMod.java
index 8cb07bd..1366a09 100644
--- a/src/main/java/makamys/lodmod/LODMod.java
+++ b/src/main/java/makamys/lodmod/LODMod.java
@@ -216,10 +216,6 @@ public class LODMod
fogEventWasPosted = true;
}
- public static void debugHookToChunkMeshEnd() {
-
- }
-
public static boolean shouldRenderVanillaWorld() {
return !isActive() || (isActive() && renderer.renderWorld && !renderer.rendererActive);
}
diff --git a/src/main/java/makamys/lodmod/renderer/ChunkMesh.java b/src/main/java/makamys/lodmod/renderer/ChunkMesh.java
index 928f63b..9721b44 100644
--- a/src/main/java/makamys/lodmod/renderer/ChunkMesh.java
+++ b/src/main/java/makamys/lodmod/renderer/ChunkMesh.java
@@ -17,6 +17,7 @@ import org.lwjgl.BufferUtils;
import makamys.lodmod.LODMod;
import makamys.lodmod.MixinConfigPlugin;
import makamys.lodmod.ducks.IWorldRenderer;
+import makamys.lodmod.util.BufferWriter;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.WorldRenderer;
@@ -31,15 +32,13 @@ public class ChunkMesh extends Mesh {
Flags flags;
- NBTBase nbtData;
-
// TODO move this somewhere else
List<String> nameList = (List<String>) ((TextureMap)Minecraft.getMinecraft().getTextureManager().getTexture(TextureMap.locationBlocksTexture)).mapUploadedSprites.keySet().stream().collect(Collectors.toList());
public static int usedRAM = 0;
public static int instances = 0;
- public ChunkMesh(int x, int y, int z, Flags flags, int quadCount, byte[] data, List<String> stringTable, int pass) {
+ public ChunkMesh(int x, int y, int z, Flags flags, int quadCount, ByteBuffer buffer, int pass) {
this.x = x;
this.y = y;
this.z = z;
@@ -47,7 +46,8 @@ public class ChunkMesh extends Mesh {
this.quadCount = quadCount;
this.pass = pass;
- this.nbtData = new NBTTagByteArray(data);
+ this.buffer = buffer;
+ usedRAM += buffer.limit();
instances++;
}
@@ -59,7 +59,9 @@ public class ChunkMesh extends Mesh {
this.quadCount = quadCount;
this.pass = pass;
- this.nbtData = toNBT(quads, quadCount);
+ NBTBase nbtData = toNBT(quads, quadCount);
+ buffer = createBuffer(((NBTTagByteArray)nbtData).func_150292_c(), nameList);
+ usedRAM += buffer.limit();
instances++;
}
@@ -72,26 +74,34 @@ public class ChunkMesh extends Mesh {
return null;
}
- List<MeshQuad> quads = new ArrayList<>();
-
int xOffset = wr.posX;
int yOffset = wr.posY;
int zOffset = wr.posZ;
- for(int quadI = 0; quadI < t.vertexCount / 4; quadI++) {
- boolean fr = MixinConfigPlugin.isOptiFinePresent() && LODMod.ofFastRender;
- MeshQuad quad = new MeshQuad(t.rawBuffer, quadI * 32, new ChunkMesh.Flags(t.hasTexture, t.hasBrightness, t.hasColor, t.hasNormals), fr ? xOffset : 0, fr ? yOffset : 0, fr ? zOffset : 0);
- /*if(quad.bUs[0] == quad.bUs[1] && quad.bUs[1] == quad.bUs[2] && quad.bUs[2] == quad.bUs[3] && quad.bUs[3] == quad.bVs[0] && quad.bVs[0] == quad.bVs[1] && quad.bVs[1] == quad.bVs[2] && quad.bVs[2] == quad.bVs[3] && quad.bVs[3] == 0) {
- quad.deleted = true;
- }*/
- if(quad.plane == quad.PLANE_XZ && !quad.isClockwiseXZ()) {
- // water hack
- quad.deleted = true;
- }
- quads.add(quad);
- }
+ boolean fr = MixinConfigPlugin.isOptiFinePresent() && LODMod.ofFastRender;
+ int tessellatorXOffset = fr ? xOffset : 0;
+ int tessellatorYOffset = fr ? yOffset : 0;
+ int tessellatorZOffset = fr ? zOffset : 0;
+
boolean optimize = LODMod.optimizeChunkMeshes;
+
+ ChunkMesh.Flags flags = new ChunkMesh.Flags(t.hasTexture, t.hasBrightness, t.hasColor, t.hasNormals);
+
if(optimize) {
+ List<MeshQuad> quads = new ArrayList<>();
+
+ for(int quadI = 0; quadI < t.vertexCount / 4; quadI++) {
+ MeshQuad quad = new MeshQuad(t.rawBuffer, quadI * 32, flags, tessellatorXOffset, tessellatorYOffset, tessellatorZOffset);
+ //if(quad.bUs[0] == quad.bUs[1] && quad.bUs[1] == quad.bUs[2] && quad.bUs[2] == quad.bUs[3] && quad.bUs[3] == quad.bVs[0] && quad.bVs[0] == quad.bVs[1] && quad.bVs[1] == quad.bVs[2] && quad.bVs[2] == quad.bVs[3] && quad.bVs[3] == 0) {
+ // quad.deleted = true;
+ //}
+ if(quad.plane == quad.PLANE_XZ && !quad.isClockwiseXZ()) {
+ // water hack
+ quad.deleted = true;
+ }
+ quads.add(quad);
+ }
+
ArrayList<ArrayList<MeshQuad>> quadsByPlaneDir = new ArrayList<>(); // XY, XZ, YZ
for(int i = 0; i < 3; i++) {
quadsByPlaneDir.add(new ArrayList<MeshQuad>());
@@ -117,23 +127,74 @@ public class ChunkMesh extends Mesh {
}
}
}
- }
-
- int quadCount = countValidQuads(quads);
-
- totalOriginalQuadCount += quads.size();
- totalSimplifiedQuadCount += quadCount;
- //System.out.println("simplified quads " + totalOriginalQuadCount + " -> " + totalSimplifiedQuadCount + " (ratio: " + ((float)totalSimplifiedQuadCount / (float)totalOriginalQuadCount) + ") totalMergeCountByPlane: " + Arrays.toString(totalMergeCountByPlane));
-
- LODMod.debugHookToChunkMeshEnd();
-
- if(quadCount > 0) {
- return new ChunkMesh(
- (int)(xOffset / 16), (int)(yOffset / 16), (int)(zOffset / 16),
- new ChunkMesh.Flags(t.hasTexture, t.hasBrightness, t.hasColor, t.hasNormals),
- quadCount, quads, pass);
+
+ int quadCount = countValidQuads(quads);
+
+ totalOriginalQuadCount += quads.size();
+ totalSimplifiedQuadCount += quadCount;
+ //System.out.println("simplified quads " + totalOriginalQuadCount + " -> " + totalSimplifiedQuadCount + " (ratio: " + ((float)totalSimplifiedQuadCount / (float)totalOriginalQuadCount) + ") totalMergeCountByPlane: " + Arrays.toString(totalMergeCountByPlane));
+
+ if(quadCount > 0) {
+ return new ChunkMesh(
+ (int)(xOffset / 16), (int)(yOffset / 16), (int)(zOffset / 16),
+ new ChunkMesh.Flags(t.hasTexture, t.hasBrightness, t.hasColor, t.hasNormals),
+ quadCount, quads, pass);
+ } else {
+ return null;
+ }
} else {
- return null;
+ int quadCount = t.vertexCount / 4;
+ ByteBuffer buffer = BufferUtils.createByteBuffer(quadCount * 6 * 7 * 4);
+ BufferWriter out = new BufferWriter(buffer);
+
+ try {
+ for(int i = 0; i < quadCount; i++) {
+ writeBufferQuad(t, i * 32, out, -tessellatorXOffset + xOffset, -tessellatorYOffset + yOffset, -tessellatorZOffset + zOffset);
+ }
+ } catch(IOException e) {
+ e.printStackTrace();
+ }
+ buffer.flip();
+
+ if(quadCount > 0) {
+ return new ChunkMesh(
+ (int)(xOffset / 16), (int)(yOffset / 16), (int)(zOffset / 16),
+ flags,
+ quadCount, buffer, pass);
+ } else {
+ return null;
+ }
+ }
+ }
+
+ private static void writeBufferQuad(Tessellator t, int offset, BufferWriter out, float offsetX, float offsetY, float offsetZ) throws IOException {
+ for(int vertexI = 0; vertexI < 6; vertexI++) {
+
+ int vi = new int[]{0, 1, 3, 1, 2, 3}[vertexI];
+
+ int i = offset + vi * 8;
+
+ float x = Float.intBitsToFloat(t.rawBuffer[i + 0]) + offsetX;
+ float y = Float.intBitsToFloat(t.rawBuffer[i + 1]) + offsetY;
+ float z = Float.intBitsToFloat(t.rawBuffer[i + 2]) + offsetZ;
+
+ out.writeFloat(x);
+ out.writeFloat(y);
+ out.writeFloat(z);
+
+ float u = Float.intBitsToFloat(t.rawBuffer[i + 3]);
+ float v = Float.intBitsToFloat(t.rawBuffer[i + 4]);
+
+ out.writeFloat(u);
+ out.writeFloat(v);
+
+ int brightness = t.rawBuffer[i + 7];
+ out.writeInt(brightness);
+
+ int color = t.rawBuffer[i + 5];
+ out.writeInt(color);
+
+ i += 8;
}
}
@@ -168,7 +229,7 @@ public class ChunkMesh extends Mesh {
return quadCount;
}
- private NBTBase toNBT(List<MeshQuad> quads, int quadCount) {
+ private NBTBase toNBT(List<? extends MeshQuad> quads, int quadCount) {
ByteArrayOutputStream byteOut = new ByteArrayOutputStream(quadCount * (2 + 4 * (3 + 2 + 2 + 4)));
DataOutputStream out = new DataOutputStream(byteOut);
try {
@@ -188,22 +249,8 @@ public class ChunkMesh extends Mesh {
if(buffer != null) {
usedRAM -= buffer.limit();
}
- if(nbtData != null) {
- usedRAM += ((NBTTagByteArray)nbtData).func_150292_c().length;
- }
instances--;
}
-
- @Override
- public void prepareBuffer() {
- this.buffer = createBuffer(((NBTTagByteArray)nbtData).func_150292_c(), nameList);
- }
-
- @Override
- public void destroyBuffer(){
- usedRAM -= buffer.limit();
- this.buffer = null;
- }
private ByteBuffer createBuffer(byte[] data, List<String> stringTable) {
if(!(flags.hasTexture && flags.hasColor && flags.hasBrightness && !flags.hasNormals)) {
diff --git a/src/main/java/makamys/lodmod/util/BufferWriter.java b/src/main/java/makamys/lodmod/util/BufferWriter.java
new file mode 100644
index 0000000..ae81be1
--- /dev/null
+++ b/src/main/java/makamys/lodmod/util/BufferWriter.java
@@ -0,0 +1,46 @@
+package makamys.lodmod.util;
+
+import java.nio.ByteBuffer;
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+import java.nio.ShortBuffer;
+
+public class BufferWriter {
+
+ private ByteBuffer buf;
+
+ private FloatBuffer floatBuffer;
+ private ShortBuffer shortBuffer;
+ private IntBuffer intBuffer;
+
+ public BufferWriter(ByteBuffer buf) {
+ this.buf = buf;
+ this.floatBuffer = buf.asFloatBuffer();
+ this.shortBuffer = buf.asShortBuffer();
+ this.intBuffer = buf.asIntBuffer();
+ }
+
+ private void incrementPosition(int add) {
+ buf.position(buf.position() + add);
+ floatBuffer.position(buf.position() / 4);
+ shortBuffer.position(buf.position() / 2);
+ intBuffer.position(buf.position() / 4);
+ }
+
+ public void writeFloat(float x) {
+ try {
+ floatBuffer.put(x);
+
+ incrementPosition(4);
+ } catch(Exception e){
+ e.printStackTrace();
+ }
+ }
+
+ public void writeInt(int x) {
+ intBuffer.put(x);
+
+ incrementPosition(4);
+ }
+
+} \ No newline at end of file
diff --git a/src/main/java/makamys/lodmod/util/Util.java b/src/main/java/makamys/lodmod/util/Util.java
index ae80b78..851e6f5 100644
--- a/src/main/java/makamys/lodmod/util/Util.java
+++ b/src/main/java/makamys/lodmod/util/Util.java
@@ -53,9 +53,11 @@ public class Util {
}
public static byte[] byteBufferToArray(ByteBuffer buffer) {
- byte[] dst = new byte[buffer.remaining()];
+ byte[] dst = new byte[buffer.limit()];
+ int pos = buffer.position();
+ buffer.position(0);
buffer.get(dst);
- buffer.flip();
+ buffer.position(pos);
return dst;
}