From 030c71c868e70205d9d2e43d691d073c33ef876e Mon Sep 17 00:00:00 2001 From: CrushedPixel Date: Mon, 28 Nov 2016 23:21:20 +0100 Subject: [PATCH] Automatically disable and re-enable Optifine's Fast Render setting before rendering a video --- .../com/replaymod/compat/ReplayModCompat.java | 2 + .../compat/optifine/DisableFastRender.java | 37 +++++++++++++++++++ .../compat/optifine/OptifineReflection.java | 27 ++++++++++++++ .../render/events/ReplayRenderEvent.java | 24 ++++++++++++ .../render/rendering/VideoRenderer.java | 7 ++++ 5 files changed, 97 insertions(+) create mode 100644 src/main/java/com/replaymod/compat/optifine/DisableFastRender.java create mode 100644 src/main/java/com/replaymod/compat/optifine/OptifineReflection.java create mode 100644 src/main/java/com/replaymod/render/events/ReplayRenderEvent.java diff --git a/src/main/java/com/replaymod/compat/ReplayModCompat.java b/src/main/java/com/replaymod/compat/ReplayModCompat.java index 0587764f..bdfc9289 100644 --- a/src/main/java/com/replaymod/compat/ReplayModCompat.java +++ b/src/main/java/com/replaymod/compat/ReplayModCompat.java @@ -1,5 +1,6 @@ package com.replaymod.compat; +import com.replaymod.compat.optifine.DisableFastRender; import com.replaymod.compat.shaders.ShaderBeginRender; import com.replaymod.core.ReplayMod; import net.minecraftforge.fml.common.FMLCommonHandler; @@ -18,6 +19,7 @@ public class ReplayModCompat { public void init(FMLInitializationEvent event) { EventBus bus = FMLCommonHandler.instance().bus(); bus.register(new ShaderBeginRender()); + bus.register(new DisableFastRender()); } } diff --git a/src/main/java/com/replaymod/compat/optifine/DisableFastRender.java b/src/main/java/com/replaymod/compat/optifine/DisableFastRender.java new file mode 100644 index 00000000..5dec6a94 --- /dev/null +++ b/src/main/java/com/replaymod/compat/optifine/DisableFastRender.java @@ -0,0 +1,37 @@ +package com.replaymod.compat.optifine; + +import com.replaymod.render.events.ReplayRenderEvent; +import net.minecraft.client.Minecraft; +import net.minecraftforge.fml.client.FMLClientHandler; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; + +public class DisableFastRender { + + private final Minecraft mc = Minecraft.getMinecraft(); + + private boolean wasFastRender = false; + + @SubscribeEvent + public void onRenderBegin(ReplayRenderEvent.Pre event) { + if (!FMLClientHandler.instance().hasOptifine()) return; + + try { + wasFastRender = (boolean) OptifineReflection.gameSettings_ofFastRender.get(mc.gameSettings); + OptifineReflection.gameSettings_ofFastRender.set(mc.gameSettings, false); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + + @SubscribeEvent + public void onRenderEnd(ReplayRenderEvent.Post event){ + if (!FMLClientHandler.instance().hasOptifine()) return; + + try { + OptifineReflection.gameSettings_ofFastRender.set(mc.gameSettings, wasFastRender); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + +} diff --git a/src/main/java/com/replaymod/compat/optifine/OptifineReflection.java b/src/main/java/com/replaymod/compat/optifine/OptifineReflection.java new file mode 100644 index 00000000..49d54e44 --- /dev/null +++ b/src/main/java/com/replaymod/compat/optifine/OptifineReflection.java @@ -0,0 +1,27 @@ +package com.replaymod.compat.optifine; + +import net.minecraft.client.settings.GameSettings; + +import java.lang.reflect.Field; + +public class OptifineReflection { + + // GameSettings.ofFastRender + public static Field gameSettings_ofFastRender; + + static { + try { + // this throws an ignored ClassNotFoundException if Optifine isn't installed + Class.forName("Config"); + + gameSettings_ofFastRender = GameSettings.class.getDeclaredField("ofFastRender"); + gameSettings_ofFastRender.setAccessible(true); + } catch (ClassNotFoundException ignore) { + // no optifine installed + } catch (NoSuchFieldException e) { + // the field wasn't found. Has it been renamed? + e.printStackTrace(); + } + } + +} diff --git a/src/main/java/com/replaymod/render/events/ReplayRenderEvent.java b/src/main/java/com/replaymod/render/events/ReplayRenderEvent.java new file mode 100644 index 00000000..f52ce0bb --- /dev/null +++ b/src/main/java/com/replaymod/render/events/ReplayRenderEvent.java @@ -0,0 +1,24 @@ +package com.replaymod.render.events; + +import com.replaymod.render.rendering.VideoRenderer; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import net.minecraftforge.fml.common.eventhandler.Event; + +@RequiredArgsConstructor +public abstract class ReplayRenderEvent extends Event { + @Getter + private final VideoRenderer videoRenderer; + + public static class Pre extends ReplayRenderEvent { + public Pre(VideoRenderer videoRenderer) { + super(videoRenderer); + } + } + + public static class Post extends ReplayRenderEvent { + public Post(VideoRenderer videoRenderer) { + super(videoRenderer); + } + } +} diff --git a/src/main/java/com/replaymod/render/rendering/VideoRenderer.java b/src/main/java/com/replaymod/render/rendering/VideoRenderer.java index 640eb8c0..8bc415cc 100644 --- a/src/main/java/com/replaymod/render/rendering/VideoRenderer.java +++ b/src/main/java/com/replaymod/render/rendering/VideoRenderer.java @@ -7,6 +7,7 @@ import com.replaymod.render.RenderSettings; import com.replaymod.render.ReplayModRender; import com.replaymod.render.VideoWriter; import com.replaymod.render.capturer.RenderInfo; +import com.replaymod.render.events.ReplayRenderEvent; import com.replaymod.render.frame.RGBFrame; import com.replaymod.render.gui.GuiRenderingDone; import com.replaymod.render.gui.GuiVideoRenderer; @@ -22,6 +23,7 @@ import net.minecraft.client.gui.ScaledResolution; import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.shader.Framebuffer; import net.minecraft.util.Timer; +import net.minecraftforge.fml.common.FMLCommonHandler; import org.lwjgl.input.Mouse; import org.lwjgl.opengl.Display; import org.lwjgl.util.Dimension; @@ -86,6 +88,8 @@ public class VideoRenderer implements RenderInfo { * @return {@code true} if rendering was successful, {@code false} if the user aborted rendering (or the window was closed) */ public boolean renderVideo() { + FMLCommonHandler.instance().bus().post(new ReplayRenderEvent.Pre(this)); + setup(); // Because this might take some time to prepare we'll render the GUI at least once to not confuse the user @@ -129,6 +133,9 @@ public class VideoRenderer implements RenderInfo { } finish(); + + FMLCommonHandler.instance().bus().post(new ReplayRenderEvent.Post(this)); + return !cancelled; }