From d0620091d2e5323096147740e464b1aa6cbb2711 Mon Sep 17 00:00:00 2001 From: Jonas Herzig Date: Sat, 24 Jul 2021 09:11:34 +0200 Subject: [PATCH] Add support for FREX Flawless Frames API (fixes #150) --- .../render/hooks/ForceChunkLoadingHook.java | 3 ++ .../render/rendering/VideoRenderer.java | 10 ++--- .../render/utils/FlawlessFrames.java | 40 +++++++++++++++++++ src/main/resources/fabric.mod.json | 3 ++ 4 files changed, 51 insertions(+), 5 deletions(-) create mode 100644 src/main/java/com/replaymod/render/utils/FlawlessFrames.java diff --git a/src/main/java/com/replaymod/render/hooks/ForceChunkLoadingHook.java b/src/main/java/com/replaymod/render/hooks/ForceChunkLoadingHook.java index 14143698..7352945f 100644 --- a/src/main/java/com/replaymod/render/hooks/ForceChunkLoadingHook.java +++ b/src/main/java/com/replaymod/render/hooks/ForceChunkLoadingHook.java @@ -1,5 +1,6 @@ package com.replaymod.render.hooks; +import com.replaymod.render.utils.FlawlessFrames; import net.minecraft.client.render.WorldRenderer; public class ForceChunkLoadingHook { @@ -9,11 +10,13 @@ public class ForceChunkLoadingHook { public ForceChunkLoadingHook(WorldRenderer renderGlobal) { this.hooked = renderGlobal; + FlawlessFrames.setEnabled(true); IForceChunkLoading.from(renderGlobal).replayModRender_setHook(this); } public void uninstall() { IForceChunkLoading.from(hooked).replayModRender_setHook(null); + FlawlessFrames.setEnabled(false); } public interface IBlockOnChunkRebuilds { diff --git a/src/main/java/com/replaymod/render/rendering/VideoRenderer.java b/src/main/java/com/replaymod/render/rendering/VideoRenderer.java index 6baf7a28..dfa7e096 100644 --- a/src/main/java/com/replaymod/render/rendering/VideoRenderer.java +++ b/src/main/java/com/replaymod/render/rendering/VideoRenderer.java @@ -23,6 +23,7 @@ import com.replaymod.render.hooks.ForceChunkLoadingHook; import com.replaymod.render.metadata.MetadataInjector; import com.replaymod.render.mixin.MainWindowAccessor; import com.replaymod.render.mixin.WorldRendererAccessor; +import com.replaymod.render.utils.FlawlessFrames; import com.replaymod.replay.ReplayHandler; import com.replaymod.replaystudio.pathing.path.Keyframe; import com.replaymod.replaystudio.pathing.path.Path; @@ -707,11 +708,11 @@ public class VideoRenderer implements RenderInfo { public static String[] checkCompat(RenderSettings settings) { //#if FABRIC>=1 - if (net.fabricmc.loader.api.FabricLoader.getInstance().isModLoaded("sodium")) { + if (net.fabricmc.loader.api.FabricLoader.getInstance().isModLoaded("sodium") && !FlawlessFrames.hasSodium()) { return new String[] { - "Rendering is not currently supported while Sodium is installed.", - "See https://github.com/ReplayMod/ReplayMod/issues/150", - "For now, you need to uninstall Sodium before rendering!" + "Rendering is not supported with your Sodium version.", + "It is missing support for the FREX Flawless Frames API.", + "Either update to the latest version or uninstall Sodium before rendering!", }; } //#if MC>=11700 @@ -721,7 +722,6 @@ public class VideoRenderer implements RenderInfo { //$$ "ODS export requires Iris to be installed for Minecraft 1.17 and above.", //$$ "Note that it is nevertheless incompatible with other shaders and will simply replace them.", //$$ "Get it from: https://irisshaders.net/", - //$$ "Use the Standalone version! Sodium is not currently compatible with rendering!", //$$ }; //$$ } //#endif diff --git a/src/main/java/com/replaymod/render/utils/FlawlessFrames.java b/src/main/java/com/replaymod/render/utils/FlawlessFrames.java new file mode 100644 index 00000000..e419adef --- /dev/null +++ b/src/main/java/com/replaymod/render/utils/FlawlessFrames.java @@ -0,0 +1,40 @@ +package com.replaymod.render.utils; + +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.function.Consumer; +import java.util.function.Function; + +import static com.replaymod.core.ReplayMod.MOD_ID; + +/** + * Uses the "Flawless Frames" FREX feature which allows us to instruct third-party mods to sacrifice performance (even + * beyond the point where it can no longer achieve interactive frame rates) in exchange for a noticeable boost to + * quality. + * In particular also to force-load all chunks with Canvas/Sodium/Bobby. + * + * See https://github.com/grondag/frex/pull/9 + */ +public class FlawlessFrames { + private static final List> CONSUMERS = new CopyOnWriteArrayList<>(); + private static boolean hasSodium; + + private FlawlessFrames() {} + + public static void registerConsumer(Function> provider) { + Consumer consumer = provider.apply(MOD_ID); + CONSUMERS.add(consumer); + + if (provider.getClass().getName().contains(".sodium.") || consumer.getClass().getName().contains(".sodium.")) { + hasSodium = true; + } + } + + public static void setEnabled(boolean enabled) { + CONSUMERS.forEach(it -> it.accept(enabled)); + } + + public static boolean hasSodium() { + return hasSodium; + } +} diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 8dc61a19..6eb336ce 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -25,6 +25,9 @@ "modmenu": [ "com.replaymod.core.gui.ModMenuApiImpl" ], + "frex_flawless_frames": [ + "com.replaymod.render.utils.FlawlessFrames::registerConsumer" + ], "preLaunch": [ "com.replaymod.core.DummyChainLoadEntryPoint" ],