Add configs for buffer building timeouts and small refactors

This commit is contained in:
James Seibel
2021-08-30 23:16:27 -05:00
parent d5d48f2448
commit 2c2c6d6785
3 changed files with 173 additions and 123 deletions
@@ -45,7 +45,6 @@ import com.seibel.lod.proxy.ClientProxy;
import com.seibel.lod.util.LodUtil;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.player.ClientPlayerEntity;
import net.minecraft.client.renderer.ActiveRenderInfo;
import net.minecraft.client.renderer.FogRenderer;
import net.minecraft.client.renderer.GameRenderer;
@@ -67,7 +66,7 @@ import net.minecraft.util.math.vector.Vector3f;
* This is where LODs are draw to the world.
*
* @author James Seibel
* @version 8-21-2021
* @version 8-30-2021
*/
public class LodRenderer
{
@@ -198,96 +197,10 @@ public class LodRenderer
}
}
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();
//We check if the player has moved
if (newTime - prevPlayerPosTime > 2000)
{
if (previousPos.detailLevel == 0 ||
player.xChunk != previousPos.posX ||
player.zChunk != previousPos.posZ)
{
// yes
fullRegen = true;
previousPos.changeParameters((byte) 4, player.xChunk, player.zChunk);
//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;
}
//We check if the vanilla rendered chunks are changed
if (newTime - prevVanillaChunkTime > 1000)
{
if (!previousVanillaRenderedChunks.equals(vanillaRenderedChunks))
{
partialRegen = true;
previousVanillaRenderedChunks = (HashSet<ChunkPos>) vanillaRenderedChunks.clone();
}
prevVanillaChunkTime = newTime;
}
//We check if there is any newly generated terrain to show
if (newTime - prevChunkTime > 5000)
{
if (lodDim.regenDimension)
{
partialRegen = true;
lodDim.regenDimension = false;
}
prevChunkTime = newTime;
}
HashSet<ChunkPos> chunkPosToSkip = LodUtil.getNearbyLodChunkPosToSkip(lodDim, player.blockPosition());
// 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());
}
}
if(chunkPosToSkip.isEmpty() && player.position().y>256)
vanillaRenderedChunks.clear();
// did the user change the debug setting?
if (LodConfig.CLIENT.debugMode.get() != previousDebugMode)
{
previousDebugMode = LodConfig.CLIENT.debugMode.get();
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;
// see if the chunks Minecraft is going to render are the
// same as last time
/*
if (!vanillaRenderedChunks.containsAll(chunkPosToSkip) || vanillaRenderedChunks.size() != chunkPosToSkip.size())
{
regen = true;
vanillaRenderedChunks = chunkPosToSkip;
}*/
// TODO move the buffer regeneration logic into its own class (probably called in the client proxy instead)
// starting here...
determineIfLodsShouldRegenerate(lodDim);
//=================//
// create the LODs //
@@ -301,14 +214,17 @@ public class LodRenderer
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(), true);
lodBufferBuilder.generateLodBuffersAsync(this, lodDim, mc.player.blockPosition(), true);
// the regen process has been started,
// it will be done when lodBufferBuilder.newBuffersAvaliable
// 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
@@ -317,8 +233,9 @@ public class LodRenderer
{
swapBuffers();
}
//===========================//
// GL settings for rendering //
//===========================//
@@ -425,8 +342,8 @@ public class LodRenderer
// end of internal LOD profiling
profiler.pop();
}
/**
* This is where the actual drawing happens.
*/
@@ -459,26 +376,27 @@ 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)
{
// fancy fog (fragment distance based fog)
glFogDistanceMode = NVFogDistance.GL_EYE_RADIAL_NV;
} else
}
else
{
// fast fog (frustum distance based fog)
glFogDistanceMode = NVFogDistance.GL_EYE_PLANE_ABSOLUTE_NV;
}
farPlaneBlockDistance = LodConfig.CLIENT.lodChunkRenderDistance.get() * LodUtil.CHUNK_WIDTH;
// the multipliers are percentages
// of the regular view distance.
if (fogDistance == FogDistance.FAR)
@@ -487,12 +405,13 @@ 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.1f);
RenderSystem.fogEnd(farPlaneBlockDistance * 1.0f);
} else if (fogQuality == FogQuality.FAST)
}
else if (fogQuality == FogQuality.FAST)
{
// for the far fog of the normal chunks
// to start right where the LODs' end use:
@@ -500,20 +419,21 @@ public class LodRenderer
RenderSystem.fogStart(farPlaneBlockDistance * 1.5f);
RenderSystem.fogEnd(farPlaneBlockDistance * 2.0f);
}
} else if (fogDistance == FogDistance.NEAR)
}
else if (fogDistance == FogDistance.NEAR)
{
if (fogQuality == FogQuality.FANCY)
{
RenderSystem.fogEnd(mc.options.renderDistance * 16 * 1.41f);
RenderSystem.fogStart(mc.options.renderDistance * 16 * 1.6f);
} else if (fogQuality == FogQuality.FAST)
}
else if (fogQuality == FogQuality.FAST)
{
RenderSystem.fogEnd(mc.options.renderDistance * 16 * 1.0f);
RenderSystem.fogStart(mc.options.renderDistance * 16 * 1.5f);
}
}
GL11.glEnable(GL11.GL_FOG);
RenderSystem.enableFog();
RenderSystem.setupNvFogDistance();
@@ -524,7 +444,6 @@ public class LodRenderer
/**
* Revert any changes that were made to the fog.
*/
@SuppressWarnings("deprecation")
private void cleanupFog(NearFarFogSettings fogSettings,
float defaultFogStartDist, float defaultFogEndDist,
int defaultFogMode, int defaultFogDistance)
@@ -537,8 +456,8 @@ public class LodRenderer
// 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);
}
@@ -632,7 +551,6 @@ public class LodRenderer
/**
* setup the lighting to be used for the LODs
*/
@SuppressWarnings("deprecation")
private void setupLighting(LodDimension lodDimension, float partialTicks)
{
// Determine if the player has night vision
@@ -665,7 +583,7 @@ public class LodRenderer
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.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();
@@ -842,6 +760,112 @@ public class LodRenderer
return fogSettings;
}
/**
* Determines if the LODs should have a fullRegen or partialRegen
*/
@SuppressWarnings("unchecked")
private void determineIfLodsShouldRegenerate(LodDimension lodDim)
{
//=============//
// full regens //
//=============//
// check if the view distance changed
if (ClientProxy.previousLodRenderDistance != LodConfig.CLIENT.lodChunkRenderDistance.get()
|| mc.options.renderDistance != prevRenderDistance
|| prevFogDistance != LodConfig.CLIENT.fogDistance.get())
{
fullRegen = true;
previousPos.changeParameters((byte) 4, mc.player.xChunk, mc.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();
}
// did the user change the debug setting?
if (LodConfig.CLIENT.debugMode.get() != previousDebugMode)
{
previousDebugMode = LodConfig.CLIENT.debugMode.get();
fullRegen = true;
}
long newTime = System.currentTimeMillis();
// check if the player has moved
if (newTime - prevPlayerPosTime > LodConfig.CLIENT.bufferRebuildPlayerMoveTimeout.get())
{
if (previousPos.detailLevel == 0
|| mc.player.xChunk != previousPos.posX
|| mc.player.zChunk != previousPos.posZ)
{
fullRegen = true;
previousPos.changeParameters((byte) 4, mc.player.xChunk, mc.player.zChunk);
//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;
}
//================//
// partial regens //
//================//
// check if the vanilla rendered chunks changed
if (newTime - prevVanillaChunkTime > LodConfig.CLIENT.bufferRebuildChunkChangeTimeout.get())
{
if (!previousVanillaRenderedChunks.equals(vanillaRenderedChunks))
{
partialRegen = true;
previousVanillaRenderedChunks = (HashSet<ChunkPos>) vanillaRenderedChunks.clone();
}
prevVanillaChunkTime = newTime;
}
// check if there is any newly generated terrain to show
if (newTime - prevChunkTime > LodConfig.CLIENT.bufferRebuildLodChangeTimeout.get())
{
if (lodDim.regenDimension)
{
partialRegen = true;
lodDim.regenDimension = false;
}
prevChunkTime = newTime;
}
//==============//
// LOD skipping //
//==============//
// determine which LODs should not be rendered close to the player
HashSet<ChunkPos> chunkPosToSkip = LodUtil.getNearbyLodChunkPosToSkip(lodDim, mc.player.blockPosition());
for (ChunkPos pos : chunkPosToSkip)
{
if (!vanillaRenderedChunks.contains(pos))
{
vanillaRenderedChunks.add(pos);
lodDim.setToRegen(pos.getRegionX(), pos.getRegionZ());
}
}
// if the player is high enough, draw all LODs
if(chunkPosToSkip.isEmpty() && mc.player.position().y > 256)
{
vanillaRenderedChunks.clear();
}
}
}