diff --git a/src/main/java/com/backsun/lod/mixin/MixinWorldRenderer.java b/src/main/java/com/backsun/lod/mixin/MixinWorldRenderer.java index 28cd04e8b..16bbd20e7 100644 --- a/src/main/java/com/backsun/lod/mixin/MixinWorldRenderer.java +++ b/src/main/java/com/backsun/lod/mixin/MixinWorldRenderer.java @@ -5,7 +5,8 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import com.backsun.lod.renderer.RenderGlobalHook; +import com.backsun.lod.LodMain; +import com.backsun.lod.util.LodConfig; import com.mojang.blaze3d.matrix.MatrixStack; import net.minecraft.client.renderer.RenderType; @@ -14,9 +15,22 @@ import net.minecraft.client.renderer.WorldRenderer; @Mixin(WorldRenderer.class) public class MixinWorldRenderer { - @Inject(at = @At("HEAD"), method = "renderBlockLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/matrix/MatrixStack;DDD)V", cancellable = false) - private void renderBlockLayer(RenderType blockLayerIn, MatrixStack matrixStackIn, double xIn, double yIn, double zIn, CallbackInfo callback) + private static float previousPartialTicks = 0; + + @Inject(at = @At("RETURN"), method = "renderSky(Lcom/mojang/blaze3d/matrix/MatrixStack;F)V", cancellable = false) + private void renderSky(MatrixStack matrixStackIn, float partialTicks, CallbackInfo callback) { - RenderGlobalHook.startRenderingStencil(blockLayerIn); + // get the partial ticks since renderBlockLayer doesn't + // have access to them + previousPartialTicks = partialTicks; + } + + @Inject(at = @At("HEAD"), method = "renderBlockLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/matrix/MatrixStack;DDD)V", cancellable = false) + private void renderBlockLayer(RenderType renderType, MatrixStack matrixStackIn, double xIn, double yIn, double zIn, CallbackInfo callback) + { + // only render if LODs are enabled and + // only render before solid blocks + if (LodConfig.CLIENT.drawLODs.get() && renderType == RenderType.getSolid()) + LodMain.client_proxy.renderLods(previousPartialTicks); } } diff --git a/src/main/java/com/backsun/lod/proxy/ClientProxy.java b/src/main/java/com/backsun/lod/proxy/ClientProxy.java index 2a8408f20..a47fba1b6 100644 --- a/src/main/java/com/backsun/lod/proxy/ClientProxy.java +++ b/src/main/java/com/backsun/lod/proxy/ClientProxy.java @@ -1,18 +1,13 @@ package com.backsun.lod.proxy; -import org.lwjgl.opengl.GL11; - import com.backsun.lod.builders.LodBuilder; import com.backsun.lod.objects.LodChunk; import com.backsun.lod.objects.LodDimension; import com.backsun.lod.objects.LodRegion; import com.backsun.lod.objects.LodWorld; import com.backsun.lod.renderer.LodRenderer; -import com.backsun.lod.renderer.RenderGlobalHook; -import com.backsun.lod.util.LodConfig; import net.minecraft.client.Minecraft; -import net.minecraftforge.client.event.RenderWorldLastEvent; import net.minecraftforge.event.world.BlockEvent; import net.minecraftforge.event.world.ChunkEvent; import net.minecraftforge.event.world.WorldEvent; @@ -49,25 +44,13 @@ public class ClientProxy // render event // //==============// - @SubscribeEvent - public void renderWorldLast(RenderWorldLastEvent event) - { - RenderGlobalHook.endRenderingStencil(); - GL11.glStencilFunc(GL11.GL_EQUAL, 0, 0xFF); - - if (LodConfig.CLIENT.drawLODs.get()) - renderLods(event.getPartialTicks()); - - GL11.glDisable(GL11.GL_STENCIL_TEST); - } - /** * Do any setup that is required to draw LODs * and then tell the LodRenderer to draw. */ public void renderLods(float partialTicks) { - // update the + // update each regions' width to match the new render distance int newWidth = Math.max(4, (mc.gameSettings.renderDistanceChunks * LodChunk.WIDTH * 2) / LodRegion.SIZE); if (lodWorld != null && lodBuilder.regionWidth != newWidth) { diff --git a/src/main/java/com/backsun/lod/renderer/LodRenderer.java b/src/main/java/com/backsun/lod/renderer/LodRenderer.java index 49f72970b..e31424b4e 100644 --- a/src/main/java/com/backsun/lod/renderer/LodRenderer.java +++ b/src/main/java/com/backsun/lod/renderer/LodRenderer.java @@ -241,18 +241,27 @@ public class LodRenderer // set the required open GL settings GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_FILL); GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); - GL11.glDisable(GL11.GL_TEXTURE_2D); + GL11.glDisable(GL11.GL_TEXTURE_2D); // TODO store the default values of each of these so they can be reset correctly GL11.glEnable(GL11.GL_CULL_FACE); GL11.glEnable(GL11.GL_COLOR_MATERIAL); GL11.glEnable(GL11.GL_DEPTH_TEST); + // disable the lights Minecraft uses + GL11.glDisable(GL11.GL_LIGHT0); + GL11.glDisable(GL11.GL_LIGHT1); + Matrix4f modelViewMatrix = generateModelViewMatrix(partialTicks); setupProjectionMatrix(partialTicks); setupLighting(partialTicks); NearFarFogSetting fogSetting = determineFogSettings(); - + + // determine the current fog settings so they can be + // reset after drawing the LODs + float defaultFogStartDist = GL11.glGetFloat(GL11.GL_FOG_START); + float defaultFogEndDist = GL11.glGetFloat(GL11.GL_FOG_END); + int defaultFogMode = GL11.glGetInteger(GL11.GL_FOG_MODE); @@ -278,19 +287,26 @@ public class LodRenderer profiler.endStartSection("LOD cleanup"); - // this must be done otherwise other parts of the screen may be drawn with a fog effect - // IE the GUI - FogRenderer.resetFog(); - RenderSystem.disableFog(); - GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_FILL); GL11.glEnable(GL11.GL_TEXTURE_2D); GL11.glDisable(LOD_GL_LIGHT_NUMBER); + // re-enable the lights Minecraft uses + GL11.glEnable(GL11.GL_LIGHT0); + GL11.glEnable(GL11.GL_LIGHT1); + // TODO record the light states before to make sure they are being reset correctly + RenderSystem.disableLighting(); // this can't be called until after the buffers are built // because otherwise the buffers may be set to the wrong size previousChunkRenderDistance = mc.gameSettings.renderDistanceChunks; + // reset the fog settings so the normal chunks + // will be drawn correctly + RenderSystem.fogStart(defaultFogStartDist); + RenderSystem.fogEnd(defaultFogEndDist); + RenderSystem.fogMode(defaultFogMode); + + // end of profiler tracking profiler.endSection(); @@ -478,7 +494,7 @@ public class LodRenderer { float sunBrightness = lodDimension.dimension.hasSkyLight() ? mc.world.getSunBrightness(partialTicks) : 0.2f; float gammaMultiplyer = (float)mc.gameSettings.gamma - 0.5f; - float lightStrength = sunBrightness - 0.7f + (gammaMultiplyer * 0.2f); + float lightStrength = sunBrightness - 0.4f + (gammaMultiplyer * 0.2f); float lightAmbient[] = {lightStrength, lightStrength, lightStrength, 1.0f}; diff --git a/src/main/java/com/backsun/lod/renderer/RenderGlobalHook.java b/src/main/java/com/backsun/lod/renderer/RenderGlobalHook.java deleted file mode 100644 index ad1c75e98..000000000 --- a/src/main/java/com/backsun/lod/renderer/RenderGlobalHook.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.backsun.lod.renderer; - - -import org.lwjgl.opengl.GL11; - -import net.minecraft.client.renderer.RenderType; - -/** - * This code is used for drawing - * to the stencil buffer. - * - * @author James Seibel - * @version 02-17-2021 - */ -public class RenderGlobalHook -{ - /** - * this variable should be the same as the method name below. - * It is used when transforming the RenderGlobal class' - * renderBlockLayer method. - */ - public static final String START_STENCIL_METHOD_NAME = "startRenderingStencil"; - - /** - * This method tells OpenGL to start drawing everything to the stencil. - * This is done to prevent LODs from being rendered on top of the world. - *

- * Called in the order (as of minecraft 1.16.4):
- * RenderType.getSolid()
- * RenderType.getCutoutMipped()
- * RenderType.getCutout()
- * RenderType.getTranslucent()
- * RenderType.getTripwire()
- */ - public static void startRenderingStencil(RenderType blockLayerIn) - { - // we only enable drawing to the stencil once since - // we want to skip the rendering of the out of world fog - // but catch everything else - if (blockLayerIn == RenderType.getSolid()) - { - // solid is the first layer rendered - // clear the buffer so we can start fresh. - // if this isn't cleared first we will have overlap with the fog - // outside the world - GL11.glClearStencil(0); - GL11.glStencilMask(0x11111111); - GL11.glClear(GL11.GL_STENCIL_BUFFER_BIT); - - GL11.glEnable(GL11.GL_STENCIL_TEST); - GL11.glStencilFunc(GL11.GL_ALWAYS, 1, 0x11111111); - GL11.glStencilMask(0b11111111); - GL11.glStencilOp(GL11.GL_KEEP, // this doesn't mater since GL_ALWAYS is being used - GL11.GL_KEEP, // stencil test passes - GL11.GL_REPLACE); // stencil + depth pass - } - } - - - /** - * this variable should be the same as the method name below. - * It is used when transforming the RenderGlobal class' - * renderBlockLayer method. - */ - public static final String END_STENCIL_METHOD_NAME = "endRenderingStencil"; - - /** - * Currently this method isn't used in any transformations since we end - * the stencil drawing in the ClientProxy right before we draw the LODs. - */ - public static void endRenderingStencil(RenderType blockLayerIn) - { - GL11.glStencilOp(GL11.GL_KEEP, // this doesn't mater since GL_ALWAYS is being used - GL11.GL_KEEP, // stencil test passes - GL11.GL_KEEP); // stencil + depth pass - } - - public static void endRenderingStencil() - { - endRenderingStencil(null); - } -}