aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/makamys/lodmod/renderer
diff options
context:
space:
mode:
authormakamys <makamys@outlook.com>2022-06-09 12:57:52 +0200
committermakamys <makamys@outlook.com>2022-06-09 12:57:52 +0200
commit5bea63de0d78487b91dd701a8f6931b9314f2be5 (patch)
tree9a23fc91c986d8763b31c48f670b812e9ce24c8a /src/main/java/makamys/lodmod/renderer
parent5820fe56fb4022ddda044a8fe502b59e18147836 (diff)
downloadNeodymium-5bea63de0d78487b91dd701a8f6931b9314f2be5.tar.gz
Neodymium-5bea63de0d78487b91dd701a8f6931b9314f2be5.tar.bz2
Neodymium-5bea63de0d78487b91dd701a8f6931b9314f2be5.zip
Rebrand pt. 1: Rename mod to Neodymium
Diffstat (limited to 'src/main/java/makamys/lodmod/renderer')
-rw-r--r--src/main/java/makamys/lodmod/renderer/ChunkMesh.java455
-rw-r--r--src/main/java/makamys/lodmod/renderer/FarChunkCache.java12
-rw-r--r--src/main/java/makamys/lodmod/renderer/FarWorldRenderer.java14
-rw-r--r--src/main/java/makamys/lodmod/renderer/GPUMemoryManager.java215
-rw-r--r--src/main/java/makamys/lodmod/renderer/LODChunk.java184
-rw-r--r--src/main/java/makamys/lodmod/renderer/LODRegion.java195
-rw-r--r--src/main/java/makamys/lodmod/renderer/LODRenderer.java730
-rw-r--r--src/main/java/makamys/lodmod/renderer/Mesh.java44
-rw-r--r--src/main/java/makamys/lodmod/renderer/MeshQuad.java426
-rw-r--r--src/main/java/makamys/lodmod/renderer/SimpleChunkMesh.java350
10 files changed, 0 insertions, 2625 deletions
diff --git a/src/main/java/makamys/lodmod/renderer/ChunkMesh.java b/src/main/java/makamys/lodmod/renderer/ChunkMesh.java
deleted file mode 100644
index f07a908..0000000
--- a/src/main/java/makamys/lodmod/renderer/ChunkMesh.java
+++ /dev/null
@@ -1,455 +0,0 @@
-package makamys.lodmod.renderer;
-
-import java.io.ByteArrayOutputStream;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.FloatBuffer;
-import java.nio.IntBuffer;
-import java.nio.ShortBuffer;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.stream.Collectors;
-
-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;
-import net.minecraft.client.renderer.texture.TextureAtlasSprite;
-import net.minecraft.client.renderer.texture.TextureMap;
-import net.minecraft.entity.Entity;
-import net.minecraft.nbt.NBTBase;
-import net.minecraft.nbt.NBTTagByteArray;
-import net.minecraft.tileentity.TileEntity;
-
-public class ChunkMesh extends Mesh {
-
- Flags flags;
-
- // 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, ByteBuffer buffer, int pass) {
- this.x = x;
- this.y = y;
- this.z = z;
- this.flags = flags;
- this.quadCount = quadCount;
- this.pass = pass;
-
- this.buffer = buffer;
- usedRAM += buffer.limit();
- instances++;
- }
-
- public ChunkMesh(int x, int y, int z, Flags flags, int quadCount, List<MeshQuad> quads, int pass) {
- this.x = x;
- this.y = y;
- this.z = z;
- this.flags = flags;
- this.quadCount = quadCount;
- this.pass = pass;
-
- NBTBase nbtData = toNBT(quads, quadCount);
- buffer = createBuffer(((NBTTagByteArray)nbtData).func_150292_c(), nameList);
- usedRAM += buffer.limit();
- instances++;
- }
-
- private static int totalOriginalQuadCount = 0;
- private static int totalSimplifiedQuadCount = 0;
-
- 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;
- }
-
- int xOffset = wr.posX;
- int yOffset = wr.posY;
- int zOffset = wr.posZ;
-
- 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>());
- }
- for(MeshQuad quad : quads) {
- if(quad.plane != MeshQuad.PLANE_NONE) {
- quadsByPlaneDir.get(quad.plane).add(quad);
- }
- }
- for(int plane = 0; plane < 3; plane++) {
- quadsByPlaneDir.get(plane).sort(MeshQuad.QuadPlaneComparator.quadPlaneComparators[plane]);
- }
-
- for(int plane = 0; plane < 3; plane++) {
- List<MeshQuad> planeDirQuads = quadsByPlaneDir.get(plane);
- int planeStart = 0;
- for(int quadI = 0; quadI < planeDirQuads.size(); quadI++) {
- MeshQuad quad = planeDirQuads.get(quadI);
- MeshQuad nextQuad = quadI == planeDirQuads.size() - 1 ? null : planeDirQuads.get(quadI + 1);
- if(!quad.onSamePlaneAs(nextQuad)) {
- simplifyPlane(planeDirQuads.subList(planeStart, quadI));
- planeStart = quadI + 1;
- }
- }
- }
-
- 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 {
- 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, 2, 0, 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;
- }
- }
-
- private static void simplifyPlane(List<MeshQuad> planeQuads) {
- MeshQuad lastQuad = null;
- // Pass 1: merge quads to create rows
- for(MeshQuad quad : planeQuads) {
- if(lastQuad != null) {
- lastQuad.tryToMerge(quad);
- }
- if(quad.isValid(quad)) {
- lastQuad = quad;
- }
- }
-
- // Pass 2: merge rows to create rectangles
- // TODO optimize?
- for(int i = 0; i < planeQuads.size(); i++) {
- for(int j = i + 1; j < planeQuads.size(); j++) {
- planeQuads.get(i).tryToMerge(planeQuads.get(j));
- }
- }
- }
-
- private static int countValidQuads(List<MeshQuad> quads) {
- int quadCount = 0;
- for(MeshQuad quad : quads) {
- if(!quad.deleted) {
- quadCount++;
- }
- }
- return 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 {
- for(int pass = 0; pass <= 9; pass++){
- for(MeshQuad quad : quads) {
- quad.writeToDisk(out, pass);
- }
- }
- } catch(IOException e) {}
-
- NBTTagByteArray arr = new NBTTagByteArray(byteOut.toByteArray());
- usedRAM += arr.func_150292_c().length;
- return arr;
- }
-
- void destroy() {
- if(buffer != null) {
- usedRAM -= buffer.limit();
- instances--;
- buffer = null;
-
- if(gpuStatus == Mesh.GPUStatus.SENT) {
- gpuStatus = Mesh.GPUStatus.PENDING_DELETE;
- }
- }
- }
-
- @Override
- public void destroyBuffer() {
- destroy();
- }
-
- private ByteBuffer createBuffer(byte[] data, List<String> stringTable) {
- if(!(flags.hasTexture && flags.hasColor && flags.hasBrightness && !flags.hasNormals)) {
- // for simplicity's sake we just assume this setup
- System.out.println("invalid mesh properties, expected a chunk");
- return null;
- }
- int coordsOffset = quadCount * 2;
- int textureOffset = quadCount * (2 + 4 + 4 + 4);
- int brightnessOffset = quadCount * (2 + 4 + 4 + 4 + 4 + 4);
- int colorOffset = quadCount * (2 + 4 + 4 + 4 + 4 + 4 + 4 + 4);
-
- ByteBuffer buffer = BufferUtils.createByteBuffer(quadCount * 6 * getStride());
- FloatBuffer floatBuffer = buffer.asFloatBuffer();
- ShortBuffer shortBuffer = buffer.asShortBuffer();
- IntBuffer intBuffer = buffer.asIntBuffer();
-
- try {
- for(int quadI = 0; quadI < quadCount; quadI++) {
- short spriteIndex = readShortAt(data, quadI * 2);
- String spriteName = stringTable.get(spriteIndex);
-
- TextureAtlasSprite tas = ((TextureMap)Minecraft.getMinecraft().getTextureManager().getTexture(TextureMap.locationBlocksTexture)).getAtlasSprite(spriteName);
-
- for (int vertexNum = 0; vertexNum < 6; vertexNum++) {
- int vi = new int[]{0, 1, 3, 1, 2, 3}[vertexNum];
- int vertexI = 4 * quadI + vi;
- int offset = vertexI * getStride();
- int simpleX = Byte.toUnsignedInt(data[coordsOffset + 0 * 4 * quadCount + 4 * quadI + vi]);
- if(simpleX == 255) simpleX = 256;
- int simpleY = Byte.toUnsignedInt(data[coordsOffset + 1 * 4 * quadCount + 4 * quadI + vi]);
- if(simpleY == 255) simpleY = 256;
- int simpleZ = Byte.toUnsignedInt(data[coordsOffset + 2 * 4 * quadCount + 4 * quadI + vi]);
- if(simpleZ == 255) simpleZ = 256;
- floatBuffer.put(x * 16 + simpleX / 16f); // x
- floatBuffer.put(y * 16 + simpleY / 16f); // y
- floatBuffer.put(z * 16 + simpleZ / 16f); // z
-
- byte relU = data[textureOffset + 0 * 4 * quadCount + 4 * quadI + vi];
- byte relV = data[textureOffset + 1 * 4 * quadCount + 4 * quadI + vi];
-
- floatBuffer.put(tas.getMinU() + (tas.getMaxU() - tas.getMinU()) * (relU / 16f)); // u
- floatBuffer.put(tas.getMinV() + (tas.getMaxV() - tas.getMinV()) * (relV / 16f)); // v
-
- shortBuffer.position(floatBuffer.position() * 2);
-
- shortBuffer.put((short)Byte.toUnsignedInt(data[brightnessOffset + 0 * 4 * quadCount + 4 * quadI + vi])); // bU
- shortBuffer.put((short)Byte.toUnsignedInt(data[brightnessOffset + 1 * 4 * quadCount + 4 * quadI + vi])); // bV
-
- intBuffer.position(shortBuffer.position() / 2);
-
- int integet = readIntAt(data, colorOffset + 4 * 4 * quadI + 4 * vi);
- intBuffer.put(integet); // c
-
- floatBuffer.position(intBuffer.position());
- }
- }
- } catch(Exception e) {
- e.printStackTrace();
- }
-
- buffer.position(floatBuffer.position() * 4);
- buffer.flip();
-
- usedRAM += buffer.limit();
-
- return buffer;
- }
-
- public void update() {
- }
-
- // Java is weird.
- public static short readShortAt(DataInputStream in, int offset) {
- try {
- in.reset();
- in.skip(offset);
- return in.readShort();
- } catch(IOException e) {
- return -1;
- }
- }
-
- public static short readShortAt(byte[] data, int offset) {
- return (short)(Byte.toUnsignedInt(data[offset]) << 8 | Byte.toUnsignedInt(data[offset + 1]));
- }
-
- public static int readIntAt(DataInputStream in, int offset) {
- try {
- in.reset();
- in.skip(offset);
- return in.readInt();
- } catch(IOException e) {
- return -1;
- }
- }
-
- public static int readIntAt(byte[] data, int offset) {
- return (int)(Byte.toUnsignedLong(data[offset]) << 24 | Byte.toUnsignedLong(data[offset + 1]) << 16 | Byte.toUnsignedLong(data[offset + 2]) << 8 | Byte.toUnsignedLong(data[offset + 3]));
- }
-
- public int getStride() {
- return (3 * 4 + (flags.hasTexture ? 8 : 0) + (flags.hasBrightness ? 4 : 0) + (flags.hasColor ? 4 : 0) + (flags.hasNormals ? 4 : 0));
- }
-
- static void saveChunks(List<Integer> coords) {
- System.out.println("saving " + (coords.size() / 3) + " cchunks");
- for(int i = 0; i < coords.size(); i += 3) {
- if(i % 300 == 0) {
- System.out.println((i / 3) + " / " + (coords.size() / 3));
- }
- int theX = coords.get(i);
- int theY = coords.get(i + 1);
- int theZ = coords.get(i + 2);
-
- WorldRenderer wr = new WorldRenderer(Minecraft.getMinecraft().theWorld, new ArrayList<TileEntity>(), theX * 16, theY * 16, theZ * 16, 100000);
- /*
- if (this.occlusionEnabled)
- {
- this.worldRenderers[(var6 * this.renderChunksTall + var5) * this.renderChunksWide + var4].glOcclusionQuery = this.glOcclusionQueryBase.get(var3);
- }*/
-
- wr.isWaitingOnOcclusionQuery = false;
- wr.isVisible = true;
- wr.isInFrustum = true;
- wr.chunkIndex = 0;
- wr.markDirty();
- wr.updateRenderer(Minecraft.getMinecraft().thePlayer);
- }
- //Tessellator.endSave();
- }
-
- static List<ChunkMesh> getChunkMesh(int theX, int theY, int theZ) {
- WorldRenderer wr = new WorldRenderer(Minecraft.getMinecraft().theWorld, new ArrayList<TileEntity>(), theX * 16, theY * 16, theZ * 16, 100000);
-
- wr.isWaitingOnOcclusionQuery = false;
- wr.isVisible = true;
- wr.isInFrustum = true;
- wr.chunkIndex = 0;
- wr.markDirty();
- wr.updateRenderer(Minecraft.getMinecraft().thePlayer);
- return ((IWorldRenderer)wr).getChunkMeshes();
- }
-
- public double distSq(Entity player) {
- int centerX = x * 16 + 8;
- int centerY = y * 16 + 8;
- int centerZ = z * 16 + 8;
-
- return player.getDistanceSq(centerX, centerY, centerZ);
- }
-
- public static class Flags {
- boolean hasTexture;
- boolean hasBrightness;
- boolean hasColor;
- boolean hasNormals;
-
- public Flags(byte flags) {
- hasTexture = (flags & 1) != 0;
- hasBrightness = (flags & 2) != 0;
- hasColor = (flags & 4) != 0;
- hasNormals = (flags & 8) != 0;
- }
-
- public Flags(boolean hasTexture, boolean hasBrightness, boolean hasColor, boolean hasNormals) {
- this.hasTexture = hasTexture;
- this.hasBrightness = hasBrightness;
- this.hasColor = hasColor;
- this.hasNormals = hasNormals;
- }
-
- public byte toByte() {
- byte flags = 0;
- if(hasTexture) {
- flags |= 1;
- }
- if(hasBrightness) {
- flags |= 2;
- }
- if(hasColor) {
- flags |= 4;
- }
- if(hasNormals) {
- flags |= 8;
- }
- return flags;
- }
- }
-
-}
-
diff --git a/src/main/java/makamys/lodmod/renderer/FarChunkCache.java b/src/main/java/makamys/lodmod/renderer/FarChunkCache.java
deleted file mode 100644
index f4e3cca..0000000
--- a/src/main/java/makamys/lodmod/renderer/FarChunkCache.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package makamys.lodmod.renderer;
-
-import net.minecraft.world.ChunkCache;
-import net.minecraft.world.World;
-
-public class FarChunkCache extends ChunkCache {
-
- public FarChunkCache(World p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8) {
- super(p1, p2, p3, p4, p5, p6, p7, p8);
- }
-
-}
diff --git a/src/main/java/makamys/lodmod/renderer/FarWorldRenderer.java b/src/main/java/makamys/lodmod/renderer/FarWorldRenderer.java
deleted file mode 100644
index 72eb4fd..0000000
--- a/src/main/java/makamys/lodmod/renderer/FarWorldRenderer.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package makamys.lodmod.renderer;
-
-import java.util.List;
-
-import net.minecraft.client.renderer.WorldRenderer;
-import net.minecraft.world.World;
-
-public class FarWorldRenderer extends WorldRenderer {
-
- public FarWorldRenderer(World p1, List p2, int p3, int p4, int p5, int p6) {
- super(p1, p2, p3, p4, p5, p6);
- }
-
-}
diff --git a/src/main/java/makamys/lodmod/renderer/GPUMemoryManager.java b/src/main/java/makamys/lodmod/renderer/GPUMemoryManager.java
deleted file mode 100644
index 19d4dbe..0000000
--- a/src/main/java/makamys/lodmod/renderer/GPUMemoryManager.java
+++ /dev/null
@@ -1,215 +0,0 @@
-package makamys.lodmod.renderer;
-
-import static org.lwjgl.opengl.GL15.*;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-
-import makamys.lodmod.LODMod;
-import makamys.lodmod.renderer.Mesh.GPUStatus;
-import makamys.lodmod.util.GuiHelper;
-
-public class GPUMemoryManager {
-
- private int bufferSize;
-
- public int VBO;
-
- private int nextMesh;
-
- private List<Mesh> sentMeshes = new ArrayList<>();
-
- public GPUMemoryManager() {
- VBO = glGenBuffers();
-
- bufferSize = LODMod.VRAMSize * 1024 * 1024;
-
- glBindBuffer(GL_ARRAY_BUFFER, VBO);
-
- glBufferData(GL_ARRAY_BUFFER, bufferSize, GL_DYNAMIC_DRAW);
-
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- }
-
- public void runGC(boolean full) {
- glBindBuffer(GL_ARRAY_BUFFER, VBO);
-
- int moved = 0;
- int timesReachedEnd = 0;
- int checksLeft = sentMeshes.size();
-
- while((!full && (moved < 4 && checksLeft-- > 0)) || (full && timesReachedEnd < 2) && !sentMeshes.isEmpty()) {
- nextMesh++;
- if(nextMesh >= sentMeshes.size()) {
- nextMesh = 0;
- timesReachedEnd++;
- }
- Mesh mesh = sentMeshes.get(nextMesh);
-
- if(mesh.gpuStatus == GPUStatus.SENT) {
- int offset = nextMesh == 0 ? 0 : sentMeshes.get(nextMesh - 1).getEnd();
- if(mesh.offset != offset) {
- glBufferSubData(GL_ARRAY_BUFFER, offset, mesh.buffer);
- moved++;
- }
- mesh.iFirst = offset / mesh.getStride();
- mesh.offset = offset;
- } else if(mesh.gpuStatus == GPUStatus.PENDING_DELETE) {
- mesh.iFirst = mesh.offset = -1;
- mesh.visible = false;
- mesh.gpuStatus = GPUStatus.UNSENT;
-
- sentMeshes.remove(nextMesh);
-
- mesh.destroyBuffer();
-
- if(nextMesh > 0) {
- nextMesh--;
- }
- }
- }
-
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- }
-
- private int malloc(int size) {
- int nextBase = 0;
- if(!sentMeshes.isEmpty()) {
- if(nextMesh < sentMeshes.size() - 1) {
- Mesh next = sentMeshes.get(nextMesh);
- Mesh nextnext = sentMeshes.get(nextMesh + 1);
- if(nextnext.offset - next.getEnd() >= size) {
- return next.getEnd();
- }
- }
-
- nextBase = sentMeshes.get(sentMeshes.size() - 1).getEnd();
- }
-
- if(nextBase + size >= bufferSize) {
- return -1;
- } else {
- return nextBase;
- }
- }
-
- private int end() {
- return (sentMeshes.isEmpty() ? 0 : sentMeshes.get(sentMeshes.size() - 1).getEnd());
- }
-
- public void sendMeshToGPU(Mesh mesh) {
- if(mesh == null || mesh.buffer == null) {
- return;
- }
-
- if(end() + mesh.bufferSize() >= bufferSize) {
- runGC(true);
- }
-
- if(end() + mesh.bufferSize() >= bufferSize) {
- System.out.println("VRAM is full! Try increasing the allocated VRAM in the config, if possible. Reverting to vanilla renderer.");
- LODMod.renderer.destroyPending = true;
- // TODO restart renderer with more VRAM allocated when this happens.
- return;
- }
-
- int size = mesh.bufferSize();
- int insertIndex = -1;
-
- int nextBase = -1;
- if(!sentMeshes.isEmpty()) {
- if(nextMesh < sentMeshes.size() - 1) {
- Mesh next = sentMeshes.get(nextMesh);
- Mesh nextnext = null;
- for(int i = nextMesh + 1; i < sentMeshes.size(); i++) {
- Mesh m = sentMeshes.get(i);
- if(m.gpuStatus == Mesh.GPUStatus.SENT) {
- nextnext = m;
- break;
- }
- }
- if(nextnext != null && nextnext.offset - next.getEnd() >= size) {
- nextBase = next.getEnd();
- insertIndex = nextMesh + 1;
- }
- }
-
- if(nextBase == -1) {
- nextBase = sentMeshes.get(sentMeshes.size() - 1).getEnd();
- }
- }
- if(nextBase == -1) nextBase = 0;
-
-
- if(mesh.gpuStatus == GPUStatus.UNSENT) {
- mesh.prepareBuffer();
-
- glBindBuffer(GL_ARRAY_BUFFER, VBO);
-
- glBufferSubData(GL_ARRAY_BUFFER, nextBase, mesh.buffer);
- mesh.iFirst = nextBase / mesh.getStride();
- mesh.iCount = mesh.quadCount * 6;
- mesh.offset = nextBase;
-
- if(insertIndex == -1) {
- sentMeshes.add(mesh);
- } else {
- sentMeshes.add(insertIndex, mesh);
- nextMesh = insertIndex;
- }
-
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- }
-
- mesh.gpuStatus = GPUStatus.SENT;
- }
-
- public void deleteMeshFromGPU(Mesh mesh) {
- if(mesh == null || mesh.gpuStatus == GPUStatus.UNSENT) {
- return;
- }
- mesh.gpuStatus = GPUStatus.PENDING_DELETE;
- }
-
- public void destroy() {
- glDeleteBuffers(VBO);
- }
-
- public List<String> getDebugText() {
- return Arrays.asList("VRAM: " + (end() / 1024 / 1024) + "MB / " + (bufferSize / 1024 / 1024) + "MB");
- }
-
- public void drawInfo() {
- int scale = 10000;
- int rowLength = 512;
- int yOff = 20;
-
- int height = (bufferSize / scale) / rowLength;
- GuiHelper.drawRectangle(0, yOff, rowLength, height, 0x000000, 50);
-
- int meshI = 0;
- for(Mesh mesh : sentMeshes) {
-
- int o = mesh.offset / 10000;
- int o2 = (mesh.offset + mesh.bufferSize()) / 10000;
- if(o / rowLength == o2 / rowLength) {
- if(mesh.gpuStatus != Mesh.GPUStatus.PENDING_DELETE) {
- GuiHelper.drawRectangle(o % rowLength, o / rowLength + yOff, mesh.buffer.limit() / scale + 1, 1, meshI == nextMesh ? 0x00FF00 : 0xFFFFFF);
- }
- } else {
- for(int i = o; i < o2; i++) {
- int x = i % rowLength;
- int y = i / rowLength;
- if(mesh.gpuStatus != Mesh.GPUStatus.PENDING_DELETE) {
- GuiHelper.drawRectangle(x, y + yOff, 1, 1, 0xFFFFFF);
- }
- }
- }
- meshI++;
- }
- GuiHelper.drawRectangle(0 % rowLength, 0 + yOff, 4, 4, 0x00FF00);
- GuiHelper.drawRectangle((bufferSize / scale) % rowLength, (bufferSize / scale) / rowLength + yOff, 4, 4, 0xFF0000);
- }
-
-}
diff --git a/src/main/java/makamys/lodmod/renderer/LODChunk.java b/src/main/java/makamys/lodmod/renderer/LODChunk.java
deleted file mode 100644
index 2c5d61c..0000000
--- a/src/main/java/makamys/lodmod/renderer/LODChunk.java
+++ /dev/null
@@ -1,184 +0,0 @@
-package makamys.lodmod.renderer;
-
-import java.util.List;
-
-import makamys.lodmod.LODMod;
-import net.minecraft.entity.Entity;
-import net.minecraft.nbt.NBTTagCompound;
-import net.minecraft.nbt.NBTTagEnd;
-import net.minecraft.nbt.NBTTagList;
-import net.minecraft.world.chunk.Chunk;
-
-public class LODChunk {
-
- int x, z;
- public boolean needsChunk = true;
- int lod = 0;
- boolean visible;
- boolean dirty;
- boolean discardedMesh;
-
- SimpleChunkMesh[] simpleMeshes = new SimpleChunkMesh[2];
- ChunkMesh[] chunkMeshes = new ChunkMesh[32];
-
- public boolean[] isSectionVisible = new boolean[16];
-
- LODRenderer renderer = LODMod.renderer;
-
- public LODChunk(int x, int z) {
- this.x = x;
- this.z = z;
- }
- /*
- public LODChunk(NBTTagCompound nbt, List<String> spriteList) {
- this.x = nbt.getInteger("x");
- this.z = nbt.getInteger("z");
-
- loadChunkMeshesNBT(nbt.getCompoundTag("chunkMeshes"), spriteList);
- }
-
- private void loadChunkMeshesNBT(NBTTagCompound chunkMeshesCompound, List<String> spriteList) {
- for(Object o : chunkMeshesCompound.func_150296_c()) {
- String key = (String)o;
- int keyInt = Integer.parseInt(key);
-
- byte[] data = chunkMeshesCompound.getByteArray(key);
-
- chunkMeshes[keyInt] = new ChunkMesh(x, keyInt / 2, z, new ChunkMesh.Flags(true, true, true, false), data.length / (2 + 4 * (3 + 2 + 2 + 4)), data, spriteList, keyInt % 2);
- }
- }
- */
- @Override
- public String toString() {
- return "LODChunk(" + x + ", " + z + ")";
- }
-
- public double distSq(Entity entity) {
- return Math.pow(entity.posX - x * 16, 2) + Math.pow(entity.posZ - z * 16, 2);
- }
-
- public void putChunkMeshes(int cy, List<ChunkMesh> newChunkMeshes) {
- for(int i = 0; i < 2; i++) {
- ChunkMesh newChunkMesh = newChunkMeshes.size() > i ? newChunkMeshes.get(i) : null;
- if(chunkMeshes[cy * 2 + i] != null) {
- if(newChunkMesh != null) {
- newChunkMesh.pass = i;
- }
-
- renderer.removeMesh(chunkMeshes[cy * 2 + i]);
- chunkMeshes[cy * 2 + i].destroy();
- }
- chunkMeshes[cy * 2 + i] = newChunkMesh;
- }
- LODMod.renderer.lodChunkChanged(this);
- dirty = true;
- discardedMesh = false;
- }
-
- // nice copypasta
- public void putSimpleMeshes(List<SimpleChunkMesh> newSimpleMeshes) {
- for(int i = 0; i < 2; i++) {
- SimpleChunkMesh newSimpleMesh = newSimpleMeshes.size() > i ? newSimpleMeshes.get(i) : null;
- if(simpleMeshes[i] != null) {
- if(newSimpleMesh != null) {
- newSimpleMesh.pass = i;
- }
-
- renderer.setMeshVisible(simpleMeshes[i], false);
- simpleMeshes[i].destroy();
- }
- simpleMeshes[i] = newSimpleMesh;
- }
- LODMod.renderer.lodChunkChanged(this);
- }
-
- public boolean hasChunkMeshes() {
- for(ChunkMesh cm : chunkMeshes) {
- if(cm != null) {
- return true;
- }
- }
- return false;
- }
-
- public void tick(Entity player) {
- double distSq = distSq(player);
- if(LODMod.disableSimpleMeshes || distSq < Math.pow((LODMod.renderer.renderRange / 2) * 16, 2)) {
- setLOD(2);
- } else if(distSq < Math.pow((LODMod.renderer.renderRange) * 16, 2)) {
- setLOD(1);
- } else {
- setLOD(0);
- }
- }
-
- public void setLOD(int lod) {
- if(lod == this.lod) return;
-
- this.lod = lod;
- LODMod.renderer.lodChunkChanged(this);
- if(!dirty) {
- if(lod < 2) {
- for(int i = 0; i < chunkMeshes.length; i++) {
- if(chunkMeshes[i] != null) {
- chunkMeshes[i].destroy();
- chunkMeshes[i] = null;
- discardedMesh = true;
- }
- }
- }
- }
- }
- /*
- public NBTTagCompound saveToNBT(NBTTagCompound oldNbt, List<String> oldStringTable) {
- NBTTagCompound nbt = new NBTTagCompound();
- nbt.setInteger("x", x);
- nbt.setInteger("z", z);
-
- NBTTagCompound chunkMeshesCompound = oldNbt == null ? new NBTTagCompound() : oldNbt.getCompoundTag("chunkMeshes");
- if(!discardedMesh) {
- for(int i = 0; i < chunkMeshes.length; i++) {
- if(chunkMeshes[i] != null) {
- chunkMeshesCompound.setTag(String.valueOf(i), chunkMeshes[i].nbtData);
- }
- }
- } else if(oldNbt != null && discardedMesh && lod == 2) {
- loadChunkMeshesNBT(chunkMeshesCompound, oldStringTable);
- LODMod.renderer.lodChunkChanged(this);
- }
- nbt.setTag("chunkMeshes", chunkMeshesCompound);
- dirty = false;
- return nbt;
- }
- */
- public void destroy() {
- for(SimpleChunkMesh scm: simpleMeshes) {
- if(scm != null) {
- scm.destroy();
- }
- }
- for(ChunkMesh cm: chunkMeshes) {
- if(cm != null) {
- cm.destroy();
- }
- }
- LODMod.renderer.setVisible(this, false);
- }
-
- public void receiveChunk(Chunk chunk) {
- if(!LODMod.disableSimpleMeshes) {
- putSimpleMeshes(SimpleChunkMesh.generateSimpleMeshes(chunk));
- }
- }
-
- public boolean isFullyVisible() {
- if(!visible) return false;