diff --git a/build.gradle b/build.gradle index 64ad3ee48..043f1dcd3 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,7 @@ buildscript { maven { url 'https://jitpack.io' } } dependencies { - classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '3.+', changing: true + classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '5.1.+', changing: true classpath group: 'org.spongepowered', name: 'mixingradle', version: '0.7-SNAPSHOT' } } @@ -19,20 +19,12 @@ apply plugin: 'org.spongepowered.mixin' // Only edit below this line, the above code adds and enables the necessary things for Forge to be setup. apply plugin: 'eclipse' apply plugin: 'maven-publish' -apply plugin: 'java' // needed for compileJava version = 'a1.4.1' group = 'com.seibel.lod' archivesBaseName = 'lod_1.16.5' -sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8' // Need this here so eclipse task generates correctly. - -compileJava { - // release 8 is needed because otherwise FloatBuffer.flip() will crash - // on some machines - // example thread: https://github.com/eclipse/jetty.project/issues/3244 - options.compilerArgs.addAll(['-Xlint:unchecked', '-Xlint:deprecation']) -} +java.toolchain.languageVersion = JavaLanguageVersion.of(8) // Mojang ships Java 8 to end users, so your mod should target Java 8. println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getProperty('java.vm.version') + '(' + System.getProperty('java.vendor') + ') Arch: ' + System.getProperty('os.arch')) minecraft { diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 7a3265ee9..e708b1c02 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 1d5b29fbd..05679dc3c 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.3-bin.zip diff --git a/src/main/java/com/seibel/lod/config/LodConfig.java b/src/main/java/com/seibel/lod/config/LodConfig.java index 987a25bae..b3d0d111a 100644 --- a/src/main/java/com/seibel/lod/config/LodConfig.java +++ b/src/main/java/com/seibel/lod/config/LodConfig.java @@ -20,13 +20,21 @@ package com.seibel.lod.config; import java.nio.file.Path; import java.nio.file.Paths; -import com.seibel.lod.enums.*; import org.apache.commons.lang3.tuple.Pair; import org.apache.logging.log4j.LogManager; import com.electronwill.nightconfig.core.file.CommentedFileConfig; import com.electronwill.nightconfig.core.io.WritingMode; import com.seibel.lod.ModInfo; +import com.seibel.lod.enums.DebugMode; +import com.seibel.lod.enums.DistanceCalculatorType; +import com.seibel.lod.enums.DistanceGenerationMode; +import com.seibel.lod.enums.FogDistance; +import com.seibel.lod.enums.FogDrawOverride; +import com.seibel.lod.enums.LodDetail; +import com.seibel.lod.enums.LodQualityMode; +import com.seibel.lod.enums.LodTemplate; +import com.seibel.lod.enums.ShadingMode; import net.minecraftforge.common.ForgeConfigSpec; import net.minecraftforge.eventbus.api.SubscribeEvent; @@ -37,7 +45,7 @@ import net.minecraftforge.fml.config.ModConfig; * This handles any configuration the user has access to. * * @author James Seibel - * @version 9-1-2021 + * @version 9-17-2021 */ @Mod.EventBusSubscriber public class LodConfig @@ -87,6 +95,8 @@ public class LodConfig public ForgeConfigSpec.IntValue lodChunkRenderDistance; + public ForgeConfigSpec.BooleanValue disableDirectionalCulling; + public ForgeConfigSpec.DoubleValue brightnessMultiplier; public ForgeConfigSpec.DoubleValue saturationMultiplier; @@ -150,6 +160,18 @@ public class LodConfig + " This is the render distance of the mod \n") .defineInRange("lodChunkRenderDistance", 64, 32, 512); + disableDirectionalCulling = builder + .comment("\n\n" + + " If false LODs that are behind the player's camera \n" + + " aren't drawn, increasing performance. \n\n" + + "" + + " If true all LODs are drawn, even those behind \n" + + " the player's camera, decreasing performance. \n\n" + + "" + + " Disable this if you see LODs disapearing. \n" + + " (This may happen if you are using a camera mod) \n") + .define("disableDirectionalCulling", false); + shadingMode = builder .comment("\n\n" + " What kind of shading should the LODs have? \n" diff --git a/src/main/java/com/seibel/lod/render/LodRenderer.java b/src/main/java/com/seibel/lod/render/LodRenderer.java index 03a7bd2fc..a02c73f56 100644 --- a/src/main/java/com/seibel/lod/render/LodRenderer.java +++ b/src/main/java/com/seibel/lod/render/LodRenderer.java @@ -23,7 +23,6 @@ import java.nio.FloatBuffer; import java.util.HashSet; import java.util.Iterator; -import net.minecraft.client.renderer.texture.NativeImage; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL15; import org.lwjgl.opengl.GL15C; @@ -53,6 +52,7 @@ import com.seibel.lod.wrappers.MinecraftWrapper; import net.minecraft.client.renderer.ActiveRenderInfo; import net.minecraft.client.renderer.FogRenderer; import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.client.renderer.texture.NativeImage; import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.renderer.vertex.VertexBuffer; import net.minecraft.client.renderer.vertex.VertexFormat; @@ -62,7 +62,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; @@ -73,7 +72,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 { @@ -124,7 +123,10 @@ public class LodRenderer * This is used to determine if the LODs should be regenerated */ private int[] previousPos = new int[]{0,0,0}; + public NativeImage lightMap = null; + + // these variables are used to determine if the buffers should be rebuilt private long prevDayTime = 0; private double prevBrightness = 0; private int prevRenderDistance = 0; @@ -245,15 +247,20 @@ 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); + // commented out until we can add shaders to handle lighting //setupLighting(lodDim, partialTicks); NearFarFogSettings fogSettings = determineFogSettings(); @@ -278,6 +285,7 @@ public class LodRenderer Vector3d cameraDir = cameraEntity.getLookAngle().normalize(); cameraDir = mc.getOptions().getCameraType().isMirrored() ? cameraDir.reverse() : cameraDir; + boolean cullingDisabled = LodConfig.CLIENT.graphics.disableDirectionalCulling.get(); // used to determine what type of fog to render int halfWidth = vbos.length / 2; @@ -288,7 +296,7 @@ public class LodRenderer for (int j = 0; j < vbos.length; j++) { RegionPos vboPos = new RegionPos(i + lodDim.getCenterX() - lodDim.getWidth() / 2, j + lodDim.getCenterZ() - lodDim.getWidth() / 2); - if (RenderUtil.isRegionInViewFrustum(cameraEntity.blockPosition(), cameraDir, vboPos.blockPos())) + if (cullingDisabled || RenderUtil.isRegionInViewFrustum(cameraEntity.blockPosition(), cameraDir, vboPos.blockPos())) { if ((i > halfWidth - quarterWidth && i < halfWidth + quarterWidth) && (j > halfWidth - quarterWidth && j < halfWidth + quarterWidth)) setupFog(fogSettings.near.distance, fogSettings.near.quality); @@ -323,10 +331,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); @@ -495,62 +501,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); } @@ -858,7 +845,7 @@ public class LodRenderer prevChunkTime = newTime; } - // check if there is any newly generated terrain to show + // check if the lighting has changed if (mc.getWorld().getDayTime() - prevDayTime > 1000 || mc.getOptions().gamma != prevBrightness || lightMap == null) { fullRegen = true;