* For some reason this has to be called after the frame has been rendered,
* otherwise visual stuttering/rubber banding may happen. I'm not sure why...
*/
private void swapBuffers()
{
// replace the drawable buffers with
// the newly created buffers from the lodBufferBuilder
VertexBuffersAndOffset result = lodBufferBuilder.getVertexBuffers();
vbos = result.vbos;
storageBufferIds = result.storageBufferIds;
vbosCenter = result.drawableCenterChunkPos;
}
/** Calls the BufferBuilder's destroyBuffers method. */
public void destroyBuffers()
{
lodBufferBuilder.destroyBuffers();
}
private double getFov(float partialTicks, boolean useFovSetting)
{
return mc.getGameRenderer().getFov(mc.getGameRenderer().getMainCamera(), partialTicks, useFovSetting);
}
/** Return what fog settings should be used when rendering. */
private NearFarFogSettings determineFogSettings()
{
NearFarFogSettings fogSettings = new NearFarFogSettings();
FogQuality quality = ReflectionHandler.INSTANCE.getFogQuality();
FogDrawOverride override = LodConfig.CLIENT.graphics.fogQualityOption.fogDrawOverride.get();
fogSettings.vanillaIsRenderingFog = quality != FogQuality.OFF;
// use any fog overrides the user may have set
switch (override)
{
case FANCY:
quality = FogQuality.FANCY;
break;
case NO_FOG:
quality = FogQuality.OFF;
break;
case FAST:
quality = FogQuality.FAST;
break;
case OPTIFINE_SETTING:
// don't override anything
break;
}
// only use fancy fog if the user's GPU can deliver
if (!GlProxy.getInstance().fancyFogAvailable && quality == FogQuality.FANCY)
{
quality = FogQuality.FAST;
}
// how different distances are drawn depends on the quality set
switch (quality)
{
case FANCY:
fogSettings.near.quality = FogQuality.FANCY;
fogSettings.far.quality = FogQuality.FANCY;
switch (LodConfig.CLIENT.graphics.fogQualityOption.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 FAST:
fogSettings.near.quality = FogQuality.FAST;
fogSettings.far.quality = FogQuality.FAST;
// fast fog setting should only have one type of
// fog, since the LODs are separated into a near
// and far portion; and fast fog is rendered from the
// frustrum's perspective instead of the camera
switch (LodConfig.CLIENT.graphics.fogQualityOption.fogDistance.get())
{
case NEAR_AND_FAR:
case NEAR:
fogSettings.near.distance = FogDistance.NEAR;
fogSettings.far.distance = FogDistance.NEAR;
break;
case FAR:
fogSettings.near.distance = FogDistance.FAR;
fogSettings.far.distance = FogDistance.FAR;
break;
}
break;
case OFF:
fogSettings.near.quality = FogQuality.OFF;
fogSettings.far.quality = FogQuality.OFF;
break;
}
return fogSettings;
}
/** Determines if the LODs should have a fullRegen or partialRegen */
private void determineIfLodsShouldRegenerate(LodDimension lodDim, float partialTicks)
{
short chunkRenderDistance = (short) mc.getRenderDistance();
int vanillaRenderedChunksWidth = chunkRenderDistance * 2 + 2;
//=============//
// full regens //
//=============//
// check if the view distance changed
if (ClientProxy.previousLodRenderDistance != LodConfig.CLIENT.graphics.qualityOption.lodChunkRenderDistance.get()
|| chunkRenderDistance != prevRenderDistance
|| prevFogDistance != LodConfig.CLIENT.graphics.fogQualityOption.fogDistance.get())
{
vanillaRenderedChunks = new boolean[vanillaRenderedChunksWidth][vanillaRenderedChunksWidth];
DetailDistanceUtil.updateSettings();
fullRegen = true;
previousPos = LevelPosUtil.createLevelPos((byte) 4, mc.getPlayer().xChunk, mc.getPlayer().zChunk);
prevFogDistance = LodConfig.CLIENT.graphics.fogQualityOption.fogDistance.get();
prevRenderDistance = chunkRenderDistance;
}
// did the user change the debug setting?
if (LodConfig.CLIENT.advancedModOptions.debugging.debugMode.get() != previousDebugMode)
{
previousDebugMode = LodConfig.CLIENT.advancedModOptions.debugging.debugMode.get();
fullRegen = true;
}
long newTime = System.currentTimeMillis();
// check if the player has moved
if (newTime - prevPlayerPosTime > LodConfig.CLIENT.advancedModOptions.buffers.rebuildTimes.get().playerMoveTimeout)
{
if (LevelPosUtil.getDetailLevel(previousPos) == 0
|| mc.getPlayerChunkPos().getX() != LevelPosUtil.getPosX(previousPos)
|| mc.getPlayerChunkPos().getZ() != LevelPosUtil.getPosZ(previousPos))
{
vanillaRenderedChunks = new boolean[vanillaRenderedChunksWidth][vanillaRenderedChunksWidth];
fullRegen = true;
previousPos = LevelPosUtil.createLevelPos((byte) 4, mc.getPlayerChunkPos().getX(), mc.getPlayerChunkPos().getZ());
}
prevPlayerPosTime = newTime;
}
// determine how far the lighting has to
// change in order to rebuild the buffers
// the max brightness is 1 and the minimum is 0.2
float skyBrightness = lodDim.dimension.hasSkyLight() ? mc.getSkyDarken(partialTicks) : 0.2f;
float minLightingDifference;
switch (LodConfig.CLIENT.advancedModOptions.buffers.rebuildTimes.get())
{
case FREQUENT:
minLightingDifference = 0.025f;
break;
case NORMAL:
minLightingDifference = 0.05f;
break;
default:
case RARE:
minLightingDifference = 0.1f;
break;
}
// check if the lighting changed
if (Math.abs(skyBrightness - prevSkyBrightness) > minLightingDifference
// make sure the lighting gets to the max/minimum value
// (just in case the minLightingDifference is too large to notice the change)
|| (skyBrightness == 1.0f && prevSkyBrightness != 1.0f) // noon
|| (skyBrightness == 0.2f && prevSkyBrightness != 0.2f) // midnight
|| mc.getOptions().gamma != prevBrightness)
{
fullRegen = true;
prevBrightness = mc.getOptions().gamma;
prevSkyBrightness = skyBrightness;
}
//================//
// partial regens //
//================//
// check if the vanilla rendered chunks changed
if (newTime - prevVanillaChunkTime > LodConfig.CLIENT.advancedModOptions.buffers.rebuildTimes.get().renderedChunkTimeout)
{
if (vanillaRenderedChunksChanged)
{
partialRegen = true;
vanillaRenderedChunksChanged = false;
}
prevVanillaChunkTime = newTime;
}
// check if there is any newly generated terrain to show
if (newTime - prevChunkTime > LodConfig.CLIENT.advancedModOptions.buffers.rebuildTimes.get().chunkChangeTimeout)
{
if (lodDim.regenDimensionBuffers)
{
partialRegen = true;
lodDim.regenDimensionBuffers = false;
}
prevChunkTime = newTime;
}
//==============//
// LOD skipping //
//==============//
// determine which LODs should not be rendered close to the player
HashSet