diff --git a/src/main/java/com/seibel/lod/builders/LodNodeBufferBuilder.java b/src/main/java/com/seibel/lod/builders/LodNodeBufferBuilder.java index d5f217c67..d6c0aba2b 100644 --- a/src/main/java/com/seibel/lod/builders/LodNodeBufferBuilder.java +++ b/src/main/java/com/seibel/lod/builders/LodNodeBufferBuilder.java @@ -30,7 +30,7 @@ import com.seibel.lod.handlers.LodConfig; import com.seibel.lod.objects.LodQuadTree; import com.seibel.lod.objects.LodQuadTreeDimension; import com.seibel.lod.objects.LodQuadTreeNode; -import com.seibel.lod.objects.NearFarVbos; +import com.seibel.lod.objects.RegionPos; import com.seibel.lod.proxy.ClientProxy; import com.seibel.lod.render.LodNodeRenderer; import com.seibel.lod.util.LodThreadFactory; @@ -48,31 +48,27 @@ import net.minecraftforge.common.WorldWorkerManager; * This object is used to create NearFarBuffer objects. * * @author James Seibel - * @version 8-15-2021 + * @version 8-17-2021 */ public class LodNodeBufferBuilder { private Minecraft mc; /** This holds the thread used to generate new LODs off the main thread. */ - private ExecutorService genThread = Executors.newSingleThreadExecutor(new LodThreadFactory(this.getClass().getSimpleName())); + private ExecutorService mainGenThread = Executors.newSingleThreadExecutor(new LodThreadFactory(this.getClass().getSimpleName() + " - main")); + /** This holds the threads used to generate the buffers. */ + private ExecutorService bufferGenThreads = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors(), new LodThreadFactory(this.getClass().getSimpleName() + " - buffer")); private LodNodeBuilder LodQuadTreeNodeBuilder; - /** The buffers that are used to create LODs using near fog */ - public BufferBuilder buildableNearBuffer; /** The buffers that are used to create LODs using far fog */ - public BufferBuilder buildableFarBuffer; + public volatile BufferBuilder[][] buildableBuffers; - /** Used when building a new VBO */ - public VertexBuffer buildableNearVbo; - /** Used when building a new VBO */ - public VertexBuffer buildableFarVbo; + /** Used when building new VBOs */ + public volatile VertexBuffer[][] buildableVbos; - /** VBO that is sent over to the LodNodeRenderer */ - public VertexBuffer drawableNearVbo; - /** VBO that is sent over to the LodNodeRenderer */ - public VertexBuffer drawableFarVbo; + /** VBOs that are sent over to the LodNodeRenderer */ + public volatile VertexBuffer[][] drawableVbos; /** if this is true the LOD buffers are currently being * regenerated. */ @@ -124,7 +120,7 @@ public class LodNodeBufferBuilder if (generatingBuffers) return; - if (buildableNearBuffer == null) + if (buildableBuffers == null) throw new IllegalStateException("\"generateLodBuffersAsync\" was called before the \"setupBuffers\" method was called."); if (previousDimension != lodDim) @@ -133,6 +129,9 @@ public class LodNodeBufferBuilder } + // TODO + maxChunkGenRequests = LodConfig.CLIENT.numberOfWorldGenerationThreads.get() * 8; + generatingBuffers = true; @@ -151,7 +150,6 @@ public class LodNodeBufferBuilder { try { - long startTime = System.currentTimeMillis(); // index of the chunk currently being added to the @@ -166,9 +164,7 @@ public class LodNodeBufferBuilder // Used when determining what detail level to use at what distance int maxBlockDistance = (numbChunksWide / 2) * 16; - // generate our new buildable buffers - buildableNearBuffer.begin(GL11.GL_QUADS, LodNodeRenderer.LOD_VERTEX_FORMAT); - buildableFarBuffer.begin(GL11.GL_QUADS, LodNodeRenderer.LOD_VERTEX_FORMAT); + startBuffers(); // used when determining which chunks are closer when queuing distance // generation @@ -293,12 +289,19 @@ public class LodNodeBufferBuilder } // lod null or empty - // should we draw near or far fog? BufferBuilder currentBuffer = null; - if (isCoordinateInNearFogArea(i, j, numbChunksWide / 2)) - currentBuffer = buildableNearBuffer; - else - currentBuffer = buildableFarBuffer; + try + { + // local position in the vbo and bufferBuilder arrays + RegionPos regionArrayPos = new RegionPos(new ChunkPos(i, j)); + currentBuffer = buildableBuffers[regionArrayPos.x][regionArrayPos.z]; + } + catch(Exception e) + { + e.printStackTrace(); + continue; + } + // determine detail level should this LOD be drawn at int distance = (int) Math.sqrt(Math.pow((playerBlockPosRounded.getX() - lod.getCenter().getX()), 2) + Math.pow((playerBlockPosRounded.getZ() - lod.getCenter().getZ()), 2)); @@ -372,46 +375,39 @@ public class LodNodeBufferBuilder } // finish the buffer building - buildableNearBuffer.end(); - buildableFarBuffer.end(); + closeBuffers(); // upload the new buffers - buildableNearVbo.upload(buildableNearBuffer); - buildableFarVbo.upload(buildableFarBuffer); + uploadBuffers(); + long endTime = System.currentTimeMillis(); long buildTime = endTime - startTime; - if (buildTime > 1000) - { -// ClientProxy.LOGGER.info("\"LodNodeBufferBuilder.generateLodBuffersAsync\" took " + buildTime + " milliseconds, consider lowering the render quality."); - } + ClientProxy.LOGGER.info("Buffer Build time: " + buildTime + " ms"); // mark that the buildable buffers as ready to swap switchVbos = true; } catch (Exception e) { - ClientProxy.LOGGER.warn("\"LodNodeBufferBuilder.generateLodBuffersAsync\" ran into trouble: " + e.getMessage()); + ClientProxy.LOGGER.warn("\"LodNodeBufferBuilder.generateLodBuffersAsync\" ran into trouble: "); e.printStackTrace(); } finally { - // regardless of if we successfully created the buffers or not + // regardless of if we successfully created the buffers // we are done generating. generatingBuffers = false; // clean up any potentially open resources - if (buildableNearBuffer != null && buildableNearBuffer.building()) - buildableNearBuffer.end(); - - if (buildableFarBuffer != null && buildableFarBuffer.building()) - buildableFarBuffer.end(); + if (buildableBuffers != null) + closeBuffers(); } }); - genThread.execute(thread); + mainGenThread.execute(thread); return; } @@ -443,22 +439,6 @@ public class LodNodeBufferBuilder } - /** - * Find the coordinates that are in the center half of the given - * 2D matrix, starting at (0,0) and going to (2 * lodRadius, 2 * lodRadius). - */ - private static boolean isCoordinateInNearFogArea(int chunkX, int chunkZ, int lodRadius) - { - int halfRadius = lodRadius / 2; - - return (chunkX >= lodRadius - halfRadius - && chunkX <= lodRadius + halfRadius) - && - (chunkZ >= lodRadius - halfRadius - && chunkZ <= lodRadius + halfRadius); - } - - @@ -467,46 +447,80 @@ public class LodNodeBufferBuilder //===============================// + /** + * Called from the LodRenderer to create the + * BufferBuilders. + */ + public void setupBuffers(int numbRegionsWide, int bufferMaxCapacity) + { + buildableBuffers = new BufferBuilder[numbRegionsWide][numbRegionsWide]; + + buildableVbos = new VertexBuffer[numbRegionsWide][numbRegionsWide]; + drawableVbos = new VertexBuffer[numbRegionsWide][numbRegionsWide]; + + for (int x = 0; x < numbRegionsWide; x++) + { + for (int z = 0; z < numbRegionsWide; z++) + { + buildableBuffers[x][z] = new BufferBuilder(bufferMaxCapacity); + buildableVbos[x][z] = new VertexBuffer(LodNodeRenderer.LOD_VERTEX_FORMAT); + drawableVbos[x][z] = new VertexBuffer(LodNodeRenderer.LOD_VERTEX_FORMAT); + } + } + } + + /** + * Calls begin on each of the buildable BufferBuilders. + */ + public void startBuffers() + { + for (int x = 0; x < buildableBuffers.length; x++) + for (int z = 0; z < buildableBuffers.length; z++) + buildableBuffers[x][z].begin(GL11.GL_QUADS, LodNodeRenderer.LOD_VERTEX_FORMAT); + } + + /** + * Calls end on each of the buildable BufferBuilders. + */ + public void closeBuffers() + { + for (int x = 0; x < buildableBuffers.length; x++) + for (int z = 0; z < buildableBuffers.length; z++) + if (buildableBuffers[x][z].building()) + buildableBuffers[x][z].end(); + } + /** * Called from the LodRenderer to create the * BufferBuilders at the right size. * * @param bufferMaxCapacity */ - public void setupBuffers(int bufferMaxCapacity) + public void uploadBuffers() { - buildableNearBuffer = new BufferBuilder(bufferMaxCapacity); - buildableFarBuffer = new BufferBuilder(bufferMaxCapacity); - - buildableNearVbo = new VertexBuffer(LodNodeRenderer.LOD_VERTEX_FORMAT); - buildableFarVbo = new VertexBuffer(LodNodeRenderer.LOD_VERTEX_FORMAT); - - drawableNearVbo = new VertexBuffer(LodNodeRenderer.LOD_VERTEX_FORMAT); - drawableFarVbo = new VertexBuffer(LodNodeRenderer.LOD_VERTEX_FORMAT); + for (int x = 0; x < buildableVbos.length; x++) + { + for (int z = 0; z < buildableVbos.length; z++) + { + buildableVbos[x][z].upload(buildableBuffers[x][z]); + } + } } + /** * Get the newly created VBOs */ - public NearFarVbos getVertexBuffers() + public VertexBuffer[][] getVertexBuffers() { - NearFarVbos vbos = new NearFarVbos(buildableNearVbo, buildableFarVbo); - - VertexBuffer tmp = null; - - tmp = drawableNearVbo; - drawableNearVbo = buildableNearVbo; - buildableNearVbo = tmp; - - tmp = buildableNearVbo; - buildableNearVbo = drawableNearVbo; - drawableNearVbo = tmp; - + VertexBuffer[][] tmp = drawableVbos; + drawableVbos = buildableVbos; + buildableVbos = tmp; // the vbos have been swapped switchVbos = false; - return vbos; + return drawableVbos; } /** diff --git a/src/main/java/com/seibel/lod/builders/LodNodeBuilder.java b/src/main/java/com/seibel/lod/builders/LodNodeBuilder.java index 56514e296..16bad492b 100644 --- a/src/main/java/com/seibel/lod/builders/LodNodeBuilder.java +++ b/src/main/java/com/seibel/lod/builders/LodNodeBuilder.java @@ -54,7 +54,7 @@ import net.minecraft.world.gen.Heightmap; * * @author Leonardo Amato * @author James Seibel - * @version 8-14-2021 + * @version 8-17-2021 */ public class LodNodeBuilder { @@ -64,10 +64,8 @@ public class LodNodeBuilder public static final int CHUNK_SECTION_HEIGHT = CHUNK_DATA_WIDTH; public static final Heightmap.Type DEFAULT_HEIGHTMAP = Heightmap.Type.WORLD_SURFACE_WG; - /** - * Default size of any LOD regions we use - */ - public int regionWidth = 5; + /** How wide LodDimensions should be in regions */ + public int defaultDimensionWidthInRegions = 5; public LodNodeBuilder() { @@ -102,7 +100,7 @@ public class LodNodeBuilder if (lodWorld.getLodDimension(dim) == null) { - lodDim = new LodQuadTreeDimension(dim, lodWorld, regionWidth); + lodDim = new LodQuadTreeDimension(dim, lodWorld, defaultDimensionWidthInRegions); lodWorld.addLodDimension(lodDim); } else diff --git a/src/main/java/com/seibel/lod/objects/LodQuadTreeWorld.java b/src/main/java/com/seibel/lod/objects/LodQuadTreeWorld.java index ebf38954d..d70609a72 100644 --- a/src/main/java/com/seibel/lod/objects/LodQuadTreeWorld.java +++ b/src/main/java/com/seibel/lod/objects/LodQuadTreeWorld.java @@ -20,6 +20,8 @@ package com.seibel.lod.objects; import java.util.Hashtable; import java.util.Map; +import com.seibel.lod.proxy.ClientProxy; + import net.minecraft.world.DimensionType; /** @@ -27,7 +29,7 @@ import net.minecraft.world.DimensionType; * * @author James Seibel * @author Leonardo Amato - * @version 8-14-2021 + * @version 8-17-2021 */ public class LodQuadTreeWorld { @@ -130,6 +132,8 @@ public class LodQuadTreeWorld if (lodDimensions == null) return; + ClientProxy.LOGGER.info("Saving LODs"); + for (DimensionType key : lodDimensions.keySet()) lodDimensions.get(key).saveDirtyRegionsToFileAsync(); } diff --git a/src/main/java/com/seibel/lod/objects/NearFarVbos.java b/src/main/java/com/seibel/lod/objects/NearFarVbos.java deleted file mode 100644 index 070d2bbd6..000000000 --- a/src/main/java/com/seibel/lod/objects/NearFarVbos.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * This file is part of the LOD Mod, licensed under the GNU GPL v3 License. - * - * Copyright (C) 2020 James Seibel - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.seibel.lod.objects; - -import net.minecraft.client.renderer.vertex.VertexBuffer; - -/** - * This object is just a replacement for an array - * to make things easier to understand in the LodRenderer - * and BuildBufferThread. - * - * @author James Seibel - * @version 08-15-2021 - */ -public class NearFarVbos -{ - public VertexBuffer nearVbo; - - public VertexBuffer farVbo; - - /** - * @param newNearVbo - * @param newFarVbo - */ - public NearFarVbos(VertexBuffer newNearVbo, VertexBuffer newFarVbo) - { - nearVbo = newNearVbo; - farVbo = newFarVbo; - } -} diff --git a/src/main/java/com/seibel/lod/proxy/ClientProxy.java b/src/main/java/com/seibel/lod/proxy/ClientProxy.java index 26145ac63..5b6fa67f5 100644 --- a/src/main/java/com/seibel/lod/proxy/ClientProxy.java +++ b/src/main/java/com/seibel/lod/proxy/ClientProxy.java @@ -48,7 +48,7 @@ import net.minecraftforge.eventbus.api.SubscribeEvent; * and is the starting point for most of this program. * * @author James_Seibel - * @version 8-14-2021 + * @version 8-17-2021 */ public class ClientProxy { @@ -63,6 +63,11 @@ public class ClientProxy Minecraft mc = Minecraft.getInstance(); + /** This is used to determine if the LODs should be regenerated */ + public static int previousChunkRenderDistance = 0; + /** This is used to determine if the LODs should be regenerated */ + public static int previousLodMultiplierDistance = 0; + public ClientProxy() { @@ -86,37 +91,13 @@ public class ClientProxy return; - // calculate how wide the dimension(s) should be in regions - int chunksWide = (mc.options.renderDistance * 2) * LodConfig.CLIENT.lodChunkRadiusMultiplier.get(); - int newWidth = (int)Math.ceil(chunksWide / (float) LodUtil.REGION_WIDTH_IN_CHUNKS); - newWidth = (newWidth % 2 == 0) ? (newWidth += 1) : (newWidth += 2); // make sure we have a odd number of regions - - if (lodNodeBuilder.regionWidth != newWidth) - { - lodWorld.resizeDimensionRegionWidth(newWidth); - lodNodeBuilder.regionWidth = newWidth; - - //LOGGER.info("new dimension width in regions: " + newWidth + "\t potential: " + newWidth ); - - // skip this frame, hopefully the lodWorld - // should have everything set up by then - return; - } + viewDistanceChangedEvent(); LodQuadTreeDimension lodDim = lodWorld.getLodDimension(mc.player.level.dimensionType()); if (lodDim == null) return; - // make sure the dimension is centered - RegionPos playerRegionPos = new RegionPos(mc.player.blockPosition()); - RegionPos worldRegionOffset = new RegionPos(playerRegionPos.x - lodDim.getCenterX(), playerRegionPos.z - lodDim.getCenterZ()); - if (worldRegionOffset.x != 0 || worldRegionOffset.z != 0) - { - lodWorld.saveAllDimensions(); - lodDim.move(worldRegionOffset); - - //LOGGER.info("offset: " + worldRegionOffset.x + "," + worldRegionOffset.z + "\t center: " + lodDim.getCenterX() + "," + lodDim.getCenterZ()); - } + playerMoveEvent(lodDim); // comment out when creating a release @@ -136,10 +117,16 @@ public class ClientProxy profiler.pop(); // end LOD profiler.push("terrain"); // restart "terrain" - } - - + + + // these can't be set until after the buffers are built (in renderer.drawLODs) + // otherwise the buffers may be set to the wrong size, or not changed at all + previousChunkRenderDistance = mc.options.renderDistance; + previousLodMultiplierDistance = LodConfig.CLIENT.lodChunkRadiusMultiplier.get(); + } + + private void applyConfigOverrides() { // remind the developer(s). that config override is active @@ -155,7 +142,7 @@ public class ClientProxy LodConfig.CLIENT.maxDrawDetail.set(LodDetail.FULL); LodConfig.CLIENT.maxGenerationDetail.set(LodDetail.FULL); - LodConfig.CLIENT.lodChunkRadiusMultiplier.set(12); + LodConfig.CLIENT.lodChunkRadiusMultiplier.set(20); LodConfig.CLIENT.fogDistance.set(FogDistance.FAR); LodConfig.CLIENT.fogDrawOverride.set(FogDrawOverride.NEVER_DRAW_FOG); LodConfig.CLIENT.shadingMode.set(ShadingMode.DARKEN_SIDES); @@ -230,6 +217,51 @@ public class ClientProxy + //==================// + // frame LOD events // + //==================// + + /** + * Re-centers the given LodDimension if it needs to be. + */ + private void playerMoveEvent(LodQuadTreeDimension lodDim) + { + // make sure the dimension is centered + RegionPos playerRegionPos = new RegionPos(mc.player.blockPosition()); + RegionPos worldRegionOffset = new RegionPos(playerRegionPos.x - lodDim.getCenterX(), playerRegionPos.z - lodDim.getCenterZ()); + if (worldRegionOffset.x != 0 || worldRegionOffset.z != 0) + { + lodWorld.saveAllDimensions(); + lodDim.move(worldRegionOffset); + + //LOGGER.info("offset: " + worldRegionOffset.x + "," + worldRegionOffset.z + "\t center: " + lodDim.getCenterX() + "," + lodDim.getCenterZ()); + } + } + + + /** + * Re-sizes all LodDimensions if they needs to be. + */ + private void viewDistanceChangedEvent() + { + // calculate how wide the dimension(s) should be in regions + int chunksWide = (mc.options.renderDistance * 2) * LodConfig.CLIENT.lodChunkRadiusMultiplier.get(); + int newWidth = (int)Math.ceil(chunksWide / (float) LodUtil.REGION_WIDTH_IN_CHUNKS); + newWidth = (newWidth % 2 == 0) ? (newWidth += 1) : (newWidth += 2); // make sure we have a odd number of regions + + // do the dimensions need to change in size? + if (lodNodeBuilder.defaultDimensionWidthInRegions != newWidth) + { + // TODO make this async + + // update the dimensions to fit the new width + lodWorld.resizeDimensionRegionWidth(newWidth); + lodNodeBuilder.defaultDimensionWidthInRegions = newWidth; + + //LOGGER.info("new dimension width in regions: " + newWidth + "\t potential: " + newWidth ); + } + } + //================// // public getters // diff --git a/src/main/java/com/seibel/lod/render/LodNodeRenderer.java b/src/main/java/com/seibel/lod/render/LodNodeRenderer.java index 6d3d0cbd9..b0012da1c 100644 --- a/src/main/java/com/seibel/lod/render/LodNodeRenderer.java +++ b/src/main/java/com/seibel/lod/render/LodNodeRenderer.java @@ -38,7 +38,6 @@ import com.seibel.lod.handlers.ReflectionHandler; import com.seibel.lod.objects.LodQuadTreeDimension; import com.seibel.lod.objects.LodQuadTreeNode; import com.seibel.lod.objects.NearFarFogSettings; -import com.seibel.lod.objects.NearFarVbos; import com.seibel.lod.proxy.ClientProxy; import com.seibel.lod.util.LodUtil; @@ -66,7 +65,7 @@ import net.minecraft.util.math.vector.Vector3f; * This is where LODs are draw to the world. * * @author James Seibel - * @version 8-15-2021 + * @version 8-17-2021 */ public class LodNodeRenderer { @@ -106,15 +105,12 @@ public class LodNodeRenderer /** This is used to generate the buildable buffers */ private LodNodeBufferBuilder lodNodeBufferBuilder; - /** This is the VertexBuffer used to draw any LODs that use near fog */ - private VertexBuffer nearVbo; - /** This is the VertexBuffer used to draw any LODs that use far fog */ - private VertexBuffer farVbo; + /** 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 int previousChunkRenderDistance = 0; + /** This is used to determine if the LODs should be regenerated */ private int prevChunkX = 0; /** This is used to determine if the LODs should be regenerated */ @@ -189,9 +185,10 @@ public class LodNodeRenderer // should LODs be regenerated? if ((int)player.getX() / LodUtil.CHUNK_WIDTH != prevChunkX || - (int)player.getZ() / LodUtil.CHUNK_WIDTH != prevChunkZ || - previousChunkRenderDistance != mc.options.renderDistance || - prevFogDistance != LodConfig.CLIENT.fogDistance.get()) + (int)player.getZ() / LodUtil.CHUNK_WIDTH != prevChunkZ || + ClientProxy.previousChunkRenderDistance != mc.options.renderDistance || + ClientProxy.previousLodMultiplierDistance != LodConfig.CLIENT.lodChunkRadiusMultiplier.get() || + prevFogDistance != LodConfig.CLIENT.fogDistance.get()) { // yes regen = true; @@ -248,8 +245,11 @@ public class LodNodeRenderer if (regen && !lodNodeBufferBuilder.generatingBuffers && !lodNodeBufferBuilder.newBuffersAvaliable()) { // this will mainly happen when the view distance is changed - if (previousChunkRenderDistance != mc.options.renderDistance) - setupBuffers(numbChunksWide); + int renderDistance = mc.options.renderDistance; + int lodMultiplier = LodConfig.CLIENT.lodChunkRadiusMultiplier.get(); + if (renderDistance != ClientProxy.previousChunkRenderDistance || + lodMultiplier != ClientProxy.previousLodMultiplierDistance) + setupBuffers(lodDim.getWidth()); // generate the LODs on a separate thread to prevent stuttering or freezing lodNodeBufferBuilder.generateLodBuffersAsync(this, lodDim, player.blockPosition(), numbChunksWide); @@ -317,11 +317,17 @@ public class LodNodeRenderer //===========// profiler.popPush("LOD draw"); - setupFog(fogSettings.near.distance, fogSettings.near.quality); - sendLodsToGpuAndDraw(nearVbo, modelViewMatrix); - - setupFog(fogSettings.far.distance, fogSettings.far.quality); - sendLodsToGpuAndDraw(farVbo, modelViewMatrix); + if (vbos != null) + { + for (int i = 0; i < vbos.length; i++) + { + for (int j = 0; j < vbos.length; j++) + { + setupFog(fogSettings.near.distance, fogSettings.near.quality); + sendLodsToGpuAndDraw(vbos[i][j], modelViewMatrix); + } + } + } @@ -341,10 +347,6 @@ public class LodNodeRenderer GL11.glEnable(GL11.GL_LIGHT1); RenderSystem.disableLighting(); - // this can't be called until after the buffers are built - // because otherwise the buffers may be set to the wrong size - previousChunkRenderDistance = mc.options.renderDistance; - // reset the fog settings so the normal chunks // will be drawn correctly cleanupFog(fogSettings, defaultFogStartDist, defaultFogEndDist, defaultFogMode, defaultFogDistance); @@ -606,30 +608,21 @@ public class LodNodeRenderer /** * Create all buffers that will be used. */ - private void setupBuffers(int numbChunksWide) + private void setupBuffers(int numbRegionsWide) { // calculate the max amount of memory needed (in bytes) - int bufferMemory = RenderUtil.getBufferMemoryForRadiusMultiplier(LodConfig.CLIENT.lodChunkRadiusMultiplier.get()); + 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) { - int maxRadiusMultiplier = RenderUtil.getMaxRadiusMultiplierWithAvaliableMemory(LodConfig.CLIENT.lodTemplate.get(), LodUtil.CHUNK_DETAIL_LEVEL); - - ClientProxy.LOGGER.warn("The lodChunkRadiusMultiplier was set too high " - + "and had to be lowered to fit memory constraints " - + "from " + LodConfig.CLIENT.lodChunkRadiusMultiplier.get() + " " - + "to " + maxRadiusMultiplier); - - LodConfig.CLIENT.lodChunkRadiusMultiplier.set( - maxRadiusMultiplier); - - bufferMemory = RenderUtil.getBufferMemoryForRadiusMultiplier(maxRadiusMultiplier); + 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."); } - lodNodeBufferBuilder.setupBuffers(bufferMemory); + lodNodeBufferBuilder.setupBuffers(numbRegionsWide, bufferMemory); } @@ -658,11 +651,7 @@ public class LodNodeRenderer { // replace the drawable buffers with // the newly created buffers from the lodBufferBuilder - NearFarVbos newVbos = lodNodeBufferBuilder.getVertexBuffers(); - - // bind the buffers with their respective VBOs - nearVbo = newVbos.nearVbo; - farVbo = newVbos.farVbo; + vbos = lodNodeBufferBuilder.getVertexBuffers(); } diff --git a/src/main/java/com/seibel/lod/render/RenderUtil.java b/src/main/java/com/seibel/lod/render/RenderUtil.java index 9a7f8c132..a81e8e947 100644 --- a/src/main/java/com/seibel/lod/render/RenderUtil.java +++ b/src/main/java/com/seibel/lod/render/RenderUtil.java @@ -29,7 +29,7 @@ import net.minecraft.util.math.ChunkPos; * to be used in the rendering process. * * @author James Seibel - * @version 6-17-2021 + * @version 8-17-2021 */ public class RenderUtil { @@ -86,13 +86,10 @@ public class RenderUtil /** * Get how much buffer memory would be required for the given radius multiplier */ - public static int getBufferMemoryForRadiusMultiplier(int radiusMultiplier) - { - int numbChunksWide = mc.options.renderDistance * - radiusMultiplier * 2; - + public static int getBufferMemoryForRegion() + { // calculate the max amount of buffer memory needed (in bytes) - return numbChunksWide * numbChunksWide * + return LodUtil.REGION_WIDTH_IN_CHUNKS * LodUtil.REGION_WIDTH_IN_CHUNKS * LodConfig.CLIENT.lodTemplate.get(). getBufferMemoryForSingleLod(LodUtil.CHUNK_DETAIL_LEVEL); }