diff --git a/src/main/java/com/seibel/lod/builders/bufferBuilding/LodBufferBuilder.java b/src/main/java/com/seibel/lod/builders/bufferBuilding/LodBufferBuilder.java
index 0636b2294..0fcea659f 100644
--- a/src/main/java/com/seibel/lod/builders/bufferBuilding/LodBufferBuilder.java
+++ b/src/main/java/com/seibel/lod/builders/bufferBuilding/LodBufferBuilder.java
@@ -30,6 +30,7 @@ import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.locks.ReentrantLock;
+import com.seibel.lod.enums.VanillaOverdraw;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL15C;
@@ -90,13 +91,6 @@ public class LodBufferBuilder
*/
public static final int DEFAULT_MEMORY_ALLOCATION = 1024;
-
- /** This boolean matrix indicate the buffer builder in that position has to be regenerated */
- public volatile boolean[][] regenPos;
-
- /** This boolean indicates that ever buffer need to be regenerated */
- public volatile boolean fullRegeneration = false;
-
public static int skyLightPlayer = 15;
/**
@@ -195,7 +189,7 @@ public class LodBufferBuilder
Thread thread = new Thread(() ->
- generateLodBuffersThread(renderer, lodDim, playerBlockPos, fullRegen));
+ generateLodBuffersThread(renderer, lodDim, playerBlockPos, fullRegen));
mainGenThread.execute(thread);
}
@@ -302,6 +296,8 @@ public class LodBufferBuilder
if (setsToRender[xR][zR] == null)
setsToRender[xR][zR] = new PosToRenderContainer(minDetail, regionPos.x, regionPos.z);
+
+ //We ask the lod dimension which block we have to render given the player position
PosToRenderContainer posToRender = setsToRender[xR][zR];
posToRender.clear(minDetail, regionPos.x, regionPos.z);
@@ -313,13 +309,10 @@ public class LodBufferBuilder
-
-
// keep a local version, so we don't have to worry about indexOutOfBounds Exceptions
// if it changes in the LodRenderer while we are working here
boolean[][] vanillaRenderedChunks = renderer.vanillaRenderedChunks;
short gameChunkRenderDistance = (short) (vanillaRenderedChunks.length / 2 - 1);
- boolean smallRenderDistance = gameChunkRenderDistance <= 4;
@@ -330,19 +323,18 @@ public class LodBufferBuilder
posX = posToRender.getNthPosX(index);
posZ = posToRender.getNthPosZ(index);
- // skip any chunks that Minecraft is going to render
- chunkXdist = LevelPosUtil.getChunkPos(detailLevel, posX) - playerChunkPos.x;
- chunkZdist = LevelPosUtil.getChunkPos(detailLevel, posZ) - playerChunkPos.z;
- boolean isItBorderPos = LodUtil.isBorderChunk(vanillaRenderedChunks, chunkXdist + gameChunkRenderDistance + 1, chunkZdist + gameChunkRenderDistance + 1);
- if (gameChunkRenderDistance >= Math.abs(chunkXdist)
- && gameChunkRenderDistance >= Math.abs(chunkZdist)
- && detailLevel <= LodUtil.CHUNK_DETAIL_LEVEL
- && vanillaRenderedChunks[chunkXdist + gameChunkRenderDistance + 1][chunkZdist + gameChunkRenderDistance + 1]
- && (!isItBorderPos || smallRenderDistance))
+ //We don't want to render this fake block if
+ //The block is inside the render distance with, is not bigger than a chunk and is positioned in a chunk set as vanilla rendered
+ //
+ //The block is in the player chunk or in a chunk adjacent to the player
+ if(isThisPositionGoingToBeRendered(detailLevel, posX, posZ, playerChunkPos, vanillaRenderedChunks, gameChunkRenderDistance))
{
continue;
}
+
+ // We extract the adj data in the four cardinal direction
+
Arrays.fill(adjShadeDisabled, false);
// skip any chunks that Minecraft is going to render
for (Direction direction : Box.ADJ_DIRECTIONS)
@@ -351,34 +343,41 @@ public class LodBufferBuilder
zAdj = posZ + Box.DIRECTION_NORMAL_MAP.get(direction).getZ();
chunkXdist = LevelPosUtil.getChunkPos(detailLevel, xAdj) - playerChunkPos.x;
chunkZdist = LevelPosUtil.getChunkPos(detailLevel, zAdj) - playerChunkPos.z;
- if (posToRender.contains(detailLevel, xAdj, zAdj)
- && (gameChunkRenderDistance < Math.abs(chunkXdist)
- || gameChunkRenderDistance < Math.abs(chunkZdist)
- || !(vanillaRenderedChunks[chunkXdist + gameChunkRenderDistance + 1][chunkZdist + gameChunkRenderDistance + 1]
- && (!LodUtil.isBorderChunk(vanillaRenderedChunks, chunkXdist + gameChunkRenderDistance + 1, chunkZdist + gameChunkRenderDistance + 1) || smallRenderDistance))))
+ if(/*posToRender.contains(detailLevel, xAdj, zAdj)
+ &&*/ !isThisPositionGoingToBeRendered(detailLevel, xAdj, zAdj, playerChunkPos, vanillaRenderedChunks, gameChunkRenderDistance))
+ /*if (posToRender.contains(detailLevel, xAdj, zAdj)
+ && (gameChunkRenderDistance < Math.abs(chunkXdist)
+ || gameChunkRenderDistance < Math.abs(chunkZdist)
+ || !(vanillaRenderedChunks[chunkXdist + gameChunkRenderDistance + 1][chunkZdist + gameChunkRenderDistance + 1]
+ && (!LodUtil.isBorderChunk(vanillaRenderedChunks, chunkXdist + gameChunkRenderDistance + 1, chunkZdist + gameChunkRenderDistance + 1) || smallRenderDistance))))*/
{
for (int verticalIndex = 0; verticalIndex < lodDim.getMaxVerticalData(detailLevel, xAdj, zAdj); verticalIndex++)
{
long data = lodDim.getData(detailLevel, xAdj, zAdj, verticalIndex);
+ adjShadeDisabled[Box.DIRECTION_INDEX.get(direction)] = DataPointUtil.getAlpha(data) < 255;
adjData.get(direction)[verticalIndex] = data;
}
}
else
{
- if (gameChunkRenderDistance >= Math.abs(chunkXdist)
- && gameChunkRenderDistance >= Math.abs(chunkZdist)
- && (!LodUtil.isBorderChunk(vanillaRenderedChunks, chunkXdist + gameChunkRenderDistance + 1, chunkZdist + gameChunkRenderDistance + 1) || smallRenderDistance)
- && vanillaRenderedChunks[chunkXdist + gameChunkRenderDistance + 1][chunkZdist + gameChunkRenderDistance + 1]
- && !DataPointUtil.isVoid(lodDim.getSingleData(detailLevel, xAdj, zAdj)))
+ if (!isThisPositionGoingToBeRendered(detailLevel, xAdj, zAdj, playerChunkPos, vanillaRenderedChunks, gameChunkRenderDistance)
+ && !DataPointUtil.isVoid(lodDim.getSingleData(detailLevel, xAdj, zAdj)))
+ {
adjShadeDisabled[Box.DIRECTION_INDEX.get(direction)] = DataPointUtil.getAlpha(lodDim.getSingleData(detailLevel, xAdj, zAdj)) < 255;
- adjData.get(direction)[0] = DataPointUtil.EMPTY_DATA;
+ adjData.get(direction)[0] = DataPointUtil.EMPTY_DATA;
+ }
}
}
+
+ // We render every vertical lod present in this position
+ // We only stop when we find a block that is void or non existing block
long data;
for (int verticalIndex = 0; verticalIndex < lodDim.getMaxVerticalData(detailLevel, posX, posZ); verticalIndex++)
{
- if(verticalIndex > 0)
+
+ //we get the above block as adj UP
+ if (verticalIndex > 0)
{
adjData.get(Direction.UP)[0] = lodDim.getData(detailLevel, posX, posZ, verticalIndex - 1);
}
@@ -388,7 +387,8 @@ public class LodBufferBuilder
}
- if(verticalIndex < lodDim.getMaxVerticalData(detailLevel, posX, posZ) - 1)
+ //we get the below block as adj DOWN
+ if (verticalIndex < lodDim.getMaxVerticalData(detailLevel, posX, posZ) - 1)
{
adjData.get(Direction.DOWN)[0] = lodDim.getData(detailLevel, posX, posZ, verticalIndex + 1);
}
@@ -397,10 +397,14 @@ public class LodBufferBuilder
adjData.get(Direction.DOWN)[0] = DataPointUtil.EMPTY_DATA;
}
+ //We extract the data to render
data = lodDim.getData(detailLevel, posX, posZ, verticalIndex);
+
+ //If the data is not renderable (Void or non existing) we stop since there is no data left in this position
if (DataPointUtil.isVoid(data) || !DataPointUtil.doesItExist(data))
break;
-
+
+ //We send the call to create the vertices
LodConfig.CLIENT.graphics.advancedGraphicsOption.lodTemplate.get().template.addLodToBuffer(currentBuffers[bufferIndex], playerBlockPosRounded, data, adjData,
detailLevel, posX, posZ, box, renderer.previousDebugMode, renderer.lightMap, adjShadeDisabled);
}
@@ -476,6 +480,34 @@ public class LodBufferBuilder
}
}
+ private boolean isThisPositionGoingToBeRendered(byte detailLevel, int posX, int posZ, ChunkPos playerChunkPos, boolean[][] vanillaRenderedChunks, int gameChunkRenderDistance){
+
+
+ // skip any chunks that Minecraft is going to render
+ int chunkXdist = LevelPosUtil.getChunkPos(detailLevel, posX) - playerChunkPos.x;
+ int chunkZdist = LevelPosUtil.getChunkPos(detailLevel, posZ) - playerChunkPos.z;
+
+ boolean isItBorderPos;
+ if (LodConfig.CLIENT.graphics.advancedGraphicsOption.vanillaOverdraw.get() == VanillaOverdraw.NEVER)
+ isItBorderPos = LodUtil.isBorderChunk(vanillaRenderedChunks, chunkXdist + gameChunkRenderDistance + 1, chunkZdist + gameChunkRenderDistance + 1);
+ else
+ isItBorderPos = false;
+
+ boolean nearPlayer = Math.abs(chunkXdist) <= 1 && Math.abs(chunkZdist) <= 1;;
+ boolean smallRenderDistance = gameChunkRenderDistance <= 4;
+
+
+ //We check if the position is
+
+ return (gameChunkRenderDistance >= Math.abs(chunkXdist)
+ && gameChunkRenderDistance >= Math.abs(chunkZdist)
+ && detailLevel <= LodUtil.CHUNK_DETAIL_LEVEL
+ && vanillaRenderedChunks[chunkXdist + gameChunkRenderDistance + 1][chunkZdist + gameChunkRenderDistance + 1]
+ && (!isItBorderPos || smallRenderDistance)
+ || nearPlayer);
+ }
+
+
@@ -584,6 +616,8 @@ public class LodBufferBuilder
bufferLock.unlock();
}
+
+
/**
* Sets the buffers and Vbos to null, forcing them to be recreated
* and destroys any bound OpenGL objects.
@@ -611,7 +645,8 @@ public class LodBufferBuilder
// called we aren't worried about stuttering anyway.
// This way we don't have to worry about what context this
// was called from (if any).
- RenderSystem.recordRenderCall(() -> {
+ RenderSystem.recordRenderCall(() ->
+ {
GL45.glDeleteBuffers(buildableId);
GL45.glDeleteBuffers(drawableId);
});
@@ -652,7 +687,8 @@ public class LodBufferBuilder
drawableId = 0;
- RenderSystem.recordRenderCall(() -> {
+ RenderSystem.recordRenderCall(() ->
+ {
if (buildableId != 0)
GL45.glDeleteBuffers(buildableId);
if (drawableId != 0)