From 94d994e761443302a0432a4239b44a444470f29f Mon Sep 17 00:00:00 2001 From: Leonardo Date: Tue, 7 Sep 2021 18:52:58 +0200 Subject: [PATCH] re-added the commit --- .../seibel/lod/builders/LodBufferBuilder.java | 17 +- .../lodTemplates/CubicLodTemplate.java | 17 +- .../lod/handlers/LodDimensionFileHandler.java | 2 +- .../com/seibel/lod/render/LodRenderer.java | 478 +++++++++--------- 4 files changed, 266 insertions(+), 248 deletions(-) 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 + +}