Move Render helper methods into RenderUtil
Also refactor said methods along with ClientApit
This commit is contained in:
@@ -34,6 +34,7 @@ import com.seibel.lod.core.objects.math.Vec3f;
|
||||
import com.seibel.lod.core.render.GLProxy;
|
||||
import com.seibel.lod.core.render.LodFogConfig;
|
||||
import com.seibel.lod.core.render.LodRenderProgram;
|
||||
import com.seibel.lod.core.render.RenderUtil;
|
||||
import com.seibel.lod.core.render.objects.GLState;
|
||||
import com.seibel.lod.core.render.objects.GLVertexBuffer;
|
||||
import com.seibel.lod.core.render.objects.QuadElementBuffer;
|
||||
@@ -54,7 +55,7 @@ import java.util.concurrent.TimeUnit;
|
||||
* This is where LODs are draw to the world.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 12-12-2021
|
||||
* @version 2022-8-21
|
||||
*/
|
||||
public class a7LodRenderer
|
||||
{
|
||||
@@ -125,18 +126,7 @@ public class a7LodRenderer
|
||||
EVENT_LOGGER.error("drawLODs() called after close()!");
|
||||
return;
|
||||
}
|
||||
//=================================//
|
||||
// determine if LODs should render //
|
||||
//=================================//
|
||||
if (MC_RENDER.playerHasBlindnessEffect())
|
||||
{
|
||||
// if the player is blind, don't render LODs,
|
||||
// and don't change minecraft's fog
|
||||
// which blindness relies on.
|
||||
return;
|
||||
}
|
||||
if (MC_RENDER.getLightmapWrapper() == null)
|
||||
return;
|
||||
|
||||
|
||||
// get MC's shader program
|
||||
// Save all MC render state
|
||||
@@ -203,24 +193,14 @@ public class a7LodRenderer
|
||||
//LightmapTexture lightmapTexture = new LightmapTexture();
|
||||
|
||||
/*---------Get required data--------*/
|
||||
// Get the matrixs for rendering
|
||||
int vanillaBlockRenderedDistance = MC_RENDER.getRenderDistance() * LodUtil.CHUNK_WIDTH;
|
||||
int lodChunkDist = Config.Client.Graphics.Quality.lodChunkRenderDistance.get();
|
||||
int farPlaneBlockDistance;
|
||||
// required for setupFog and setupProjectionMatrix
|
||||
if (MC.getWrappedClientWorld().getDimensionType().hasCeiling())
|
||||
farPlaneBlockDistance = Math.min(lodChunkDist, LodUtil.CEILED_DIMENSION_MAX_RENDER_DISTANCE) * LodUtil.CHUNK_WIDTH;
|
||||
else
|
||||
farPlaneBlockDistance = lodChunkDist * LodUtil.CHUNK_WIDTH;
|
||||
|
||||
Mat4f combinedMatrix = createCombinedMatrix(baseProjectionMatrix, baseModelViewMatrix,
|
||||
vanillaBlockRenderedDistance, farPlaneBlockDistance, partialTicks);
|
||||
Mat4f modelViewProjectionMatrix = RenderUtil.createCombinedModelViewProjectionMatrix(baseProjectionMatrix, baseModelViewMatrix, partialTicks);
|
||||
|
||||
/*---------Fill uniform data--------*/
|
||||
// Fill the uniform data. Note: GL33.GL_TEXTURE0 == texture bindpoint 0
|
||||
shaderProgram.fillUniformData(combinedMatrix,
|
||||
shaderProgram.fillUniformData(modelViewProjectionMatrix,
|
||||
MC_RENDER.isFogStateSpecial() ? getSpecialFogColor(partialTicks) : getFogColor(partialTicks),
|
||||
0, MC.getWrappedClientWorld().getHeight(), MC.getWrappedClientWorld().getMinHeight(), farPlaneBlockDistance,
|
||||
0, MC.getWrappedClientWorld().getHeight(), MC.getWrappedClientWorld().getMinHeight(), RenderUtil.getFarClipPlaneDistanceInBlocks(),
|
||||
vanillaBlockRenderedDistance, MC_RENDER.isFogStateSpecial());
|
||||
|
||||
// Note: Since lightmapTexture is changing every frame, it's faster to recreate it than to reuse the old one.
|
||||
@@ -272,6 +252,8 @@ public class a7LodRenderer
|
||||
tickLogger.incLogTries();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=================//
|
||||
// Setup Functions //
|
||||
//=================//
|
||||
@@ -313,44 +295,7 @@ public class a7LodRenderer
|
||||
return MC_RENDER.getSpecialFogColor(partialTicks);
|
||||
}
|
||||
|
||||
private static float calculateNearClipPlane(float distance, float partialTicks) {
|
||||
double fov = MC_RENDER.getFov(partialTicks);
|
||||
double aspectRatio = (double)MC_RENDER.getScreenWidth()/MC_RENDER.getScreenHeight();
|
||||
return (float) (distance
|
||||
/ Math.sqrt(1d + LodUtil.pow2(Math.tan(fov/180d*Math.PI/2d))
|
||||
* (LodUtil.pow2(aspectRatio) + 1d)));
|
||||
}
|
||||
|
||||
/**
|
||||
* create and return a new projection matrix based on MC's projection matrix
|
||||
* @param projMat this is Minecraft's current projection matrix
|
||||
* @param modelMat this is Minecraft's current model matrix
|
||||
* @param vanillaBlockRenderedDistance Minecraft's vanilla far plane distance
|
||||
*/
|
||||
private static Mat4f createCombinedMatrix(Mat4f projMat, Mat4f modelMat, float vanillaBlockRenderedDistance,
|
||||
int farPlaneBlockDistance, float partialTicks)
|
||||
{
|
||||
//Create a copy of the current matrix, so the current matrix isn't modified.
|
||||
Mat4f lodProj = projMat.copy();
|
||||
|
||||
float nearClipPlane;
|
||||
if (Config.Client.Advanced.lodOnlyMode.get()) {
|
||||
nearClipPlane = 0.1f;
|
||||
} else if (Config.Client.Graphics.AdvancedGraphics.useExtendedNearClipPlane.get()) {
|
||||
nearClipPlane = Math.min((vanillaBlockRenderedDistance-16f),8f*16f);
|
||||
} else {
|
||||
nearClipPlane = 16f;
|
||||
}
|
||||
|
||||
//Set new far and near clip plane values.
|
||||
lodProj.setClipPlanes(
|
||||
calculateNearClipPlane(nearClipPlane, partialTicks),
|
||||
(float)((farPlaneBlockDistance+LodUtil.REGION_WIDTH) * Math.sqrt(2)));
|
||||
|
||||
lodProj.multiply(modelMat);
|
||||
|
||||
return lodProj;
|
||||
}
|
||||
|
||||
|
||||
//======================//
|
||||
// Cleanup Functions //
|
||||
|
||||
@@ -32,6 +32,7 @@ import com.seibel.lod.core.logging.SpamReducedLogger;
|
||||
import com.seibel.lod.core.objects.math.Mat4f;
|
||||
import com.seibel.lod.core.render.GLProxy;
|
||||
import com.seibel.lod.core.render.RenderSystemTest;
|
||||
import com.seibel.lod.core.render.RenderUtil;
|
||||
import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper;
|
||||
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||
@@ -52,7 +53,7 @@ import java.util.concurrent.TimeUnit;
|
||||
* Specifically for the client.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2022-8-20
|
||||
* @version 2022-8-21
|
||||
*/
|
||||
public class ClientApi
|
||||
{
|
||||
@@ -231,19 +232,13 @@ public class ClientApi
|
||||
profiler.push("DH-RenderLevel");
|
||||
try
|
||||
{
|
||||
if (!MC.playerExists())
|
||||
return;
|
||||
if (levelWrapper == null)
|
||||
return;
|
||||
DhWorld dhWorld = SharedApi.currentWorld;
|
||||
if (dhWorld == null)
|
||||
return;
|
||||
if (!(SharedApi.currentWorld instanceof IClientWorld))
|
||||
if (!RenderUtil.shouldLodsRender(levelWrapper))
|
||||
return;
|
||||
|
||||
//FIXME: Improve class hierarchy of DhWorld, IClientWorld, IServerWorld to fix all this hard casting
|
||||
// (also in RenderUtil)
|
||||
DhWorld dhWorld = SharedApi.currentWorld;
|
||||
IClientLevel level = (IClientLevel) dhWorld.getOrLoadLevel(levelWrapper);
|
||||
if (level == null)
|
||||
return; //Level is not ready yet.
|
||||
|
||||
if (prefLoggerEnabled)
|
||||
{
|
||||
|
||||
@@ -19,25 +19,38 @@
|
||||
|
||||
package com.seibel.lod.core.render;
|
||||
|
||||
import com.seibel.lod.core.a7.level.IClientLevel;
|
||||
import com.seibel.lod.core.a7.world.DhWorld;
|
||||
import com.seibel.lod.core.a7.world.IClientWorld;
|
||||
import com.seibel.lod.core.api.internal.a7.SharedApi;
|
||||
import com.seibel.lod.core.config.Config;
|
||||
import com.seibel.lod.core.handlers.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.lod.core.objects.DHBlockPos;
|
||||
import com.seibel.lod.core.objects.DHChunkPos;
|
||||
import com.seibel.lod.core.objects.math.Mat4f;
|
||||
import com.seibel.lod.core.objects.math.Vec3f;
|
||||
import com.seibel.lod.core.util.LodUtil;
|
||||
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||
import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper;
|
||||
|
||||
/**
|
||||
* This holds miscellaneous helper code
|
||||
* to be used in the rendering process.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 10-19-2021
|
||||
* @version 2022-8-21
|
||||
*/
|
||||
public class RenderUtil
|
||||
{
|
||||
private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
||||
private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
|
||||
|
||||
|
||||
//=================//
|
||||
// culling methods //
|
||||
//=================//
|
||||
|
||||
/**
|
||||
* Returns if the given ChunkPos is in the loaded area of the world.
|
||||
* @param center the center of the loaded world (probably the player's ChunkPos)
|
||||
@@ -64,7 +77,6 @@ public class RenderUtil
|
||||
&& z <= centerCoordinate + MC_RENDER.getRenderDistance());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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).
|
||||
@@ -80,7 +92,6 @@ public class RenderUtil
|
||||
&& j <= lodRadius + halfRadius);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if one of the region's 4 corners is in front
|
||||
* of the camera.
|
||||
@@ -118,4 +129,112 @@ public class RenderUtil
|
||||
// flickering or odd disappearances
|
||||
return objectVector.dotProduct(cameraDir) > -0.1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=====================//
|
||||
// matrix manipulation //
|
||||
//=====================//
|
||||
|
||||
/**
|
||||
* create and return a new projection matrix based on MC's modelView and projection matrices
|
||||
* @param mcProjMat Minecraft's current projection matrix
|
||||
*/
|
||||
public static Mat4f createLodProjectionMatrix(Mat4f mcProjMat, float partialTicks)
|
||||
{
|
||||
int farPlaneDistanceInBlocks = RenderUtil.getFarClipPlaneDistanceInBlocks();
|
||||
|
||||
// Create a copy of the current matrix, so it won't be modified.
|
||||
Mat4f lodProj = mcProjMat.copy();
|
||||
|
||||
// Set new far and near clip plane values.
|
||||
lodProj.setClipPlanes(
|
||||
getNearClipPlaneDistanceInBlocks(partialTicks),
|
||||
(float)((farPlaneDistanceInBlocks+LodUtil.REGION_WIDTH) * Math.sqrt(2)));
|
||||
|
||||
return lodProj;
|
||||
}
|
||||
|
||||
/** create and return a new projection matrix based on MC's modelView and projection matrices */
|
||||
public static Mat4f createLodModelViewMatrix(Mat4f mcModelViewMat)
|
||||
{
|
||||
// nothing beyond copying needs to be done to MC's MVM currently,
|
||||
// this method is just here in case that changes in the future
|
||||
return mcModelViewMat.copy();
|
||||
}
|
||||
|
||||
/**
|
||||
* create and return a new combined modelView/projection matrix based on MC's modelView and projection matrices
|
||||
* @param mcProjMat Minecraft's current projection matrix
|
||||
* @param mcModelViewMat Minecraft's current model view matrix
|
||||
*/
|
||||
public static Mat4f createCombinedModelViewProjectionMatrix(Mat4f mcProjMat, Mat4f mcModelViewMat, float partialTicks)
|
||||
{
|
||||
Mat4f lodProj = createLodProjectionMatrix(mcProjMat, partialTicks);
|
||||
lodProj.multiply(createLodModelViewMatrix(mcModelViewMat));
|
||||
return lodProj;
|
||||
}
|
||||
|
||||
public static float getNearClipPlaneDistanceInBlocks(float partialTicks)
|
||||
{
|
||||
int vanillaBlockRenderedDistance = MC_RENDER.getRenderDistance() * LodUtil.CHUNK_WIDTH;
|
||||
|
||||
float nearClipPlane;
|
||||
if (Config.Client.Advanced.lodOnlyMode.get()) {
|
||||
nearClipPlane = 0.1f;
|
||||
} else if (Config.Client.Graphics.AdvancedGraphics.useExtendedNearClipPlane.get()) {
|
||||
nearClipPlane = Math.min(vanillaBlockRenderedDistance - LodUtil.CHUNK_WIDTH, (float) 8 * LodUtil.CHUNK_WIDTH); // allow a max near clip plane of 8 chunks
|
||||
} else {
|
||||
nearClipPlane = 16f;
|
||||
}
|
||||
|
||||
// modify the based on the player's FOV
|
||||
double fov = MC_RENDER.getFov(partialTicks);
|
||||
double aspectRatio = (double) MC_RENDER.getScreenWidth() / MC_RENDER.getScreenHeight();
|
||||
return (float) (nearClipPlane
|
||||
/ Math.sqrt(1d + LodUtil.pow2(Math.tan(fov / 180d * Math.PI / 2d))
|
||||
* (LodUtil.pow2(aspectRatio) + 1d)));
|
||||
}
|
||||
public static int getFarClipPlaneDistanceInBlocks()
|
||||
{
|
||||
int lodChunkDist = Config.Client.Graphics.Quality.lodChunkRenderDistance.get();
|
||||
return lodChunkDist * LodUtil.CHUNK_WIDTH;
|
||||
}
|
||||
|
||||
/** @return false if LODs shouldn't be rendered for any reason */
|
||||
public static boolean shouldLodsRender(ILevelWrapper levelWrapper)
|
||||
{
|
||||
if (!MC.playerExists())
|
||||
return false;
|
||||
|
||||
if (levelWrapper == null)
|
||||
return false;
|
||||
|
||||
DhWorld dhWorld = SharedApi.currentWorld;
|
||||
if (dhWorld == null)
|
||||
return false;
|
||||
|
||||
if (!(SharedApi.currentWorld instanceof IClientWorld))
|
||||
return false; // don't attempt to render server worlds
|
||||
|
||||
//FIXME: Improve class hierarchy of DhWorld, IClientWorld, IServerWorld to fix all this hard casting
|
||||
// (also in ClientApi)
|
||||
IClientLevel level = (IClientLevel) dhWorld.getOrLoadLevel(levelWrapper);
|
||||
if (level == null)
|
||||
return false; //Level is not ready yet.
|
||||
|
||||
if (MC_RENDER.playerHasBlindnessEffect())
|
||||
{
|
||||
// if the player is blind, don't render LODs,
|
||||
// and don't change minecraft's fog
|
||||
// which blindness relies on.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (MC_RENDER.getLightmapWrapper() == null)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user