diff --git a/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java b/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java
index 676a3d275..4e78f3612 100644
--- a/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java
+++ b/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java
@@ -112,6 +112,8 @@ public class LodBufferBuilder
private volatile ChunkPos drawableCenterChunkPos = new ChunkPos(0,0);
private volatile ChunkPos buildableCenterChunkPos = new ChunkPos(0,0);
+
+
public LodBufferBuilder()
{
@@ -146,8 +148,6 @@ public class LodBufferBuilder
ChunkPos playerChunkPos = new ChunkPos(playerBlockPos);
BlockPos playerBlockPosRounded = playerChunkPos.getWorldPosition();
- // this will be the center of the VBOs once they have been built
- buildableCenterChunkPos = playerChunkPos;
Thread thread = new Thread(() ->
{
@@ -180,7 +180,8 @@ public class LodBufferBuilder
if (setsToRender.length != lodDim.regions.length)
setsToRender = new Object[lodDim.regions.length][lodDim.regions.length];
-
+ // this will be the center of the VBOs once they have been built
+ buildableCenterChunkPos = playerChunkPos;
for (int xRegion = 0; xRegion < lodDim.regions.length; xRegion++)
{
@@ -249,7 +250,6 @@ public class LodBufferBuilder
// skip any chunks that Minecraft is going to render
try
{
- boolean disableFix = false;
if (lodDim.doesDataExist(detailLevel, posX, posZ))
{
lodData = lodDim.getData(detailLevel, posX, posZ);
@@ -263,20 +263,21 @@ public class LodBufferBuilder
if (gameChunkRenderDistance >= Math.abs(chunkXdist) && gameChunkRenderDistance >= Math.abs(chunkZdist))
{
+
if (!renderer.vanillaRenderedChunks[chunkXdist + gameChunkRenderDistance + 1][chunkZdist + gameChunkRenderDistance + 1]
- && (posToRender.contains(detailLevel, xAdj, zAdj) || disableFix))
+ && posToRender.contains(detailLevel, xAdj, zAdj))
{
adjData[direction]= lodDim.getData(detailLevel, xAdj, zAdj);
}
} else
{
- if (posToRender.contains(detailLevel, xAdj, zAdj) || disableFix)
+ if (posToRender.contains(detailLevel, xAdj, zAdj))
{
adjData[direction] = lodDim.getData(detailLevel, xAdj, zAdj);
}
}
}
- LodConfig.CLIENT.graphics.lodTemplate.get().template.addLodToBuffer(currentBuffer, playerBlockPos, lodData, adjData,
+ LodConfig.CLIENT.graphics.lodTemplate.get().template.addLodToBuffer(currentBuffer, playerBlockPosRounded, lodData, adjData,
detailLevel, posX, posZ, renderer.previousDebugMode);
}
} catch (ArrayIndexOutOfBoundsException e)
@@ -451,6 +452,8 @@ public class LodBufferBuilder
}
}
+
+
/**
* Get the newly created VBOs
*/
diff --git a/src/main/java/com/seibel/lod/builders/lodTemplates/CubicLodTemplate.java b/src/main/java/com/seibel/lod/builders/lodTemplates/CubicLodTemplate.java
index 147ea9982..234f6ba57 100644
--- a/src/main/java/com/seibel/lod/builders/lodTemplates/CubicLodTemplate.java
+++ b/src/main/java/com/seibel/lod/builders/lodTemplates/CubicLodTemplate.java
@@ -47,7 +47,7 @@ public class CubicLodTemplate extends AbstractLodTemplate
}
@Override
- public void addLodToBuffer(BufferBuilder buffer, BlockPos playerBlockPos, long data, long[] adjData,
+ public void addLodToBuffer(BufferBuilder buffer, BlockPos bufferCenterBlockPos, long data, long[] adjData,
byte detailLevel, int posX, int posZ,DebugMode debugging)
{
AxisAlignedBB bbox;
@@ -60,7 +60,8 @@ public class CubicLodTemplate extends AbstractLodTemplate
width,
posX * width,
0,
- posZ * width);
+ posZ * width,
+ bufferCenterBlockPos);
int color = DataPoint.getColor(data);
if (debugging != DebugMode.OFF)
@@ -70,12 +71,12 @@ public class CubicLodTemplate extends AbstractLodTemplate
if (bbox != null)
{
- addBoundingBoxToBuffer(buffer, bbox, color, playerBlockPos, adjData);
+ addBoundingBoxToBuffer(buffer, bbox, color, bufferCenterBlockPos, adjData);
}
}
- private AxisAlignedBB generateBoundingBox(int height, int depth, int width, double xOffset, double yOffset, double zOffset)
+ private AxisAlignedBB generateBoundingBox(int height, int depth, int width, double xOffset, double yOffset, double zOffset, BlockPos bufferCenterBlockPos)
{
// don't add an LOD if it is empty
if (height == -1 && depth == -1)
@@ -88,7 +89,13 @@ public class CubicLodTemplate extends AbstractLodTemplate
height++;
}
- return new AxisAlignedBB(0, depth, 0, width, height, width).move(xOffset, yOffset, zOffset);
+ // offset the AABB by it's x/z position in the world since
+ // it uses doubles to specify its location, unlike the model view matrix
+ // which only uses floats
+ double x = -bufferCenterBlockPos.getX();
+ double z = -bufferCenterBlockPos.getZ();
+
+ return new AxisAlignedBB(0, depth, 0, width, height, width).move(xOffset, yOffset, zOffset).move(x, 0, z);
}
private void addBoundingBoxToBuffer(BufferBuilder buffer, AxisAlignedBB bb, int c, BlockPos playerBlockPos, long[] adjData)
diff --git a/src/main/java/com/seibel/lod/handlers/LodDimensionFileHandler.java b/src/main/java/com/seibel/lod/handlers/LodDimensionFileHandler.java
index 8dfe98099..8a133fa2e 100644
--- a/src/main/java/com/seibel/lod/handlers/LodDimensionFileHandler.java
+++ b/src/main/java/com/seibel/lod/handlers/LodDimensionFileHandler.java
@@ -88,7 +88,7 @@ public class LodDimensionFileHandler
* file handler, older versions (smaller numbers) will be deleted and overwritten,
* newer versions (larger numbers) will be ignored and won't be read.
*/
- public static final int LOD_SAVE_FILE_VERSION = 4;
+ public static final int LOD_SAVE_FILE_VERSION = 5;
/**
* This is the string written before the file version
diff --git a/src/main/java/com/seibel/lod/render/LodRenderer.java b/src/main/java/com/seibel/lod/render/LodRenderer.java
index 4e5f25015..98802c72e 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.LevelPosUtil;
import org.lwjgl.opengl.GL;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.NVFogDistance;
@@ -56,8 +57,8 @@ import net.minecraft.entity.Entity;
import net.minecraft.potion.EffectInstance;
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.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.vector.Matrix4f;
import net.minecraft.util.math.vector.Vector3d;
@@ -69,7 +70,7 @@ import net.minecraft.util.math.vector.Vector3f;
* This is where LODs are draw to the world.
*
* @author James Seibel
- * @version 9-6-2021
+ * @version 8-31-2021
*/
public class LodRenderer
{
@@ -78,7 +79,7 @@ public class LodRenderer
* it should be something different than what is used by Minecraft
*/
private static final int LOD_GL_LIGHT_NUMBER = GL11.GL_LIGHT2;
-
+
/**
* 64 MB by default is the maximum amount of memory that
* can be directly allocated.
@@ -91,80 +92,78 @@ public class LodRenderer
* https://stackoverflow.com/questions/50499238/bytebuffer-allocatedirect-and-xmx
*/
public static final int MAX_ALOCATEABLE_DIRECT_MEMORY = 64 * 1024 * 1024;
-
+
/**
* Does this computer's GPU support fancy fog?
*/
private static Boolean fancyFogAvailable = null;
-
-
+
+
/**
* If true the LODs colors will be replaced with
* a checkerboard, this can be used for debugging.
*/
public DebugMode previousDebugMode = DebugMode.OFF;
-
+
private MinecraftWrapper mc;
private GameRenderer gameRender;
private IProfiler profiler;
private int farPlaneBlockDistance;
private ReflectionHandler reflectionHandler;
-
-
+
+
/**
* This is used to generate the buildable buffers
*/
private LodBufferBuilder lodBufferBuilder;
-
+
/**
* Each VertexBuffer represents 1 region
*/
private VertexBuffer[][] vbos;
public static final VertexFormat LOD_VERTEX_FORMAT = DefaultVertexFormats.POSITION_COLOR;
private ChunkPos vbosCenter = new ChunkPos(0,0);
-
+
/**
* This is used to determine if the LODs should be regenerated
*/
- private byte previousDetailLevel = 0;
- private int previousChunkPosX = 0;
- private int previousChunkPosZ = 0;
+ private int[] previousPos = new int[]{0,0,0};
private int prevRenderDistance = 0;
private long prevPlayerPosTime = 0;
private long prevVanillaChunkTime = 0;
private long prevChunkTime = 0;
-
-
+
+
/**
* This is used to determine if the LODs should be regenerated
*/
private FogDistance prevFogDistance = FogDistance.NEAR_AND_FAR;
-
+
/**
* if this is true the LOD buffers should be regenerated,
* provided they aren't already being regenerated.
*/
private volatile boolean partialRegen = false;
private volatile boolean fullRegen = true;
-
+
/**
* This HashSet contains every chunk that Vanilla Minecraft
* is going to render
*/
public boolean[][] vanillaRenderedChunks;
public boolean vanillaRenderedChunksChanged;
-
-
+
+
public LodRenderer(LodBufferBuilder newLodNodeBufferBuilder)
{
mc = MinecraftWrapper.INSTANCE;
gameRender = mc.getGameRenderer();
-
+
reflectionHandler = new ReflectionHandler();
lodBufferBuilder = newLodNodeBufferBuilder;
}
-
-
+
+
/**
* Besides drawing the LODs this method also starts
* the async process of generating the Buffers that hold those LODs.
@@ -180,37 +179,37 @@ public class LodRenderer
// don't try drawing anything
return;
}
-
-
+
+
//===============//
// initial setup //
//===============//
-
+
profiler = newProfiler;
profiler.push("LOD setup");
-
-
+
+
// only check the GPU capability's once
if (fancyFogAvailable == null)
{
// see if this GPU can run fancy fog
fancyFogAvailable = GL.getCapabilities().GL_NV_fog_distance;
-
+
if (!fancyFogAvailable)
{
ClientProxy.LOGGER.info("This GPU does not support GL_NV_fog_distance. This means that fancy fog options will not be available.");
}
}
-
-
+
+
// TODO move the buffer regeneration logic into its own class (probably called in the client proxy instead)
// starting here...
determineIfLodsShouldRegenerate(lodDim);
-
+
//=================//
// create the LODs //
//=================//
-
+
// only regenerate the LODs if:
// 1. we want to regenerate LODs
// 2. we aren't already regenerating the LODs
@@ -220,78 +219,87 @@ public class LodRenderer
{
// generate the LODs on a separate thread to prevent stuttering or freezing
lodBufferBuilder.generateLodBuffersAsync(this, lodDim, mc.getPlayer().blockPosition(), true);
-
+
// the regen process has been started,
// it will be done when lodBufferBuilder.newBuffersAvaliable()
// is true
fullRegen = false;
partialRegen = false;
}
-
+
// TODO move the buffer regeneration logic into its own class (probably called in the client proxy instead)
// ...ending here
-
-
-
+
+ // replace the buffers used to draw and build,
+ // this is only done when the createLodBufferGenerationThread
+ // has finished executing on a parallel thread.
+ if (lodBufferBuilder.newBuffersAvaliable())
+ {
+ swapBuffers();
+ }
+
+
+
//===========================//
// GL settings for rendering //
//===========================//
-
+
// set the required open GL settings
-
+
if (LodConfig.CLIENT.debugging.debugMode.get() == DebugMode.SHOW_DETAIL_WIREFRAME)
GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_LINE);
else
GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_FILL);
-
+
GL11.glDisable(GL11.GL_TEXTURE_2D);
GL11.glEnable(GL11.GL_CULL_FACE);
GL11.glEnable(GL11.GL_COLOR_MATERIAL);
GL11.glEnable(GL11.GL_DEPTH_TEST);
-
+
// disable the lights Minecraft uses
GL11.glDisable(GL11.GL_LIGHT0);
GL11.glDisable(GL11.GL_LIGHT1);
-
+
// get the default projection matrix so we can
// reset it after drawing the LODs
float[] defaultProjMatrix = new float[16];
GL11.glGetFloatv(GL11.GL_PROJECTION_MATRIX, defaultProjMatrix);
-
+
Matrix4f modelViewMatrix = generateModelViewMatrix(partialTicks);
-
+
// required for setupFog and setupProjectionMatrix
farPlaneBlockDistance = LodConfig.CLIENT.graphics.lodChunkRenderDistance.get() * LodUtil.CHUNK_WIDTH;
-
+
setupProjectionMatrix(partialTicks);
setupLighting(lodDim, partialTicks);
-
+
NearFarFogSettings fogSettings = determineFogSettings();
-
+
// determine the current fog settings so they can be
// reset after drawing the LODs
float defaultFogStartDist = GL11.glGetFloat(GL11.GL_FOG_START);
float defaultFogEndDist = GL11.glGetFloat(GL11.GL_FOG_END);
int defaultFogMode = GL11.glGetInteger(GL11.GL_FOG_MODE);
int defaultFogDistance = GL11.glGetInteger(NVFogDistance.GL_FOG_DISTANCE_MODE_NV);
-
-
+
+
//===========//
// rendering //
//===========//
profiler.popPush("LOD draw");
-
+
if (vbos != null)
{
Entity cameraEntity = mc.getCameraEntity();
Vector3d cameraDir = cameraEntity.getLookAngle().normalize();
cameraDir = mc.getOptions().getCameraType().isMirrored() ? cameraDir.reverse() : cameraDir;
-
-
+
+
+
// used to determine what type of fog to render
int halfWidth = vbos.length / 2;
int quarterWidth = vbos.length / 4;
-
+
for (int i = 0; i < vbos.length; i++)
{
for (int j = 0; j < vbos.length; j++)
@@ -303,21 +311,21 @@ public class LodRenderer
setupFog(fogSettings.near.distance, fogSettings.near.quality);
else
setupFog(fogSettings.far.distance, fogSettings.far.quality);
-
-
+
+
sendLodsToGpuAndDraw(vbos[i][j], modelViewMatrix);
}
}
}
}
-
-
+
+
//=========//
// cleanup //
//=========//
-
+
profiler.popPush("LOD cleanup");
-
+
GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_FILL);
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glDisable(LOD_GL_LIGHT_NUMBER);
@@ -325,23 +333,23 @@ public class LodRenderer
GL11.glEnable(GL11.GL_LIGHT0);
GL11.glEnable(GL11.GL_LIGHT1);
RenderSystem.disableLighting();
-
+
// reset the fog settings so the normal chunks
// will be drawn correctly
cleanupFog(fogSettings, defaultFogStartDist, defaultFogEndDist, defaultFogMode, defaultFogDistance);
-
+
// reset the projection matrix so anything drawn after
// the LODs will use the correct projection matrix
Matrix4f mvm = new Matrix4f(defaultProjMatrix);
mvm.transpose();
gameRender.resetProjectionMatrix(mvm);
-
+
// clear the depth buffer so anything drawn is drawn
// over the LODs
GL11.glClear(GL11.GL_DEPTH_BUFFER_BIT);
-
-
-
+
+
+
// replace the buffers used to draw and build,
// this is only done when the createLodBufferGenerationThread
// has finished executing on a parallel thread.
@@ -351,13 +359,13 @@ public class LodRenderer
// otherwise rubber banding may occur
swapBuffers();
}
-
-
+
+
// end of internal LOD profiling
profiler.pop();
}
-
-
+
+
/**
* This is where the actual drawing happens.
*/
@@ -365,22 +373,22 @@ public class LodRenderer
{
if (vbo == null)
return;
-
+
vbo.bind();
// 0L is the starting pointer
LOD_VERTEX_FORMAT.setupBufferState(0L);
-
+
vbo.draw(modelViewMatrix, GL11.GL_QUADS);
-
+
VertexBuffer.unbind();
LOD_VERTEX_FORMAT.clearBufferState();
}
-
-
+
+
//=================//
// Setup Functions //
//=================//
-
+
@SuppressWarnings("deprecation")
private void setupFog(FogDistance fogDistance, FogQuality fogQuality)
{
@@ -390,12 +398,12 @@ public class LodRenderer
RenderSystem.disableFog();
return;
}
-
+
if (fogDistance == FogDistance.NEAR_AND_FAR)
{
throw new IllegalArgumentException("setupFog doesn't accept the NEAR_AND_FAR fog distance.");
}
-
+
// determine the fog distance mode to use
int glFogDistanceMode;
if (fogQuality == FogQuality.FANCY)
@@ -408,7 +416,7 @@ public class LodRenderer
// fast fog (frustum distance based fog)
glFogDistanceMode = NVFogDistance.GL_EYE_PLANE_ABSOLUTE_NV;
}
-
+
// the multipliers are percentages
// of the regular view distance.
if (fogDistance == FogDistance.FAR)
@@ -417,7 +425,7 @@ public class LodRenderer
// is because we are using fog backwards to how
// it is normally used, with it hiding near objects
// instead of far objects.
-
+
if (fogQuality == FogQuality.FANCY)
{
// for more realistic fog when using FAR
@@ -452,37 +460,37 @@ public class LodRenderer
RenderSystem.fogStart(mc.getRenderDistance() * 16 * 1.5f);
}
}
-
+
GL11.glEnable(GL11.GL_FOG);
RenderSystem.enableFog();
RenderSystem.setupNvFogDistance();
RenderSystem.fogMode(GlStateManager.FogMode.LINEAR);
GL11.glFogi(NVFogDistance.GL_FOG_DISTANCE_MODE_NV, glFogDistanceMode);
}
-
+
/**
* Revert any changes that were made to the fog.
*/
private void cleanupFog(NearFarFogSettings fogSettings,
- float defaultFogStartDist, float defaultFogEndDist,
- int defaultFogMode, int defaultFogDistance)
+ float defaultFogStartDist, float defaultFogEndDist,
+ int defaultFogMode, int defaultFogDistance)
{
RenderSystem.fogStart(defaultFogStartDist);
RenderSystem.fogEnd(defaultFogEndDist);
RenderSystem.fogMode(defaultFogMode);
GL11.glFogi(NVFogDistance.GL_FOG_DISTANCE_MODE_NV, defaultFogDistance);
-
+
// disable fog if Minecraft wasn't rendering fog
// but we were
if (!fogSettings.vanillaIsRenderingFog &&
- (fogSettings.near.quality != FogQuality.OFF ||
- fogSettings.far.quality != FogQuality.OFF))
+ (fogSettings.near.quality != FogQuality.OFF ||
+ fogSettings.far.quality != FogQuality.OFF))
{
GL11.glDisable(GL11.GL_FOG);
}
}
-
-
+
+
/**
* Create the model view matrix to move the LODs
* from object space into world space.
@@ -492,8 +500,8 @@ public class LodRenderer
// get all relevant camera info
ActiveRenderInfo renderInfo = mc.getGameRenderer().getMainCamera();
Vector3d projectedView = renderInfo.getPosition();
-
-
+
+
// generate the model view matrix
MatrixStack matrixStack = new MatrixStack();
matrixStack.pushPose();
@@ -508,11 +516,11 @@ public class LodRenderer
double xDiff = eyePos.x - bufferPos.getX();
double zDiff = eyePos.z - bufferPos.getZ();
matrixStack.translate(-xDiff, -projectedView.y, -zDiff);
-
+
return matrixStack.last().pose();
}
-
-
+
+
/**
* create a new projection matrix and send it over to the GPU
*
@@ -530,16 +538,16 @@ public class LodRenderer
// Note: if the LOD objects don't distort correctly
// compared to regular minecraft terrain, make sure
// all the transformations in renderWorld are here too
-
+
MatrixStack matrixStack = new MatrixStack();
matrixStack.pushPose();
-
+
gameRender.bobHurt(matrixStack, partialTicks);
if (this.mc.getOptions().bobView)
{
gameRender.bobView(matrixStack, partialTicks);
}
-
+
// potion and nausea effects
float f = MathHelper.lerp(partialTicks, this.mc.getPlayer().oPortalTime, this.mc.getPlayer().portalTime) * this.mc.getOptions().screenEffectScale * this.mc.getOptions().screenEffectScale;
if (f > 0.0F)
@@ -553,8 +561,8 @@ public class LodRenderer
float f2 = -(gameRender.tick + partialTicks) * i;
matrixStack.mulPose(vector3f.rotationDegrees(f2));
}
-
-
+
+
// this projection matrix allows us to see past the normal
// world render distance
Matrix4f projectionMatrix =
@@ -566,14 +574,14 @@ public class LodRenderer
// terrain, so I don't think it is much of an issue.
mc.getRenderDistance(),
farPlaneBlockDistance * LodUtil.CHUNK_WIDTH * 2);
-
+
// add the screen space distortions
projectionMatrix.multiply(matrixStack.last().pose());
gameRender.resetProjectionMatrix(projectionMatrix);
return;
}
-
-
+
+
/**
* setup the lighting to be used for the LODs
*/
@@ -594,27 +602,27 @@ public class LodRenderer
}
}
}
-
-
+
+
float sunBrightness = lodDimension.dimension.hasSkyLight() ? mc.getSkyDarken(partialTicks) : 0.2f;
sunBrightness = playerHasNightVision ? 1.0f : sunBrightness;
float gammaMultiplyer = (float) mc.getOptions().gamma - 0.5f;
float lightStrength = ((sunBrightness / 2f) - 0.2f) + (gammaMultiplyer * 0.3f);
-
+
float lightAmbient[] = {lightStrength, lightStrength, lightStrength, 1.0f};
-
+
// can be used for debugging
// if (partialTicks < 0.005)
// ClientProxy.LOGGER.debug(lightStrength);
-
+
ByteBuffer temp = ByteBuffer.allocateDirect(16);
temp.order(ByteOrder.nativeOrder());
GL11.glLightfv(LOD_GL_LIGHT_NUMBER, GL11.GL_AMBIENT, (FloatBuffer) temp.asFloatBuffer().put(lightAmbient).flip());
GL11.glEnable(LOD_GL_LIGHT_NUMBER); // Enable the above lighting
-
+
RenderSystem.enableLighting();
}
-
+
/**
* Create all buffers that will be used.
*/
@@ -622,24 +630,24 @@ public class LodRenderer
{
// calculate the max amount of memory needed (in bytes)
int bufferMemory = RenderUtil.getBufferMemoryForRegion();
-
+
// if the required memory is greater than the
// MAX_ALOCATEABLE_DIRECT_MEMORY lower the lodChunkRadiusMultiplier
// to fit.
if (bufferMemory > MAX_ALOCATEABLE_DIRECT_MEMORY)
{
ClientProxy.LOGGER.warn("setupBuffers tried to allocate too much memory for the BufferBuilders."
- + " It tried to allocate \"" + bufferMemory + "\" bytes, when \"" + MAX_ALOCATEABLE_DIRECT_MEMORY + "\" is the max.");
+ + " It tried to allocate \"" + bufferMemory + "\" bytes, when \"" + MAX_ALOCATEABLE_DIRECT_MEMORY + "\" is the max.");
}
-
+
lodBufferBuilder.setupBuffers(numbRegionsWide, bufferMemory);
}
-
-
+
+
//======================//
// Other Misc Functions //
//======================//
-
+
/**
* If this is called then the next time "drawLODs" is called
* the LODs will be regenerated; the same as if the player moved.
@@ -648,12 +656,12 @@ public class LodRenderer
{
fullRegen = true;
}
-
-
+
+
/**
* Replace the current Vertex Buffers with the newly
* created buffers from the lodBufferBuilder.
- *
+ *
* For some reason this has to be called after the frame has been rendered,
* otherwise visual stuttering/rubber banding may happen. I'm not sure why...
*/
@@ -665,7 +673,7 @@ public class LodRenderer
vbos = result.vbos;
vbosCenter = result.drawableCenterChunkPos;
}
-
+
/**
* Calls the BufferBuilder's destroyBuffers method.
*/
@@ -673,183 +681,183 @@ public class LodRenderer
{
lodBufferBuilder.destroyBuffers();
}
-
-
+
+
private double getFov(float partialTicks, boolean useFovSetting)
{
return mc.getGameRenderer().getFov(mc.getGameRenderer().getMainCamera(), partialTicks, useFovSetting);
}
-
-
+
+
/**
* Return what fog settings should be used when rendering.
*/
private NearFarFogSettings determineFogSettings()
{
NearFarFogSettings fogSettings = new NearFarFogSettings();
-
-
+
+
FogQuality quality = reflectionHandler.getFogQuality();
FogDrawOverride override = LodConfig.CLIENT.graphics.fogDrawOverride.get();
-
-
+
+
if (quality == FogQuality.OFF)
fogSettings.vanillaIsRenderingFog = false;
else
fogSettings.vanillaIsRenderingFog = true;
-
-
+
+
// use any fog overrides the user may have set
switch (override)
{
- case ALWAYS_DRAW_FOG_FANCY:
- quality = FogQuality.FANCY;
- break;
-
- case NEVER_DRAW_FOG:
- quality = FogQuality.OFF;
- break;
-
- case ALWAYS_DRAW_FOG_FAST:
- quality = FogQuality.FAST;
- break;
-
- case USE_OPTIFINE_FOG_SETTING:
- // don't override anything
- break;
+ case ALWAYS_DRAW_FOG_FANCY:
+ quality = FogQuality.FANCY;
+ break;
+
+ case NEVER_DRAW_FOG:
+ quality = FogQuality.OFF;
+ break;
+
+ case ALWAYS_DRAW_FOG_FAST:
+ quality = FogQuality.FAST;
+ break;
+
+ case USE_OPTIFINE_FOG_SETTING:
+ // don't override anything
+ break;
}
-
-
+
+
// only use fancy fog if the user's GPU can deliver
if (!fancyFogAvailable && quality == FogQuality.FANCY)
{
quality = FogQuality.FAST;
}
-
-
+
+
// how different distances are drawn depends on the quality set
switch (quality)
{
- case FANCY:
- fogSettings.near.quality = FogQuality.FANCY;
- fogSettings.far.quality = FogQuality.FANCY;
-
- switch (LodConfig.CLIENT.graphics.fogDistance.get())
- {
- case NEAR_AND_FAR:
- fogSettings.near.distance = FogDistance.NEAR;
- fogSettings.far.distance = FogDistance.FAR;
+ case FANCY:
+ fogSettings.near.quality = FogQuality.FANCY;
+ fogSettings.far.quality = FogQuality.FANCY;
+
+ switch (LodConfig.CLIENT.graphics.fogDistance.get())
+ {
+ case NEAR_AND_FAR:
+ fogSettings.near.distance = FogDistance.NEAR;
+ fogSettings.far.distance = FogDistance.FAR;
+ break;
+
+ case NEAR:
+ fogSettings.near.distance = FogDistance.NEAR;
+ fogSettings.far.distance = FogDistance.NEAR;
+ break;
+
+ case FAR:
+ fogSettings.near.distance = FogDistance.FAR;
+ fogSettings.far.distance = FogDistance.FAR;
+ break;
+ }
break;
-
- case NEAR:
- fogSettings.near.distance = FogDistance.NEAR;
- fogSettings.far.distance = FogDistance.NEAR;
+
+ case FAST:
+ fogSettings.near.quality = FogQuality.FAST;
+ fogSettings.far.quality = FogQuality.FAST;
+
+ // fast fog setting should only have one type of
+ // fog, since the LODs are separated into a near
+ // and far portion; and fast fog is rendered from the
+ // frustrum's perspective instead of the camera
+ switch (LodConfig.CLIENT.graphics.fogDistance.get())
+ {
+ case NEAR_AND_FAR:
+ fogSettings.near.distance = FogDistance.NEAR;
+ fogSettings.far.distance = FogDistance.NEAR;
+ break;
+
+ case NEAR:
+ fogSettings.near.distance = FogDistance.NEAR;
+ fogSettings.far.distance = FogDistance.NEAR;
+ break;
+
+ case FAR:
+ fogSettings.near.distance = FogDistance.FAR;
+ fogSettings.far.distance = FogDistance.FAR;
+ break;
+ }
break;
-
- case FAR:
- fogSettings.near.distance = FogDistance.FAR;
- fogSettings.far.distance = FogDistance.FAR;
+
+ case OFF:
+
+ fogSettings.near.quality = FogQuality.OFF;
+ fogSettings.far.quality = FogQuality.OFF;
break;
- }
- break;
-
- case FAST:
- fogSettings.near.quality = FogQuality.FAST;
- fogSettings.far.quality = FogQuality.FAST;
-
- // fast fog setting should only have one type of
- // fog, since the LODs are separated into a near
- // and far portion; and fast fog is rendered from the
- // frustrum's perspective instead of the camera
- switch (LodConfig.CLIENT.graphics.fogDistance.get())
- {
- case NEAR_AND_FAR:
- fogSettings.near.distance = FogDistance.NEAR;
- fogSettings.far.distance = FogDistance.NEAR;
- break;
-
- case NEAR:
- fogSettings.near.distance = FogDistance.NEAR;
- fogSettings.far.distance = FogDistance.NEAR;
- break;
-
- case FAR:
- fogSettings.near.distance = FogDistance.FAR;
- fogSettings.far.distance = FogDistance.FAR;
- break;
- }
- break;
-
- case OFF:
-
- fogSettings.near.quality = FogQuality.OFF;
- fogSettings.far.quality = FogQuality.OFF;
- break;
-
+
}
-
-
+
+
return fogSettings;
}
-
-
+
+
/**
* Determines if the LODs should have a fullRegen or partialRegen
*/
+ @SuppressWarnings("unchecked")
private void determineIfLodsShouldRegenerate(LodDimension lodDim)
{
-
+ fullRegen = true;
short renderDistance = (short) mc.getRenderDistance();
//=============//
// full regens //
//=============//
// check if the view distance changed
if (ClientProxy.previousLodRenderDistance != LodConfig.CLIENT.graphics.lodChunkRenderDistance.get()
- || mc.getRenderDistance() != prevRenderDistance
- || prevFogDistance != LodConfig.CLIENT.graphics.fogDistance.get())
+ || mc.getRenderDistance() != prevRenderDistance
+ || prevFogDistance != LodConfig.CLIENT.graphics.fogDistance.get())
{
DetailDistanceUtil.updateSettings();
fullRegen = true;
- previousChunkPosX = mc.getPlayer().xChunk;
- previousChunkPosZ = mc.getPlayer().zChunk;
+ previousPos = LevelPosUtil.createLevelPos((byte) 4, mc.getPlayer().xChunk, mc.getPlayer().zChunk);
prevFogDistance = LodConfig.CLIENT.graphics.fogDistance.get();
prevRenderDistance = mc.getRenderDistance();
//should use this when it's ready
vanillaRenderedChunks = new boolean[renderDistance*2+2][renderDistance*2+2];
}
-
+
// did the user change the debug setting?
if (LodConfig.CLIENT.debugging.debugMode.get() != previousDebugMode)
{
previousDebugMode = LodConfig.CLIENT.debugging.debugMode.get();
fullRegen = true;
}
-
-
+Bug
+
long newTime = System.currentTimeMillis();
-
+
// check if the player has moved
if (newTime - prevPlayerPosTime > LodConfig.CLIENT.buffers.bufferRebuildPlayerMoveTimeout.get())
{
- if (mc.getPlayer().xChunk != previousChunkPosX
- || mc.getPlayer().zChunk != previousChunkPosZ)
+ if (LevelPosUtil.getDetailLevel(previousPos) == 0
+ || mc.getPlayer().xChunk != LevelPosUtil.getPosX(previousPos)
+ || mc.getPlayer().zChunk != LevelPosUtil.getPosZ(previousPos))
{
fullRegen = true;
- previousChunkPosX = mc.getPlayer().xChunk;
- previousChunkPosZ = mc.getPlayer().zChunk;
+ previousPos = LevelPosUtil.createLevelPos((byte) 4, mc.getPlayer().xChunk, mc.getPlayer().zChunk);
//should use this when it's ready
vanillaRenderedChunks = new boolean[renderDistance*2+2][renderDistance*2+2];
}
prevPlayerPosTime = newTime;
}
-
-
-
+
+
+
//================//
// partial regens //
//================//
-
-
+
+
// check if the vanilla rendered chunks changed
if (newTime - prevVanillaChunkTime > LodConfig.CLIENT.buffers.bufferRebuildChunkChangeTimeout.get())
{
@@ -857,12 +865,12 @@ public class LodRenderer
{
partialRegen = true;
vanillaRenderedChunksChanged = false;
-
+
}
prevVanillaChunkTime = newTime;
}
-
-
+
+
// check if there is any newly generated terrain to show
if (newTime - prevChunkTime > LodConfig.CLIENT.buffers.bufferRebuildLodChangeTimeout.get())
{
@@ -873,14 +881,14 @@ public class LodRenderer
}
prevChunkTime = newTime;
}
-
-
-
-
+
+
+
+
//==============//
// LOD skipping //
//==============//
-
+
// determine which LODs should not be rendered close to the player
HashSet chunkPosToSkip = LodUtil.getNearbyLodChunkPosToSkip(lodDim, mc.getPlayer().blockPosition());
int chunkX;
@@ -902,8 +910,8 @@ public class LodRenderer
e.printStackTrace();
}
}
-
-
+
+
// if the player is high enough, draw all LODs
if(chunkPosToSkip.isEmpty() && mc.getPlayer().position().y > 256)
{
@@ -911,5 +919,5 @@ public class LodRenderer
vanillaRenderedChunksChanged = true;
}
}
-
-}
\ No newline at end of file
+
+}