From fd67d1ac6662253ccd17d4be642a6053f5319620 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Fri, 17 Sep 2021 22:57:20 -0500 Subject: [PATCH] Change setupProjectionMatrix to be mc version agnostic Now the LOD projection matrix's zoom, transformation, distortion, etc. are all gotten dynamically from Minecraft's projection matrix. Hopefully this should prevent camera mods from breaking the mod. --- .../com/seibel/lod/render/LodRenderer.java | 108 ++++++++---------- 1 file changed, 45 insertions(+), 63 deletions(-) diff --git a/src/main/java/com/seibel/lod/render/LodRenderer.java b/src/main/java/com/seibel/lod/render/LodRenderer.java index eb7899c29..e7b146770 100644 --- a/src/main/java/com/seibel/lod/render/LodRenderer.java +++ b/src/main/java/com/seibel/lod/render/LodRenderer.java @@ -61,7 +61,6 @@ import net.minecraft.potion.Effects; import net.minecraft.profiler.IProfiler; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.ChunkPos; -import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.vector.Matrix4f; import net.minecraft.util.math.vector.Vector3d; import net.minecraft.util.math.vector.Vector3f; @@ -72,7 +71,7 @@ import net.minecraft.util.math.vector.Vector3f; * This is where LODs are draw to the world. * * @author James Seibel - * @version 9-14-2021 + * @version 9-17-2021 */ public class LodRenderer { @@ -241,15 +240,19 @@ public class LodRenderer // get the default projection matrix so we can // reset it after drawing the LODs - float[] defaultProjMatrix = new float[16]; - GL11.glGetFloatv(GL11.GL_PROJECTION_MATRIX, defaultProjMatrix); - + float[] mcProjMatrixRaw = new float[16]; + GL11.glGetFloatv(GL11.GL_PROJECTION_MATRIX, mcProjMatrixRaw); + Matrix4f mcProjectionMatrix = new Matrix4f(mcProjMatrixRaw); + // OpenGl outputs their matricies in col,row form instead of row,col + // (or maybe vice versa I have no idea :P) + mcProjectionMatrix.transpose(); + Matrix4f modelViewMatrix = generateModelViewMatrix(partialTicks); // required for setupFog and setupProjectionMatrix farPlaneBlockDistance = LodConfig.CLIENT.graphics.lodChunkRenderDistance.get() * LodUtil.CHUNK_WIDTH; - setupProjectionMatrix(partialTicks); + setupProjectionMatrix(mcProjectionMatrix, partialTicks); setupLighting(lodDim, partialTicks); NearFarFogSettings fogSettings = determineFogSettings(); @@ -319,10 +322,8 @@ public class LodRenderer // reset the projection matrix so anything drawn after // the LODs will use the correct projection matrix - Matrix4f mvm = new Matrix4f(defaultProjMatrix); - mvm.transpose(); - gameRender.resetProjectionMatrix(mvm); - + gameRender.resetProjectionMatrix(mcProjectionMatrix); + // clear the depth buffer so anything drawn is drawn // over the LODs GL11.glClear(GL11.GL_DEPTH_BUFFER_BIT); @@ -491,62 +492,43 @@ public class LodRenderer /** * create a new projection matrix and send it over to the GPU - *

- * A lot of this code is copied from renderLevel (line 567) - * in the GameRender class. The code copied is anything with - * a matrixStack and is responsible for making sure the LOD - * objects distort correctly relative to the rest of the world. - * Distortions are caused by: standing in a nether portal, - * nausea potion effect, walking bobbing. - * + * + * @param currentProjectionMatrix this is Minecraft's current projection matrix * @param partialTicks how many ticks into the frame we are */ - private void setupProjectionMatrix(float partialTicks) + private void setupProjectionMatrix(Matrix4f currentProjectionMatrix, float partialTicks) { - // Note: if the LOD objects don't distort correctly - // compared to regular minecraft terrain, make sure - // all the transformations in renderWorld are here too - - MatrixStack matrixStack = new MatrixStack(); - matrixStack.pushPose(); - - gameRender.bobHurt(matrixStack, partialTicks); - if (this.mc.getOptions().bobView) - { - gameRender.bobView(matrixStack, partialTicks); - } - - // potion and nausea effects - float f = MathHelper.lerp(partialTicks, this.mc.getPlayer().oPortalTime, this.mc.getPlayer().portalTime) * this.mc.getOptions().screenEffectScale * this.mc.getOptions().screenEffectScale; - if (f > 0.0F) - { - int i = this.mc.getPlayer().hasEffect(Effects.CONFUSION) ? 7 : 20; - float f1 = 5.0F / (f * f + 5.0F) - f * 0.04F; - f1 = f1 * f1; - Vector3f vector3f = new Vector3f(0.0F, MathHelper.SQRT_OF_TWO / 2.0F, MathHelper.SQRT_OF_TWO / 2.0F); - matrixStack.mulPose(vector3f.rotationDegrees((gameRender.tick + partialTicks) * i)); - matrixStack.scale(1.0F / f1, 1.0F, 1.0F); - float f2 = -(gameRender.tick + partialTicks) * i; - matrixStack.mulPose(vector3f.rotationDegrees(f2)); - } - - - // this projection matrix allows us to see past the normal - // world render distance - Matrix4f projectionMatrix = - Matrix4f.perspective( - getFov(partialTicks, true), - (float) this.mc.getWindow().getScreenWidth() / (float) this.mc.getWindow().getScreenHeight(), - // it is possible to see the near clip plane, but - // you have to be flying quickly in spectator mode through ungenerated - // terrain, so I don't think it is much of an issue. - mc.getRenderDistance()/2, - farPlaneBlockDistance * LodUtil.CHUNK_WIDTH * 2); - - // add the screen space distortions - projectionMatrix.multiply(matrixStack.last().pose()); - gameRender.resetProjectionMatrix(projectionMatrix); - return; + // create the new projection matrix + Matrix4f lodPoj = + Matrix4f.perspective( + getFov(partialTicks, true), + (float) this.mc.getWindow().getScreenWidth() / (float) this.mc.getWindow().getScreenHeight(), + mc.getRenderDistance()/2, + farPlaneBlockDistance * LodUtil.CHUNK_WIDTH * 2 / 4); + + // 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); + // 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(); + defaultMcProjInv.invert(); + + Matrix4f distortionMatrix = defaultMcProjInv.copy(); + distortionMatrix.multiply(currentProjectionMatrix); + + + // edit the lod projection to match Minecraft's + // (so the LODs line up with the real world) + lodPoj.multiply(distortionMatrix); + + // send the projection over to the GPU + gameRender.resetProjectionMatrix(lodPoj); }