Replace Matrix4f (MC) with Mat4f (ours) in LodRenderer

This commit is contained in:
James Seibel
2021-11-11 23:16:59 -06:00
parent 12a14b4855
commit 1ca7ac6671
10 changed files with 148 additions and 81 deletions
@@ -1,9 +1,14 @@
package com.seibel.lod.api;
import com.seibel.lod.LodMain;
import com.seibel.lod.objects.rending.Mat4f;
import net.minecraft.util.math.vector.Matrix4f;
/**
* TODO
*
* @author James Seibel
* @version 11-11-2021
*/
public class ClientApi
{
@@ -15,9 +20,12 @@ public class ClientApi
public void renderLods(Matrix4f mcModelViewMatrix, float partialTicks)
public static void renderLods(Mat4f mcModelViewMatrix, float partialTicks)
{
LodMain.client_proxy.renderLods(mcModelViewMatrix, partialTicks);
}
}
@@ -25,7 +25,9 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.seibel.lod.LodMain;
import com.seibel.lod.api.ClientApi;
import com.seibel.lod.objects.rending.Mat4f;
import com.seibel.lod.wrappers.McObjectConverter;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.WorldRenderer;
@@ -59,6 +61,9 @@ public class MixinWorldRenderer
// only render if LODs are enabled and
// only render before solid blocks
if (renderType.equals(RenderType.solid()))
LodMain.client_proxy.renderLods(matrixStackIn, previousPartialTicks);
{
Mat4f mcModelViewMatrix = McObjectConverter.Convert(matrixStackIn.last().pose());
ClientApi.renderLods(mcModelViewMatrix, previousPartialTicks);
}
}
}
@@ -2,33 +2,31 @@ package com.seibel.lod.objects.rending;
import java.nio.FloatBuffer;
import net.minecraft.util.math.vector.Vector3f;
/**
* A (almost) exact copy of Minecraft's 1.16.5
* implementation of a 4x4 matrix.
*
* @author James Seibel
*
* @version 11-11-2021
*/
public class Mat4f
{
protected float m00;
protected float m01;
protected float m02;
protected float m03;
protected float m10;
protected float m11;
protected float m12;
protected float m13;
protected float m20;
protected float m21;
protected float m22;
protected float m23;
protected float m30;
protected float m31;
protected float m32;
protected float m33;
private float m00;
private float m01;
private float m02;
private float m03;
private float m10;
private float m11;
private float m12;
private float m13;
private float m20;
private float m21;
private float m22;
private float m23;
private float m30;
private float m31;
private float m32;
private float m33;
public Mat4f()
@@ -377,20 +375,18 @@ public class Mat4f
this.m33 *= scalar;
}
/* not currently needed/implemented
* Also the parameter names should be double checked as they may be incorrect
public static Matrix4Float perspective(double fov, float heightWidthRatio, float nearClipPlane, float farClipPlane)
public static Mat4f perspective(double fov, float widthHeightRatio, float nearClipPlane, float farClipPlane)
{
float f = (float) (1.0D / Math.tan(fov * ((float) Math.PI / 180F) / 2.0D));
Matrix4Float matrix = new Matrix4Float();
matrix.m00 = f / heightWidthRatio;
Mat4f matrix = new Mat4f();
matrix.m00 = f / widthHeightRatio;
matrix.m11 = f;
matrix.m22 = (farClipPlane + nearClipPlane) / (nearClipPlane - farClipPlane);
matrix.m32 = -1.0F;
matrix.m23 = 2.0F * farClipPlane * nearClipPlane / (nearClipPlane - farClipPlane);
return matrix;
}
*/
/* not currently needed/implemented
* Also the parameter names should be double checked as they may be incorrect
@@ -409,11 +405,21 @@ public class Mat4f
}
*/
public void translate(Vector3f vec)
/**
* TODO: what kind of translation is this?
* and how is this different from "multiplyTranslationMatrix"?
*/
public void translate(Vec3f vec)
{
this.m03 += vec.x();
this.m13 += vec.y();
this.m23 += vec.z();
this.m03 += vec.x;
this.m13 += vec.y;
this.m23 += vec.z;
}
/** originally "translate" from Minecraft's MatrixStack */
public void multiplyTranslationMatrix(double x, double y, double z)
{
multiply(createTranslateMatrix((float)x, (float)y, (float)z));
}
public Mat4f copy()
@@ -466,6 +472,11 @@ public class Mat4f
m33 = values[15];
}
public Mat4f(FloatBuffer buffer)
{
this(buffer.array());
}
public void set(Mat4f mat)
{
this.m00 = mat.m00;
@@ -2,16 +2,23 @@ package com.seibel.lod.objects.rending;
import com.seibel.lod.util.LodUtil;
import net.minecraft.util.math.MathHelper;
/**
* A (almost) exact copy of Minecraft's 1.16.5
* implementation of a 3 element vector.
*
* @author James Seibel
* @version 11-11-2021
*/
public class Vec3f
{
public static Vec3f XN = new Vec3f(-1.0F, 0.0F, 0.0F);
public static Vec3f XP = new Vec3f(1.0F, 0.0F, 0.0F);
public static Vec3f YN = new Vec3f(0.0F, -1.0F, 0.0F);
public static Vec3f YP = new Vec3f(0.0F, 1.0F, 0.0F);
public static Vec3f ZN = new Vec3f(0.0F, 0.0F, -1.0F);
public static Vec3f ZP = new Vec3f(0.0F, 0.0F, 1.0F);
public static Vec3f XNeg = new Vec3f(-1.0F, 0.0F, 0.0F);
public static Vec3f XPos = new Vec3f(1.0F, 0.0F, 0.0F);
public static Vec3f YNeg = new Vec3f(0.0F, -1.0F, 0.0F);
public static Vec3f YPos = new Vec3f(0.0F, 1.0F, 0.0F);
public static Vec3f ZNeg = new Vec3f(0.0F, 0.0F, -1.0F);
public static Vec3f ZPos = new Vec3f(0.0F, 0.0F, 1.0F);
public float x;
public float y;
public float z;
@@ -130,7 +137,7 @@ public class Vec3f
}
else
{
float f1 = MathHelper.fastInvSqrt(squaredSum);
float f1 = LodUtil.fastInvSqrt(squaredSum);
this.x *= f1;
this.y *= f1;
this.z *= f1;
@@ -24,7 +24,6 @@ import org.apache.logging.log4j.Logger;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.opengl.GL15;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.seibel.lod.builders.bufferBuilding.LodBufferBuilder;
import com.seibel.lod.builders.lodBuilding.LodBuilder;
import com.seibel.lod.builders.worldGeneration.LodGenWorker;
@@ -34,6 +33,7 @@ import com.seibel.lod.enums.DistanceGenerationMode;
import com.seibel.lod.objects.lod.LodDimension;
import com.seibel.lod.objects.lod.LodWorld;
import com.seibel.lod.objects.lod.RegionPos;
import com.seibel.lod.objects.rending.Mat4f;
import com.seibel.lod.render.LodRenderer;
import com.seibel.lod.util.DataPointUtil;
import com.seibel.lod.util.DetailDistanceUtil;
@@ -43,7 +43,6 @@ import com.seibel.lod.wrappers.MinecraftWrapper;
import com.seibel.lod.wrappers.Chunk.ChunkWrapper;
import net.minecraft.profiler.IProfiler;
import net.minecraft.util.math.vector.Matrix4f;
import net.minecraft.util.text.StringTextComponent;
import net.minecraftforge.client.event.InputEvent;
import net.minecraftforge.event.TickEvent;
@@ -101,7 +100,7 @@ public class ClientProxy
//==============//
/** Do any setup that is required to draw LODs and then tell the LodRenderer to draw. */
public void renderLods(MatrixStack mcModelViewMatrix, float partialTicks)
public void renderLods(Mat4f mcModelViewMatrix, float partialTicks)
{
// comment out when creating a release
// applyConfigOverrides();
@@ -135,7 +134,7 @@ public class ClientProxy
// reset it after drawing the LODs
float[] mcProjMatrixRaw = new float[16];
GL15.glGetFloatv(GL15.GL_PROJECTION_MATRIX, mcProjMatrixRaw);
Matrix4f mcProjectionMatrix = new Matrix4f(mcProjMatrixRaw);
Mat4f mcProjectionMatrix = new Mat4f(mcProjMatrixRaw);
// OpenGl outputs their matrices in col,row form instead of row,col
// (or maybe vice versa I have no idea :P)
mcProjectionMatrix.transpose();
@@ -26,7 +26,6 @@ import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;
import org.lwjgl.opengl.NVFogDistance;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.seibel.lod.builders.bufferBuilding.LodBufferBuilder;
import com.seibel.lod.builders.bufferBuilding.LodBufferBuilder.VertexBuffersAndOffset;
import com.seibel.lod.config.LodConfig;
@@ -38,6 +37,7 @@ import com.seibel.lod.enums.GpuUploadMethod;
import com.seibel.lod.handlers.ReflectionHandler;
import com.seibel.lod.objects.lod.LodDimension;
import com.seibel.lod.objects.lod.RegionPos;
import com.seibel.lod.objects.rending.Mat4f;
import com.seibel.lod.objects.rending.NearFarFogSettings;
import com.seibel.lod.proxy.ClientProxy;
import com.seibel.lod.proxy.GlProxy;
@@ -45,6 +45,7 @@ import com.seibel.lod.render.shader.LodShaderProgram;
import com.seibel.lod.util.DetailDistanceUtil;
import com.seibel.lod.util.LevelPosUtil;
import com.seibel.lod.util.LodUtil;
import com.seibel.lod.wrappers.McObjectConverter;
import com.seibel.lod.wrappers.MinecraftWrapper;
import com.seibel.lod.wrappers.Block.BlockPosWrapper;
import com.seibel.lod.wrappers.Chunk.ChunkPosWrapper;
@@ -55,7 +56,6 @@ import net.minecraft.client.renderer.vertex.VertexBuffer;
import net.minecraft.potion.Effects;
import net.minecraft.profiler.IProfiler;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.math.vector.Matrix4f;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.util.math.vector.Vector3f;
@@ -157,7 +157,7 @@ public class LodRenderer
* @param mcProjectionMatrix
* @param partialTicks how far into the current tick this method was called.
*/
public void drawLODs(LodDimension lodDim, MatrixStack mcModelViewMatrix, Matrix4f mcProjectionMatrix, float partialTicks, IProfiler newProfiler)
public void drawLODs(LodDimension lodDim, Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, float partialTicks, IProfiler newProfiler)
{
//=================================//
// determine if LODs should render //
@@ -248,7 +248,7 @@ public class LodRenderer
int currentProgram = GL20.glGetInteger(GL20.GL_CURRENT_PROGRAM);
Matrix4f modelViewMatrix = offsetTheModelViewMatrix(mcModelViewMatrix, partialTicks);
Mat4f modelViewMatrix = offsetTheModelViewMatrix(mcModelViewMatrix, partialTicks);
vanillaBlockRenderedDistance = mc.getRenderDistance() * LodUtil.CHUNK_WIDTH;
// required for setupFog and setupProjectionMatrix
if (mc.getClientLevel().dimensionType().hasCeiling())
@@ -257,7 +257,7 @@ public class LodRenderer
farPlaneBlockDistance = LodConfig.CLIENT.graphics.qualityOption.lodChunkRenderDistance.get() * LodUtil.CHUNK_WIDTH;
Matrix4f projectionMatrix = createProjectionMatrix(mcProjectionMatrix, vanillaBlockRenderedDistance, partialTicks);
Mat4f projectionMatrix = createProjectionMatrix(mcProjectionMatrix, vanillaBlockRenderedDistance, partialTicks);
// commented out until we can add shaders to handle lighting
@@ -543,12 +543,8 @@ public class LodRenderer
* (since AxisAlignedBoundingBoxes (LODs) use doubles and thus have a higher
* accuracy vs the model view matrix, which only uses floats)
*/
private Matrix4f offsetTheModelViewMatrix(MatrixStack mcModelViewMatrix, float partialTicks)
private Mat4f offsetTheModelViewMatrix(Mat4f mcModelViewMatrix, float partialTicks)
{
// duplicate the last matrix
mcModelViewMatrix.pushPose();
// get all relevant camera info
ActiveRenderInfo camera = mc.getGameRenderer().getMainCamera();
Vector3d projectedView = camera.getPosition();
@@ -559,16 +555,9 @@ public class LodRenderer
BlockPosWrapper bufferPos = vbosCenter.getWorldPosition();
double xDiff = projectedView.x - bufferPos.getX();
double zDiff = projectedView.z - bufferPos.getZ();
mcModelViewMatrix.translate(-xDiff, -projectedView.y, -zDiff);
mcModelViewMatrix.multiplyTranslationMatrix(-xDiff, -projectedView.y, -zDiff);
// get the modified model view matrix
Matrix4f lodModelViewMatrix = mcModelViewMatrix.last().pose();
// remove the lod ModelViewMatrix
mcModelViewMatrix.popPose();
return lodModelViewMatrix;
return mcModelViewMatrix;
}
/**
@@ -577,30 +566,30 @@ public class LodRenderer
* @param vanillaBlockRenderedDistance Minecraft's vanilla far plane distance
* @param partialTicks how many ticks into the frame we are
*/
private Matrix4f createProjectionMatrix(Matrix4f currentProjectionMatrix, float vanillaBlockRenderedDistance, float partialTicks)
private Mat4f createProjectionMatrix(Mat4f currentProjectionMatrix, float vanillaBlockRenderedDistance, float partialTicks)
{
// create the new projection matrix
Matrix4f lodProj =
Matrix4f.perspective(
getFov(partialTicks, true),
(float) this.mc.getWindow().getScreenWidth() / (float) this.mc.getWindow().getScreenHeight(),
LodConfig.CLIENT.graphics.advancedGraphicsOption.useExtendedNearClipPlane.get() ? vanillaBlockRenderedDistance / 5 : 1,
farPlaneBlockDistance * LodUtil.CHUNK_WIDTH / 2);
Mat4f lodProj = Mat4f.perspective(
getFov(partialTicks, true),
(float) this.mc.getWindow().getScreenWidth() / (float) this.mc.getWindow().getScreenHeight(),
LodConfig.CLIENT.graphics.advancedGraphicsOption.useExtendedNearClipPlane.get() ? vanillaBlockRenderedDistance / 5 : 1,
farPlaneBlockDistance * LodUtil.CHUNK_WIDTH / 2);
// get Minecraft's un-edited projection matrix
// (this is before it is zoomed, distorted, etc.)
Matrix4f defaultMcProj = mc.getGameRenderer().getProjectionMatrix(mc.getGameRenderer().getMainCamera(), partialTicks, true);
Mat4f defaultMcProj = McObjectConverter.Convert(mc.getGameRenderer().getProjectionMatrix(mc.getGameRenderer().getMainCamera(), partialTicks, true));
// true here means use "use fov setting" (probably)
// this logic strips away the defaultMcProj matrix, so we
// can get the distortionMatrix, which represents all
// transformations, zooming, distortions, etc. done
// to Minecraft's Projection matrix
Matrix4f defaultMcProjInv = defaultMcProj.copy();
Mat4f defaultMcProjInv = defaultMcProj.copy();
defaultMcProjInv.invert();
Matrix4f distortionMatrix = defaultMcProjInv.copy();
Mat4f distortionMatrix = defaultMcProjInv.copy();
distortionMatrix.multiply(currentProjectionMatrix);
@@ -611,7 +600,6 @@ public class LodRenderer
return lodProj;
}
///** setup the lighting to be used for the LODs */
/*private void setupLighting(LodDimension lodDimension, float partialTicks)
{
@@ -24,7 +24,7 @@ import java.nio.FloatBuffer;
import org.lwjgl.opengl.GL20;
import org.lwjgl.system.MemoryStack;
import net.minecraft.util.math.vector.Matrix4f;
import com.seibel.lod.objects.rending.Mat4f;
/**
@@ -169,7 +169,7 @@ public class LodShaderProgram
* @param location Uniform location
* @param value Value to set
*/
public void setUniform(int location, Matrix4f value)
public void setUniform(int location, Mat4f value)
{
try (MemoryStack stack = MemoryStack.stackPush())
{
+12 -1
View File
@@ -29,9 +29,9 @@ import com.seibel.lod.enums.HorizontalResolution;
import com.seibel.lod.enums.VanillaOverdraw;
import com.seibel.lod.objects.lod.LodDimension;
import com.seibel.lod.objects.lod.RegionPos;
import com.seibel.lod.wrappers.MinecraftWrapper;
import com.seibel.lod.wrappers.Block.BlockPosWrapper;
import com.seibel.lod.wrappers.Chunk.ChunkPosWrapper;
import com.seibel.lod.wrappers.MinecraftWrapper;
import net.minecraft.client.multiplayer.ServerData;
import net.minecraft.client.renderer.WorldRenderer;
@@ -498,4 +498,15 @@ public class LodUtil
}
return false;
}
/** This is copied from Minecraft's MathHelper class */
public static float fastInvSqrt(float numb)
{
float half = 0.5F * numb;
int i = Float.floatToIntBits(numb);
i = 1597463007 - (i >> 1);
numb = Float.intBitsToFloat(i);
return numb * (1.5F - half * numb * numb);
}
}
@@ -58,6 +58,8 @@ public class ThreadMapUtil
public static final ConcurrentMap<String, Map<Direction, long[]>> adjDataMap = new ConcurrentHashMap<>();
public static final ConcurrentMap<String, Box> boxMap = new ConcurrentHashMap<>();
/** returns the array NOT cleared every time */
public static boolean[] getAdjShadeDisabledArray()
{
@@ -0,0 +1,36 @@
package com.seibel.lod.wrappers;
import java.nio.FloatBuffer;
import com.seibel.lod.objects.rending.Mat4f;
import net.minecraft.util.math.vector.Matrix4f;
/**
* This class converts between Minecraft objects (Ex: Matrix4f)
* and objects we created (Ex: Mat4f).
* Since we don't want to deal with a bunch of tiny changes
* every time Minecraft renames a variable in Matrix4f or something.
*
* @author James Seibel
* @version 11-11-2021
*/
public class McObjectConverter
{
public McObjectConverter()
{
}
/** 4x4 float matrix converter */
public static Mat4f Convert(Matrix4f mcMatrix)
{
FloatBuffer buffer = FloatBuffer.allocate(16);
mcMatrix.store(buffer);
Mat4f matrix = new Mat4f(buffer);
matrix.transpose();
return matrix;
}
}