diff --git a/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java b/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java index 0e1176a5f..4523d029b 100644 --- a/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java +++ b/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java @@ -129,11 +129,10 @@ public class LodBufferBuilder // only allow one generation process to happen at a time if (generatingBuffers) return; - + if (buildableBuffers == null) // setupBuffers hasn't been called yet return; - generatingBuffers = true; @@ -166,7 +165,7 @@ public class LodBufferBuilder // =====================// RegionPos playerRegionPos = new RegionPos(playerChunkPos); - if(center == null) + if (center == null) center = playerRegionPos; if (setsToRender == null) @@ -190,101 +189,99 @@ public class LodBufferBuilder xRegion + lodDim.getCenterX() - Math.floorDiv(lodDim.getWidth(), 2), zRegion + lodDim.getCenterZ() - Math.floorDiv(lodDim.getWidth(), 2)); - if(lodDim.regen[xRegion][zRegion]) + // local position in the vbo and bufferBuilder arrays + BufferBuilder currentBuffer = buildableBuffers[xRegion][zRegion]; + + // make sure the buffers weren't + // changed while we were running this method + if (currentBuffer == null || (currentBuffer != null && !currentBuffer.building())) + return; + + if (setsToRender[xRegion][zRegion] == null) { - // local position in the vbo and bufferBuilder arrays - BufferBuilder currentBuffer = buildableBuffers[xRegion][zRegion]; - - // make sure the buffers weren't - // changed while we were running this method - if (currentBuffer == null || (currentBuffer != null && !currentBuffer.building())) - return; - - if (setsToRender[xRegion][zRegion] == null) - { - setsToRender[xRegion][zRegion] = new ConcurrentHashMap(); - } - ConcurrentMap nodeToRender = (ConcurrentMap) setsToRender[xRegion][zRegion]; - - Callable dataToRenderThread = () -> - { - lodDim.getDataToRender( - nodeToRender, - regionPos, - playerBlockPosRounded.getX(), - playerBlockPosRounded.getZ()); - - - int posX; - int posZ; - byte detailLevel; - for (LevelPos posToRender : nodeToRender.keySet()) - { - if (!nodeToRender.get(posToRender).booleanValue()) - { - nodeToRender.remove(posToRender); - continue; - } - nodeToRender.get(posToRender).setFalse(); - // skip any chunks that Minecraft is going to render - - if (renderer.vanillaRenderedChunks.contains(posToRender.getChunkPos())) - { - continue; - } - posX = posToRender.posX; - posZ = posToRender.posZ; - detailLevel = posToRender.detailLevel; - - LevelPos chunkPos = posToRender.getConvertedLevelPos(LodUtil.CHUNK_DETAIL_LEVEL); - // skip any chunks that Minecraft is going to render - - if (renderer.vanillaRenderedChunks.contains(new ChunkPos(chunkPos.posX, chunkPos.posZ))) - { - continue; - } - - try - { - boolean disableFix = false; - if (lodDim.doesDataExist(posToRender.clone())) - { - short[] lodData = lodDim.getData(posToRender); - short[][][] adjData = new short[2][2][]; - for (int x : new int[]{0, 1}) - { - posToRender.changeParameters(detailLevel, posX + x * 2 - 1, posZ); - if (!renderer.vanillaRenderedChunks.contains(posToRender.getChunkPos()) - && (nodeToRender.containsKey(posToRender) || disableFix)) - adjData[0][x] = lodDim.getData(posToRender); - } - - for (int z : new int[]{0, 1}) - { - posToRender.changeParameters(detailLevel, posX, posZ + z * 2 - 1); - if (!renderer.vanillaRenderedChunks.contains(posToRender.getChunkPos()) - && (nodeToRender.containsKey(posToRender) || disableFix)) - adjData[1][z] = lodDim.getData(posToRender); - } - posToRender.changeParameters(detailLevel, posX, posZ); - - LodConfig.CLIENT.lodTemplate.get().template.addLodToBuffer(currentBuffer, playerBlockPos, lodData, adjData, - posToRender, renderer.previousDebugMode); - } - } catch (ArrayIndexOutOfBoundsException e) - { - return false; - } - - }// for pos to in list to render - - // the thread executed successfully - return true; - };// buffer builder worker thread - - - nodeToRenderThreads.add(dataToRenderThread); + setsToRender[xRegion][zRegion] = new ConcurrentHashMap(); } + ConcurrentMap nodeToRender = (ConcurrentMap) setsToRender[xRegion][zRegion]; + + Callable dataToRenderThread = () -> + { + lodDim.getDataToRender( + nodeToRender, + regionPos, + playerBlockPosRounded.getX(), + playerBlockPosRounded.getZ()); + + + int posX; + int posZ; + byte detailLevel; + for (LevelPos posToRender : nodeToRender.keySet()) + { + if (!nodeToRender.get(posToRender).booleanValue()) + { + nodeToRender.remove(posToRender); + continue; + } + nodeToRender.get(posToRender).setFalse(); + // skip any chunks that Minecraft is going to render + + if (renderer.vanillaRenderedChunks.contains(posToRender.getChunkPos())) + { + continue; + } + posX = posToRender.posX; + posZ = posToRender.posZ; + detailLevel = posToRender.detailLevel; + + LevelPos chunkPos = posToRender.getConvertedLevelPos(LodUtil.CHUNK_DETAIL_LEVEL); + // skip any chunks that Minecraft is going to render + + if (renderer.vanillaRenderedChunks.contains(new ChunkPos(chunkPos.posX, chunkPos.posZ))) + { + continue; + } + + try + { + boolean disableFix = false; + if (lodDim.doesDataExist(posToRender.clone())) + { + short[] lodData = lodDim.getData(posToRender); + short[][][] adjData = new short[2][2][]; + for (int x : new int[]{0, 1}) + { + posToRender.changeParameters(detailLevel, posX + x * 2 - 1, posZ); + if (!renderer.vanillaRenderedChunks.contains(posToRender.getChunkPos()) + && (nodeToRender.containsKey(posToRender) || disableFix)) + adjData[0][x] = lodDim.getData(posToRender); + } + + for (int z : new int[]{0, 1}) + { + posToRender.changeParameters(detailLevel, posX, posZ + z * 2 - 1); + if (!renderer.vanillaRenderedChunks.contains(posToRender.getChunkPos()) + && (nodeToRender.containsKey(posToRender) || disableFix)) + adjData[1][z] = lodDim.getData(posToRender); + } + posToRender.changeParameters(detailLevel, posX, posZ); + + LodConfig.CLIENT.lodTemplate.get().template.addLodToBuffer(currentBuffer, playerBlockPos, lodData, adjData, + posToRender, renderer.previousDebugMode); + } + } catch (ArrayIndexOutOfBoundsException e) + { + return false; + } + + }// for pos to in list to render + + // the thread executed successfully + return true; + };// buffer builder worker thread + + + nodeToRenderThreads.add(dataToRenderThread); + }// region z }// region z long renderStart = System.currentTimeMillis(); @@ -358,7 +355,7 @@ public class LodBufferBuilder *

* Synchronized to prevent multiple moves happening on top of each other. */ - public synchronized void move(RegionPos regionOffset,int width) + public synchronized void move(RegionPos regionOffset, int width) { int xOffset = regionOffset.x; int zOffset = regionOffset.z; diff --git a/src/main/java/com/seibel/lod/builders/worldGeneration/LodNodeGenWorker.java b/src/main/java/com/seibel/lod/builders/worldGeneration/LodNodeGenWorker.java index 67745a963..56289b6bc 100644 --- a/src/main/java/com/seibel/lod/builders/worldGeneration/LodNodeGenWorker.java +++ b/src/main/java/com/seibel/lod/builders/worldGeneration/LodNodeGenWorker.java @@ -215,7 +215,7 @@ public class LodNodeGenWorker implements IWorker break; } - lodRenderer.regenerateLODsNextFrame(); + //lodRenderer.regenerateLODsNextFrame(); /* boolean dataExistence = lodDim.doesDataExist(new LevelPos((byte) 3, pos.x, pos.z)); diff --git a/src/main/java/com/seibel/lod/objects/LodDimension.java b/src/main/java/com/seibel/lod/objects/LodDimension.java index 28b8113de..bfe588cf0 100644 --- a/src/main/java/com/seibel/lod/objects/LodDimension.java +++ b/src/main/java/com/seibel/lod/objects/LodDimension.java @@ -70,6 +70,7 @@ public class LodDimension public volatile LodRegion regions[][]; public volatile boolean isRegionDirty[][]; public volatile boolean regen[][]; + public volatile boolean regenDimension = false; private volatile RegionPos center; private volatile ChunkPos lastGenChunk; @@ -419,6 +420,7 @@ public class LodDimension regions[x][z] = new LodRegion(levelToGen, regionPos, generationMode); } regen[x][z] = true; + regenDimension = true; } else if (region.getMinDetailLevel() > levelToGen) { @@ -461,6 +463,7 @@ public class LodDimension int zIndex = (regionPos.z - center.z) + halfWidth; isRegionDirty[xIndex][zIndex] = true; regen[xIndex][zIndex] = true; + regenDimension = true; } catch (ArrayIndexOutOfBoundsException e) { // This method was probably called when the dimension was changing size. diff --git a/src/main/java/com/seibel/lod/render/LodRenderer.java b/src/main/java/com/seibel/lod/render/LodRenderer.java index f266ab89b..9eb04795f 100644 --- a/src/main/java/com/seibel/lod/render/LodRenderer.java +++ b/src/main/java/com/seibel/lod/render/LodRenderer.java @@ -23,6 +23,7 @@ import java.nio.FloatBuffer; import java.util.HashSet; import java.util.Iterator; +import com.seibel.lod.objects.LevelPos.LevelPos; import net.minecraft.world.chunk.Chunk; import org.lwjgl.opengl.GL; import org.lwjgl.opengl.GL11; @@ -124,11 +125,8 @@ public class LodRenderer /** * This is used to determine if the LODs should be regenerated */ - private int prevChunkX = 0; - /** - * This is used to determine if the LODs should be regenerated - */ - private int prevChunkZ = 0; + private LevelPos previousPos = new LevelPos((byte) 0,0,0); + private static long prevTime = 0; /** * This is used to determine if the LODs should be regenerated */ @@ -197,27 +195,34 @@ public class LodRenderer ClientPlayerEntity player = mc.player; - + // should LODs be regenerated? - if ((int) player.getX() / LodUtil.CHUNK_WIDTH != prevChunkX || - (int) player.getZ() / LodUtil.CHUNK_WIDTH != prevChunkZ || - ClientProxy.previousLodRenderDistance != LodConfig.CLIENT.lodChunkRenderDistance.get() || - prevFogDistance != LodConfig.CLIENT.fogDistance.get()) + long newTime = System.currentTimeMillis(); + if(newTime - prevTime > 5000) { - // yes - regen = true; - - prevChunkX = (int) player.getX() / LodUtil.CHUNK_WIDTH; - prevChunkZ = (int) player.getZ() / LodUtil.CHUNK_WIDTH; - prevFogDistance = LodConfig.CLIENT.fogDistance.get(); - vanillaRenderedChunks.clear(); - } else - { - // nope, the player hasn't moved, the - // render distance hasn't changed, and - // the dimension is the same + if (previousPos.detailLevel == 0 || + player.xChunk != previousPos.posX || + player.zChunk != previousPos.posZ || + ClientProxy.previousLodRenderDistance != LodConfig.CLIENT.lodChunkRenderDistance.get() || + prevFogDistance != LodConfig.CLIENT.fogDistance.get()) + { + System.out.println("changing " + previousPos); + // yes + regen = true; + previousPos.changeParameters((byte) 4, player.xChunk, player.zChunk); + prevFogDistance = LodConfig.CLIENT.fogDistance.get(); + vanillaRenderedChunks.clear(); + } + + if(lodDim.regenDimension) + { + regen = true; + lodDim.regenDimension = false; + } + prevTime = newTime; + System.out.println(newTime - prevTime); } - + // did the user change the debug setting? if (LodConfig.CLIENT.debugMode.get() != previousDebugMode) { @@ -239,7 +244,6 @@ public class LodRenderer if(!vanillaRenderedChunks.contains(pos)) { vanillaRenderedChunks.add(pos); - System.out.println(pos); lodDim.setToRegen(pos.getRegionX(),pos.getRegionZ()); } } @@ -264,6 +268,7 @@ public class LodRenderer // (this is to prevent thread conflicts) if (regen && !lodBufferBuilder.generatingBuffers && !lodBufferBuilder.newBuffersAvaliable()) { + System.out.println("redrawing"); // generate the LODs on a separate thread to prevent stuttering or freezing lodBufferBuilder.generateLodBuffersAsync(this, lodDim, player.blockPosition(), Math.floorMod((int) player.xRot,360), Math.floorMod((int) player.yRot,360), numbChunksWide);