From 5467d007b8fd59c04dfd55fb1b1b118150f4c2ab Mon Sep 17 00:00:00 2001 From: Leonardo Date: Mon, 30 Aug 2021 12:36:07 +0200 Subject: [PATCH] preparing the mod for future buffer caching --- .../seibel/lod/builders/LodBufferBuilder.java | 56 +- .../com/seibel/lod/render/LodRenderer.java | 480 +++++++++--------- 2 files changed, 281 insertions(+), 255 deletions(-) diff --git a/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java b/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java index 4523d029b..d18fb0556 100644 --- a/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java +++ b/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java @@ -124,7 +124,7 @@ public class LodBufferBuilder * swapped with the drawable buffers in the LodRenderer to be drawn. */ public void generateLodBuffersAsync(LodRenderer renderer, LodDimension lodDim, - BlockPos playerBlockPos, int xAngle, int yAngle, int numbChunksWide) + BlockPos playerBlockPos, boolean fullRegen) { // only allow one generation process to happen at a time if (generatingBuffers) @@ -158,7 +158,7 @@ public class LodBufferBuilder ArrayList> nodeToRenderThreads = new ArrayList<>(lodDim.regions.length * lodDim.regions.length); - startBuffers(); + startBuffers(fullRegen, lodDim); // =====================// // RENDERING PART // @@ -185,6 +185,8 @@ public class LodBufferBuilder { for (int zRegion = 0; zRegion < lodDim.regions.length; zRegion++) { + //if (lodDim.regen[xRegion][zRegion]) + // ClientProxy.LOGGER.debug("Rendering region " + xRegion + " " + zRegion); RegionPos regionPos = new RegionPos( xRegion + lodDim.getCenterX() - Math.floorDiv(lodDim.getWidth(), 2), zRegion + lodDim.getCenterZ() - Math.floorDiv(lodDim.getWidth(), 2)); @@ -202,15 +204,19 @@ public class LodBufferBuilder setsToRender[xRegion][zRegion] = new ConcurrentHashMap(); } ConcurrentMap nodeToRender = (ConcurrentMap) setsToRender[xRegion][zRegion]; - + final boolean regen = fullRegen; + final boolean regenReg = lodDim.regen[xRegion][zRegion]; Callable dataToRenderThread = () -> { - lodDim.getDataToRender( - nodeToRender, - regionPos, - playerBlockPosRounded.getX(), - playerBlockPosRounded.getZ()); + if (regen || regenReg) + { + lodDim.getDataToRender( + nodeToRender, + regionPos, + playerBlockPosRounded.getX(), + playerBlockPosRounded.getZ()); + } int posX; int posZ; @@ -281,7 +287,6 @@ public class LodBufferBuilder nodeToRenderThreads.add(dataToRenderThread); - }// region z }// region z long renderStart = System.currentTimeMillis(); @@ -293,20 +298,13 @@ public class LodBufferBuilder if (!future.get()) { ClientProxy.LOGGER.warn("LodBufferBuilder ran into trouble and had to start over."); - closeBuffers(); + closeBuffers(fullRegen, lodDim); return; } } long renderEnd = System.currentTimeMillis(); - // finish the buffer building - closeBuffers(); - - // upload the new buffers - uploadBuffers(); - - long endTime = System.currentTimeMillis(); @SuppressWarnings("unused") long buildTime = endTime - startTime; @@ -328,7 +326,6 @@ public class LodBufferBuilder ClientProxy.LOGGER.warn("\"LodNodeBufferBuilder.generateLodBuffersAsync\" ran into trouble: "); e.printStackTrace(); } finally - { // regardless of if we successfully created the buffers // we are done generating. @@ -336,8 +333,10 @@ public class LodBufferBuilder // clean up any potentially open resources if (buildableBuffers != null) - closeBuffers(); + closeBuffers(fullRegen, lodDim); + // upload the new buffers + uploadBuffers(); bufferLock.unlock(); } @@ -503,22 +502,35 @@ public class LodBufferBuilder /** * Calls begin on each of the buildable BufferBuilders. */ - private void startBuffers() + private void startBuffers(boolean fullRegen, LodDimension lodDim) { for (int x = 0; x < buildableBuffers.length; x++) for (int z = 0; z < buildableBuffers.length; z++) + { + //if (fullRegen || lodDim.regen[x][z]) + //{ + //if (lodDim.regen[x][z]) + // ClientProxy.LOGGER.debug("Starting region " + x + " " + z); buildableBuffers[x][z].begin(GL11.GL_QUADS, LodRenderer.LOD_VERTEX_FORMAT); + //} + } } /** * Calls end on each of the buildable BufferBuilders. */ - private void closeBuffers() + private void closeBuffers(boolean fullRegen, LodDimension lodDim) { for (int x = 0; x < buildableBuffers.length; x++) for (int z = 0; z < buildableBuffers.length; z++) - if (buildableBuffers[x][z] != null && buildableBuffers[x][z].building()) + + if (buildableBuffers[x][z] != null && buildableBuffers[x][z].building() /*&& (fullRegen || lodDim.regen[x][z])*/) + { + //if(lodDim.regen[x][z]) + // ClientProxy.LOGGER.debug("Closing region " + x + " " + z); + lodDim.regen[x][z] = false; buildableBuffers[x][z].end(); + } } /** diff --git a/src/main/java/com/seibel/lod/render/LodRenderer.java b/src/main/java/com/seibel/lod/render/LodRenderer.java index 461678d56..3613693e6 100644 --- a/src/main/java/com/seibel/lod/render/LodRenderer.java +++ b/src/main/java/com/seibel/lod/render/LodRenderer.java @@ -76,7 +76,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.

@@ -89,58 +89,60 @@ 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 Minecraft 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; - - + + /** * This is used to determine if the LODs should be regenerated */ - private LevelPos previousPos = new LevelPos((byte) 0,0,0); - private static long prevPlayerPosTime = 0; - private static long prevVanillaChunkTime = 0; - private static long prevChunkTime = 0; + private LevelPos previousPos = new LevelPos((byte) 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 regen = false; - + private volatile boolean partialRegen = false; + private volatile boolean fullRegen = true; + /** * This HashSet contains every chunk that Vanilla Minecraft * is going to render @@ -148,17 +150,17 @@ public class LodRenderer public HashSet vanillaRenderedChunks = new HashSet<>(); public HashSet previousVanillaRenderedChunks = new HashSet<>(); - + public LodRenderer(LodBufferBuilder newLodNodeBufferBuilder) { mc = Minecraft.getInstance(); gameRender = mc.gameRenderer; - + reflectionHandler = new ReflectionHandler(); lodBufferBuilder = newLodNodeBufferBuilder; } - - + + /** * Besides drawing the LODs this method also starts * the async process of generating the Buffers that hold those LODs. @@ -174,93 +176,105 @@ 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."); } } - - + + ClientPlayerEntity player = mc.player; + if (ClientProxy.previousLodRenderDistance != LodConfig.CLIENT.lodChunkRenderDistance.get() || + mc.options.renderDistance != prevRenderDistance || + prevFogDistance != LodConfig.CLIENT.fogDistance.get()) + { + // yes + fullRegen = true; + previousPos.changeParameters((byte) 4, player.xChunk, player.zChunk); + prevFogDistance = LodConfig.CLIENT.fogDistance.get(); + prevRenderDistance = mc.options.renderDistance; + //should use this when it's ready + //vanillaRenderedChunks.stream().filter(pos -> ((Math.abs(pos.x - player.xChunk) > mc.options.renderDistance) || (Math.abs(pos.z - player.zChunk) > mc.options.renderDistance))); + vanillaRenderedChunks.clear(); + } // should LODs be regenerated? long newTime = System.currentTimeMillis(); - if(newTime - prevPlayerPosTime > 5000) + //We check if the player has moved + if (newTime - prevPlayerPosTime > 2000) { if (previousPos.detailLevel == 0 || - player.xChunk != previousPos.posX || - player.zChunk != previousPos.posZ || - ClientProxy.previousLodRenderDistance != LodConfig.CLIENT.lodChunkRenderDistance.get() || - prevFogDistance != LodConfig.CLIENT.fogDistance.get()) + player.xChunk != previousPos.posX || + player.zChunk != previousPos.posZ) { // yes - regen = true; + fullRegen = true; previousPos.changeParameters((byte) 4, player.xChunk, player.zChunk); - prevFogDistance = LodConfig.CLIENT.fogDistance.get(); //should use this when it's ready //vanillaRenderedChunks.stream().filter(pos -> ((Math.abs(pos.x - player.xChunk) > mc.options.renderDistance) || (Math.abs(pos.z - player.zChunk) > mc.options.renderDistance))); vanillaRenderedChunks.clear(); } prevPlayerPosTime = newTime; } - if(newTime - prevVanillaChunkTime > 5000) + //We check if the vanilla rendered chunks are changed + if (newTime - prevVanillaChunkTime > 1000) { - if (previousVanillaRenderedChunks.equals(vanillaRenderedChunks)){ - regen = true; + if (previousVanillaRenderedChunks.equals(vanillaRenderedChunks)) + { + partialRegen = true; vanillaRenderedChunks = previousVanillaRenderedChunks; } prevVanillaChunkTime = newTime; } - if(newTime - prevChunkTime > 5000) + //We check if there is any newly generated terrain to show + if (newTime - prevChunkTime > 5000) { - if(lodDim.regenDimension) + if (lodDim.regenDimension) { - regen = true; + partialRegen = true; lodDim.regenDimension = false; } prevChunkTime = newTime; } - // determine which LODs should not be rendered close to the player HashSet chunkPosToSkip = LodUtil.getNearbyLodChunkPosToSkip(lodDim, player.blockPosition()); - - for(ChunkPos pos : chunkPosToSkip){ - if(!vanillaRenderedChunks.contains(pos)) + // determine which LODs should not be rendered close to the player + for (ChunkPos pos : chunkPosToSkip) + { + if (!vanillaRenderedChunks.contains(pos)) { vanillaRenderedChunks.add(pos); - lodDim.setToRegen(pos.getRegionX(),pos.getRegionZ()); + lodDim.setToRegen(pos.getRegionX(), pos.getRegionZ()); } } - // did the user change the debug setting? if (LodConfig.CLIENT.debugMode.get() != previousDebugMode) { previousDebugMode = LodConfig.CLIENT.debugMode.get(); - regen = true; + fullRegen = true; } - - + // determine how far the game's render distance is currently set farPlaneBlockDistance = LodConfig.CLIENT.lodChunkRenderDistance.get() * LodUtil.CHUNK_WIDTH; - + // set how how far the LODs will go - int numbChunksWide =LodConfig.CLIENT.lodChunkRenderDistance.get() * 2; + int numbChunksWide = LodConfig.CLIENT.lodChunkRenderDistance.get() * 2; // see if the chunks Minecraft is going to render are the // same as last time @@ -271,27 +285,28 @@ public class LodRenderer vanillaRenderedChunks = chunkPosToSkip; }*/ - + //=================// // create the LODs // //=================// - + // only regenerate the LODs if: // 1. we want to regenerate LODs // 2. we aren't already regenerating the LODs // 3. we aren't waiting for the build and draw buffers to swap // (this is to prevent thread conflicts) - if (regen && !lodBufferBuilder.generatingBuffers && !lodBufferBuilder.newBuffersAvaliable()) + if ((partialRegen || fullRegen) && !lodBufferBuilder.generatingBuffers && !lodBufferBuilder.newBuffersAvaliable()) { // 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); - + lodBufferBuilder.generateLodBuffersAsync(this, lodDim, player.blockPosition(), true); + // the regen process has been started, // it will be done when lodBufferBuilder.newBuffersAvaliable // is true - regen = false; + fullRegen = false; + partialRegen = false; } - + // replace the buffers used to draw and build, // this is only done when the createLodBufferGenerationThread // has finished executing on a parallel thread. @@ -299,14 +314,14 @@ public class LodRenderer { swapBuffers(); } - - + + //===========================// // GL settings for rendering // //===========================// - + // set the required open GL settings - + if (LodConfig.CLIENT.debugMode.get() == DebugMode.SHOW_DETAIL_WIREFRAME) GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_LINE); else @@ -315,72 +330,72 @@ public class LodRenderer 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); - + 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) { Vector3d cameraDir = mc.cameraEntity.getLookAngle().normalize(); cameraDir = mc.options.getCameraType().isMirrored() ? cameraDir.reverse() : cameraDir; - - + + // used to determine what type of fog to render - int halfWidth = vbos.length/2; - int quarterWidth = vbos.length/4; - + 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++) { - RegionPos vboPos = new RegionPos(i + lodDim.getCenterX() - lodDim.getWidth()/2, j + lodDim.getCenterZ() - lodDim.getWidth()/2); + RegionPos vboPos = new RegionPos(i + lodDim.getCenterX() - lodDim.getWidth() / 2, j + lodDim.getCenterZ() - lodDim.getWidth() / 2); if (RenderUtil.isRegionInViewFrustum(mc.cameraEntity.blockPosition(), cameraDir, vboPos.blockPos())) { if ((i > halfWidth - quarterWidth && i < halfWidth + quarterWidth) && (j > halfWidth - quarterWidth && j < halfWidth + quarterWidth)) 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); @@ -388,51 +403,50 @@ 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); - - + + // end of internal LOD profiling profiler.pop(); } - - + + /** * This is where the actual drawing happens. - * */ private void sendLodsToGpuAndDraw(VertexBuffer vbo, Matrix4f modelViewMatrix) { 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) { @@ -442,13 +456,13 @@ 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) @@ -460,8 +474,8 @@ 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) @@ -470,10 +484,10 @@ 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) { - RenderSystem.fogStart(farPlaneBlockDistance * 0.8f); + RenderSystem.fogStart(farPlaneBlockDistance * 0.1f); RenderSystem.fogEnd(farPlaneBlockDistance * 1.0f); } else if (fogQuality == FogQuality.FAST) { @@ -495,39 +509,39 @@ public class LodRenderer RenderSystem.fogStart(mc.options.renderDistance * 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. */ @SuppressWarnings("deprecation") 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. @@ -537,8 +551,8 @@ public class LodRenderer // get all relevant camera info ActiveRenderInfo renderInfo = mc.gameRenderer.getMainCamera(); Vector3d projectedView = renderInfo.getPosition(); - - + + // generate the model view matrix MatrixStack matrixStack = new MatrixStack(); matrixStack.pushPose(); @@ -546,11 +560,11 @@ public class LodRenderer matrixStack.mulPose(Vector3f.XP.rotationDegrees(renderInfo.getXRot())); matrixStack.mulPose(Vector3f.YP.rotationDegrees(renderInfo.getYRot() + 180)); matrixStack.translate(-projectedView.x, -projectedView.y, -projectedView.z); - + return matrixStack.last().pose(); } - - + + /** * create a new projection matrix and send it over to the GPU *

@@ -568,16 +582,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.options.bobView) { gameRender.bobView(matrixStack, partialTicks); } - + // potion and nausea effects float f = MathHelper.lerp(partialTicks, this.mc.player.oPortalTime, this.mc.player.portalTime) * this.mc.options.screenEffectScale * this.mc.options.screenEffectScale; if (f > 0.0F) @@ -591,8 +605,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 = @@ -604,14 +618,14 @@ public class LodRenderer // terrain, so I don't think it is much of an issue. mc.options.renderDistance, 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 */ @@ -623,7 +637,7 @@ public class LodRenderer if (this.mc.player != null) { Iterator iterator = this.mc.player.getActiveEffects().iterator(); - while(iterator.hasNext()) + while (iterator.hasNext()) { EffectInstance instance = iterator.next(); if (instance.getEffect() == Effects.NIGHT_VISION) @@ -633,27 +647,27 @@ public class LodRenderer } } } - - + + float sunBrightness = lodDimension.dimension.hasSkyLight() ? mc.level.getSkyDarken(partialTicks) : 0.2f; sunBrightness = playerHasNightVision ? 1.0f : sunBrightness; float gammaMultiplyer = (float) mc.options.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()); // TODO, could put return null? this crashed on James' laptop GL11.glEnable(LOD_GL_LIGHT_NUMBER); // Enable the above lighting - + RenderSystem.enableLighting(); } - + /** * Create all buffers that will be used. */ @@ -661,34 +675,34 @@ 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. */ public void regenerateLODsNextFrame() { - regen = true; + fullRegen = true; } - - + + /** * Replace the current Vertex Buffers with the newly * created buffers from the lodBufferBuilder. @@ -699,7 +713,7 @@ public class LodRenderer // the newly created buffers from the lodBufferBuilder vbos = lodBufferBuilder.getVertexBuffers(); } - + /** * Calls the BufferBuilder's destroyBuffers method. */ @@ -707,124 +721,124 @@ public class LodRenderer { lodBufferBuilder.destroyBuffers(); } - - + + private double getFov(float partialTicks, boolean useFovSetting) { return mc.gameRenderer.getFov(mc.gameRenderer.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.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.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.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.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.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; } - - + + } \ No newline at end of file