diff --git a/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java b/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java index 6124b9796..ba51e4bcd 100644 --- a/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java +++ b/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java @@ -101,7 +101,6 @@ public class LodBufferBuilder int startZ = (-LodChunk.WIDTH * (numbChunksWide / 2)) + playerZChunkOffset; - Thread t = new Thread(()-> { // index of the chunk currently being added to the @@ -123,12 +122,12 @@ public class LodBufferBuilder // z axis for (int j = 0; j < numbChunksWide; j++) { - // skip the middle - // (As the player moves some chunks will overlap or be missing, - // this is just how chunk loading/unloading works. This can hopefully - // be hidden with careful use of fog) - int middle = (numbChunksWide / 2); - if (isCoordInCenterArea(i, j, middle)) + int chunkX = i + (startX / LodChunk.WIDTH); + int chunkZ = j + (startZ / LodChunk.WIDTH); + + // skip any chunks that Minecraft is going to render + if(isCoordInCenterArea(i, j, (numbChunksWide / 2)) + && renderer.vanillaRenderedChunks.contains(new ChunkPos(chunkX, chunkZ))) { continue; } @@ -140,9 +139,6 @@ public class LodBufferBuilder double yOffset = 0; double zOffset = (LodChunk.WIDTH * j) + startZ; - int chunkX = i + (startX / LodChunk.WIDTH); - int chunkZ = j + (startZ / LodChunk.WIDTH); - LodChunk lod = lodDim.getLodFromCoordinates(chunkX, chunkZ); if (lod == null || lod.isLodEmpty()) diff --git a/src/main/java/com/seibel/lod/render/LodRender.java b/src/main/java/com/seibel/lod/render/LodRender.java index 57084932f..da6c879c0 100644 --- a/src/main/java/com/seibel/lod/render/LodRender.java +++ b/src/main/java/com/seibel/lod/render/LodRender.java @@ -3,6 +3,7 @@ package com.seibel.lod.render; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; +import java.util.HashSet; import org.lwjgl.opengl.GL11; @@ -25,11 +26,14 @@ import net.minecraft.client.renderer.ActiveRenderInfo; import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.FogRenderer; import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.client.renderer.WorldRenderer; import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.renderer.vertex.VertexBuffer; import net.minecraft.client.renderer.vertex.VertexFormat; import net.minecraft.potion.Effects; import net.minecraft.profiler.IProfiler; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.ChunkPos; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.vector.Matrix4f; import net.minecraft.util.math.vector.Vector3d; @@ -87,7 +91,9 @@ public class LodRender * provided they aren't already being regenerated. */ private boolean regen = false; - + /** This HashSet contains every chunk that Vanilla Minecraft + * is going to render */ + public HashSet vanillaRenderedChunks = new HashSet<>(); @@ -168,8 +174,19 @@ public class LodRender int totalLength = (int) farPlaneDistance * LodConfig.CLIENT.lodChunkRadiusMultiplier.get() * 2; int numbChunksWide = (totalLength / LodChunk.WIDTH); + // see if the chunks Minecraft is going to render are the + // same as last time + // (This is done so we only render LODs ) + HashSet newRenderedChunks = getRenderedChunks(); + if (!vanillaRenderedChunks.containsAll(newRenderedChunks)) + { + regen = true; + vanillaRenderedChunks = newRenderedChunks; + } + + //=================// // create the LODs // @@ -636,4 +653,37 @@ public class LodRender + /** + * This method returns the ChunkPos of all chunks that Minecraft + * is going to render this frame.

+ * + * Note: This isn't perfect. It will return some chunks that are outside + * the clipping plane. (For example, if you are high above the ground some chunks + * will be incorrectly added, even though they are outside render range). + */ + public static HashSet getRenderedChunks() + { + HashSet loadedPos = new HashSet<>(); + + Minecraft mc = Minecraft.getInstance(); + + // Wow those are some long names! + + // go through every RenderInfo to get the compiled chunks + for(WorldRenderer.LocalRenderInformationContainer + worldrenderer$localrenderinformationcontainer : mc.worldRenderer.renderInfos) + { + if (!worldrenderer$localrenderinformationcontainer.renderChunk.getCompiledChunk().isEmpty()) + { + // add the ChunkPos for every empty compiled chunk + BlockPos bpos = worldrenderer$localrenderinformationcontainer.renderChunk.getPosition(); + + loadedPos.add(new ChunkPos(bpos.getX() / 16, bpos.getZ() / 16)); + } + } + + return loadedPos; + } + + } \ No newline at end of file diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg index 3aa800305..29413c7ff 100644 --- a/src/main/resources/META-INF/accesstransformer.cfg +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -16,6 +16,10 @@ public net.minecraft.world.storage.DimensionSavedDataManager field_215759_d # fo # used when generating LodChunks public net.minecraft.block.AbstractBlock$AbstractBlockState field_235704_h_ # materialColor +# used when determining which chunks Vanilla Minecraft is going to render +public net.minecraft.client.renderer.WorldRenderer$LocalRenderInformationContainer +public net.minecraft.client.renderer.WorldRenderer field_72755_R # renderInfos +public net.minecraft.client.renderer.WorldRenderer$LocalRenderInformationContainer field_178036_a # renderChunk #=====================#