Remove the direct memory Buffer limit
Now the LOD multiplier won't be lowered when the detail is increased.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -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 //
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user