From 33aded734556daa8ded23a12f4e9eab9843eb18e Mon Sep 17 00:00:00 2001 From: James Seibel Date: Tue, 10 Oct 2023 19:33:10 -0500 Subject: [PATCH] Fix Light map flickering when multiple client levels are active --- .../minecraft/MinecraftClientWrapper.java | 5 +++-- .../minecraft/MinecraftRenderWrapper.java | 22 +++++++++++-------- coreSubProjects | 2 +- .../fabric/mixins/client/MixinLightmap.java | 12 ++++++++-- .../forge/mixins/client/MixinLightmap.java | 12 ++++++++-- 5 files changed, 37 insertions(+), 16 deletions(-) diff --git a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/minecraft/MinecraftClientWrapper.java b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/minecraft/MinecraftClientWrapper.java index 66f901834..611172844 100644 --- a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/minecraft/MinecraftClientWrapper.java +++ b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/minecraft/MinecraftClientWrapper.java @@ -31,6 +31,7 @@ import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper; import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper; import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.enums.EDhDirection; +import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; import com.seibel.distanthorizons.coreapi.ModInfo; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; @@ -211,9 +212,9 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra @Nullable @Override - public ILevelWrapper getWrappedClientWorld() + public IClientLevelWrapper getWrappedClientLevel() { - if (mc.level == null) + if (this.mc.level == null) { return null; } diff --git a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/minecraft/MinecraftRenderWrapper.java b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/minecraft/MinecraftRenderWrapper.java index bc8020c4c..13fff0619 100644 --- a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/minecraft/MinecraftRenderWrapper.java +++ b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/minecraft/MinecraftRenderWrapper.java @@ -22,6 +22,7 @@ package com.seibel.distanthorizons.common.wrappers.minecraft; import java.awt.Color; import java.lang.invoke.MethodHandles; import java.util.Collection; +import java.util.HashMap; import java.util.HashSet; import java.util.stream.Collectors; @@ -40,6 +41,8 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.misc.ILightMapWrapper; #if PRE_MC_1_19_4 import com.mojang.math.Vector3f; #else +import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; +import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper; import org.joml.Vector3f; #endif #if MC_1_20_2 @@ -93,7 +96,11 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper private static final IOptifineAccessor OPTIFINE_ACCESSOR = ModAccessorInjector.INSTANCE.get(IOptifineAccessor.class); - public LightMapWrapper lightmap = null; + /** + * In the case of immersive portals multiple levels may be active at once, causing conflicting lightmaps.
+ * Requiring the use of multiple {@link LightMapWrapper}. + */ + public HashMap lightmapByLevelWrapper = new HashMap<>(); @@ -342,10 +349,7 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper } @Override - public ILightMapWrapper getLightmapWrapper() - { - return lightmap; - } + public ILightMapWrapper getLightmapWrapper(ILevelWrapper level) { return this.lightmapByLevelWrapper.get(level); } @Override public boolean isFogStateSpecial() @@ -365,13 +369,13 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper #endif } - public void updateLightmap(NativeImage lightPixels) + public void updateLightmap(NativeImage lightPixels, IClientLevelWrapper level) { - if (lightmap == null) + if (!this.lightmapByLevelWrapper.containsKey(level)) { - lightmap = new LightMapWrapper(); + this.lightmapByLevelWrapper.put(level, new LightMapWrapper()); } - lightmap.uploadLightmap(lightPixels); + this.lightmapByLevelWrapper.get(level).uploadLightmap(lightPixels); } } diff --git a/coreSubProjects b/coreSubProjects index 82b2bf143..ff90dc04b 160000 --- a/coreSubProjects +++ b/coreSubProjects @@ -1 +1 @@ -Subproject commit 82b2bf1434cf3004e0b006e52be9be5fb28bebc6 +Subproject commit ff90dc04b7e60d7415aa780934d8a824eb805f7f diff --git a/fabric/src/main/java/com/seibel/distanthorizons/fabric/mixins/client/MixinLightmap.java b/fabric/src/main/java/com/seibel/distanthorizons/fabric/mixins/client/MixinLightmap.java index 5d37d1d86..e6d886dee 100644 --- a/fabric/src/main/java/com/seibel/distanthorizons/fabric/mixins/client/MixinLightmap.java +++ b/fabric/src/main/java/com/seibel/distanthorizons/fabric/mixins/client/MixinLightmap.java @@ -3,6 +3,10 @@ package com.seibel.distanthorizons.fabric.mixins.client; import com.mojang.blaze3d.platform.NativeImage; import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper; +import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; +import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; +import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; +import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper; import net.minecraft.client.renderer.LightTexture; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; @@ -16,15 +20,19 @@ public class MixinLightmap { @Shadow @Final - public NativeImage lightPixels; + private NativeImage lightPixels; @Inject(method = "updateLightTexture", at = @At( value = "INVOKE", target = "Lnet/minecraft/client/renderer/texture/DynamicTexture;upload()V")) public void updateLightTexture(float f, CallbackInfo ci) { + // since the light map is always updated on the client render thread we should be able to access the client level at the same time + IMinecraftClientWrapper mc = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class); + IClientLevelWrapper clientLevel = mc.getWrappedClientLevel(); + //ApiShared.LOGGER.info("Lightmap update"); - MinecraftRenderWrapper.INSTANCE.updateLightmap(lightPixels); + MinecraftRenderWrapper.INSTANCE.updateLightmap(this.lightPixels, clientLevel); } } diff --git a/forge/src/main/java/com/seibel/distanthorizons/forge/mixins/client/MixinLightmap.java b/forge/src/main/java/com/seibel/distanthorizons/forge/mixins/client/MixinLightmap.java index ba7955ef5..c2b2bb9d4 100644 --- a/forge/src/main/java/com/seibel/distanthorizons/forge/mixins/client/MixinLightmap.java +++ b/forge/src/main/java/com/seibel/distanthorizons/forge/mixins/client/MixinLightmap.java @@ -3,6 +3,10 @@ package com.seibel.distanthorizons.forge.mixins.client; import com.mojang.blaze3d.platform.NativeImage; import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper; +import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; +import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; +import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; +import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper; import net.minecraft.client.renderer.LightTexture; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; @@ -16,15 +20,19 @@ public class MixinLightmap { @Shadow @Final - public NativeImage lightPixels; + private NativeImage lightPixels; @Inject(method = "updateLightTexture", at = @At( value = "INVOKE", target = "Lnet/minecraft/client/renderer/texture/DynamicTexture;upload()V")) public void updateLightTexture(float f, CallbackInfo ci) { + // since the light map is always updated on the client render thread we should be able to access the client level at the same time + IMinecraftClientWrapper mc = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class); + IClientLevelWrapper clientLevel = mc.getWrappedClientLevel(); + //ApiShared.LOGGER.info("Lightmap update"); - MinecraftRenderWrapper.INSTANCE.updateLightmap(lightPixels); + MinecraftRenderWrapper.INSTANCE.updateLightmap(this.lightPixels, clientLevel); } }