Fix Light map flickering when multiple client levels are active

This commit is contained in:
James Seibel
2023-10-10 19:33:10 -05:00
parent 53a6b9fcd0
commit 33aded7345
5 changed files with 37 additions and 16 deletions
@@ -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;
}
@@ -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. <br>
* Requiring the use of multiple {@link LightMapWrapper}.
*/
public HashMap<IClientLevelWrapper, LightMapWrapper> 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);
}
}
@@ -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);
}
}
@@ -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);
}
}