diff --git a/build.gradle b/build.gradle index d92e484..62fc0cc 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'fabric-loom' version '1.7.+' + id 'fabric-loom' version '1.10.+' id 'io.github.juuxel.loom-quiltflower' version '1.8.0' id 'maven-publish' } @@ -15,6 +15,10 @@ dependencies { modImplementation fabricApi.module("fabric-resource-loader-v0", project.fabric_version) } +loom { + accessWidenerPath = file("src/main/resources/shaderreload.accesswidener") +} + processResources { inputs.property "version", project.version diff --git a/gradle.properties b/gradle.properties index 848c5b6..7133ef6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,12 +2,12 @@ org.gradle.jvmargs=-Xmx1G # Fabric Properties # https://modmuss50.me/fabric.html -minecraft_version=1.21 -yarn_mappings=1.21+build.7 -loader_version=0.15.11 -fabric_version=0.100.4+1.21 +minecraft_version=1.21.5 +yarn_mappings=1.21.5+build.1 +loader_version=0.16.14 +fabric_version=0.121.0+1.21.5 # Mod Properties -mod_version=1.12 +mod_version=1.13 maven_group=suso archives_base_name=shader-reload \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 0d8ab51..f57a814 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1 +1 @@ -distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip diff --git a/src/main/java/suso/shaderreload/ShaderReload.java b/src/main/java/suso/shaderreload/ShaderReload.java index 3631d62..da9665f 100644 --- a/src/main/java/suso/shaderreload/ShaderReload.java +++ b/src/main/java/suso/shaderreload/ShaderReload.java @@ -1,24 +1,22 @@ package suso.shaderreload; -import com.google.gson.JsonSyntaxException; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gl.Framebuffer; -import net.minecraft.client.gl.PostEffectProcessor; -import net.minecraft.client.gl.ShaderProgram; -import net.minecraft.client.render.VertexFormat; -import net.minecraft.client.texture.TextureManager; +import net.minecraft.client.gl.ShaderLoader; import net.minecraft.resource.*; import net.minecraft.text.Text; import net.minecraft.util.*; +import net.minecraft.util.profiler.DummyProfiler; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.jetbrains.annotations.Nullable; import org.lwjgl.glfw.GLFW; import suso.shaderreload.mixin.KeyboardInvoker; +import suso.shaderreload.mixin.ShaderLoaderAccessor; -import java.io.IOException; +import java.util.Arrays; import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; @@ -30,10 +28,9 @@ public class ShaderReload implements ClientModInitializer { public static final int GLFW_KEY = GLFW.GLFW_KEY_R; public static final Logger LOGGER = LogManager.getLogger("Shader Reload"); - private static final StopException STOP = new StopException(); private static boolean reloading = false; - private static boolean stopReloading = false; - private static ResourceReloader shaderLoader; + public static boolean isReloadingBuiltin = false; + private static @Nullable ShaderLoader.Definitions vanillaOnlyDefinitions = null; @Override public void onInitializeClient() { @@ -44,8 +41,8 @@ public static void reloadShaders() { if (reloading) return; var client = MinecraftClient.getInstance(); reloading = true; - stopReloading = false; - SimpleResourceReload.start(client.getResourceManager(), List.of(shaderLoader, client.worldRenderer), + isReloadingBuiltin = false; + SimpleResourceReload.start(client.getResourceManager(), List.of(client.getShaderLoader(), client.worldRenderer), Util.getMainWorkerExecutor(), client, CompletableFuture.completedFuture(Unit.INSTANCE), false) .whenComplete() .whenComplete((result, throwable) -> { @@ -57,79 +54,51 @@ public static void reloadShaders() { if (throwable instanceof CompletionException ex && ex.getCause() != null) { throwable = ex.getCause(); } - if (!(throwable instanceof StopException)) { - ((KeyboardInvoker) client.keyboard).invokeDebugError("debug.reload_shaders.unknown_error"); - throwable.printStackTrace(); - } + ((KeyboardInvoker) client.keyboard).invokeDebugError("debug.reload_shaders.unknown_error"); + throwable.printStackTrace(); }); } - // Print a shader exception in chat. - private static void printShaderException(Exception exception, boolean builtin) { + public static void printShaderLogError(String errorMessage, Object... arguments) { var client = MinecraftClient.getInstance(); - var throwable = (Throwable) exception; - while (!(throwable instanceof InvalidHierarchicalFileException)) { - var cause = throwable.getCause(); - if (cause != null) throwable = cause; - else { - var translationKey = "debug.reload_shaders.unknown_error" + (builtin ? ".builtin" : ""); - ((KeyboardInvoker) client.keyboard).invokeDebugError(translationKey); - throwable.printStackTrace(); - return; - } - } - var translationKey = "debug.reload_shaders.error" + (builtin ? ".builtin" : ""); + var translationKey = "debug.reload_shaders.error" + (isReloadingBuiltin ? ".builtin" : ""); ((KeyboardInvoker) client.keyboard).invokeDebugError(translationKey); - client.inGameHud.getChatHud().addMessage(Text.literal(throwable.getMessage()).formatted(Formatting.GRAY)); - } - - // Try loading a core shader; if it fails, stop shader reloading or try loading a built-in core shader. - public static ShaderProgram onLoadShaders$new(ResourceFactory factory, String name, VertexFormat format) throws IOException { - try { - return new ShaderProgram(factory, name, format); - } catch (IOException e) { - printShaderException(e, false); - if (reloading) throw STOP; - } - try { - var defaultPack = MinecraftClient.getInstance().getDefaultResourcePack(); - return new ShaderProgram(defaultPack.getFactory(), name, format); - } catch (IOException e) { - printShaderException(e, true); - throw e; - } + var logText = Text.translatable( + errorMessage.replace("{}", "%s"), + Arrays.stream(arguments) + .map(String::valueOf) + .map(ShaderReload::removeEx) + .toArray() + ).formatted(Formatting.GRAY); + client.inGameHud.getChatHud().addMessage(logText); } - // Try loading a shader effect; if it fails, request stopping and try loading a built-in shader effect. - @SuppressWarnings("resource") - public static PostEffectProcessor onLoadShader$new(TextureManager textureManager, ResourceFactory resourceFactory, - Framebuffer framebuffer, Identifier location) throws IOException { - try { - return new PostEffectProcessor(textureManager, resourceFactory, framebuffer, location); - } catch (IOException | JsonSyntaxException e) { - printShaderException(e, false); - stopReloading = true; - } - try { - var defaultPack = MinecraftClient.getInstance().getDefaultResourcePack(); - resourceFactory = new LifecycledResourceManagerImpl(CLIENT_RESOURCES, List.of(defaultPack)); - return new PostEffectProcessor(textureManager, resourceFactory, framebuffer, location); - } catch (IOException | JsonSyntaxException e) { - printShaderException(e, true); - throw e; + public static String removeEx(String msg) { + msg = msg.substring(msg.indexOf(": ") + 2); + while(true) { + final var colonIndex = msg.indexOf(": "); + if(colonIndex == -1) + break; + if(msg.substring(0, colonIndex).contains(" ")) { + // Definitely not an error name, so it shouldn't be removed + break; + } + msg = msg.substring(colonIndex + 2); } + return msg; } - // Stop shader reloading if it's requested. - public static void onLoadShader$end() { - if (reloading && stopReloading) throw STOP; + public static ResourceManager getDefaultResourceManager() { + var defaultPack = MinecraftClient.getInstance().getDefaultResourcePack(); + return new LifecycledResourceManagerImpl(CLIENT_RESOURCES, List.of(defaultPack)); } - public static void setShaderLoader(ResourceReloader value) { - shaderLoader = value; - } + public static ShaderLoader.Definitions getVanillaOnlyDefinitions() { + if(vanillaOnlyDefinitions != null) + return vanillaOnlyDefinitions; - private static class StopException extends RuntimeException { - private StopException() {} + vanillaOnlyDefinitions = ((ShaderLoaderAccessor)MinecraftClient.getInstance().getShaderLoader()) + .callPrepare(getDefaultResourceManager(), DummyProfiler.INSTANCE); + return vanillaOnlyDefinitions; } } diff --git a/src/main/java/suso/shaderreload/mixin/GameRendererMixin.java b/src/main/java/suso/shaderreload/mixin/GameRendererMixin.java deleted file mode 100644 index 0084f0e..0000000 --- a/src/main/java/suso/shaderreload/mixin/GameRendererMixin.java +++ /dev/null @@ -1,57 +0,0 @@ -package suso.shaderreload.mixin; - -import net.minecraft.client.gl.Framebuffer; -import net.minecraft.client.gl.PostEffectProcessor; -import net.minecraft.client.gl.ShaderProgram; -import net.minecraft.client.render.GameRenderer; -import net.minecraft.client.render.VertexFormat; -import net.minecraft.client.texture.TextureManager; -import net.minecraft.resource.ResourceFactory; -import net.minecraft.resource.ResourceReloader; -import net.minecraft.util.Identifier; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.Redirect; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import suso.shaderreload.ShaderReload; - -import java.io.IOException; - -@Mixin(GameRenderer.class) -public abstract class GameRendererMixin { - @Shadow private boolean postProcessorEnabled; - - @Redirect(method = "loadPrograms", at = @At(value = "NEW", target = "Lnet/minecraft/client/gl/ShaderProgram;")) - ShaderProgram onLoadPrograms$new(ResourceFactory factory, String name, VertexFormat format) throws IOException { - return ShaderReload.onLoadShaders$new(factory, name, format); - } - - @Redirect(method = "loadPostProcessor(Lnet/minecraft/util/Identifier;)V", at = @At(value = "NEW", - target = "Lnet/minecraft/client/gl/PostEffectProcessor;")) - PostEffectProcessor onLoadPostProcessor$new(TextureManager textureManager, ResourceFactory resourceFactory, - Framebuffer framebuffer, Identifier location) throws IOException { - return ShaderReload.onLoadShader$new(textureManager, resourceFactory, framebuffer, location); - } - - @Inject(method = "loadPostProcessor(Lnet/minecraft/util/Identifier;)V", at = @At(value = "INVOKE", - target = "Lorg/slf4j/Logger;warn(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V", - remap = false), cancellable = true) - void onLoadPostProcessor$error(Identifier id, CallbackInfo ci) { - postProcessorEnabled = false; - ShaderReload.onLoadShader$end(); - ci.cancel(); - } - - @Inject(method = "loadPostProcessor(Lnet/minecraft/util/Identifier;)V", at = @At("TAIL")) - void onLoadPostProcessor$success(Identifier id, CallbackInfo ci) { - ShaderReload.onLoadShader$end(); - } - - @Inject(method = "createProgramReloader", at = @At("RETURN")) - void onCreateProgramReloader(CallbackInfoReturnable cir) { - ShaderReload.setShaderLoader(cir.getReturnValue()); - } -} diff --git a/src/main/java/suso/shaderreload/mixin/GlBackendMixin.java b/src/main/java/suso/shaderreload/mixin/GlBackendMixin.java new file mode 100644 index 0000000..3dbea97 --- /dev/null +++ b/src/main/java/suso/shaderreload/mixin/GlBackendMixin.java @@ -0,0 +1,84 @@ +package suso.shaderreload.mixin; + +import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import com.mojang.blaze3d.pipeline.RenderPipeline; +import com.mojang.blaze3d.shaders.ShaderType; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gl.CompiledShaderPipeline; +import net.minecraft.client.gl.GlBackend; +import net.minecraft.client.gl.ShaderLoader; +import net.minecraft.util.Identifier; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyArg; +import suso.shaderreload.ShaderReload; + +import java.util.Map; +import java.util.function.BiFunction; +import java.util.function.Function; + +@Mixin(GlBackend.class) +public class GlBackendMixin { + @ModifyArg( + method = { + "compileShader(Lnet/minecraft/client/gl/GlBackend$ShaderKey;Ljava/util/function/BiFunction;)Lnet/minecraft/client/gl/CompiledShader;", + "compileRenderPipeline" + }, + at = @At( + value = "INVOKE", + target = "Lorg/slf4j/Logger;error(Ljava/lang/String;[Ljava/lang/Object;)V", + remap = false + ) + ) + private String shader_reload$printPipelineShaderErrors(String logMessage, Object... args) { + ShaderReload.printShaderLogError(logMessage, args); + return logMessage; + } + + @ModifyArg( + method = { + "compileShader(Lnet/minecraft/client/gl/GlBackend$ShaderKey;Ljava/util/function/BiFunction;)Lnet/minecraft/client/gl/CompiledShader;", + "compileRenderPipeline" + }, + at = @At( + value = "INVOKE", + target = "Lorg/slf4j/Logger;error(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V", + remap = false + ) + ) + private String shader_reload$printPipelineShaderErrors(String logMessage, Object arg1, Object arg2) { + ShaderReload.printShaderLogError(logMessage, arg1, arg2); + return logMessage; + } + + @WrapMethod(method = "compileRenderPipeline") + private CompiledShaderPipeline shader_reload$retryFailedShadersWithDefault(RenderPipeline pipeline, BiFunction sourceRetriever, Operation op) { + ShaderReload.isReloadingBuiltin = false; + var compiled = op.call(pipeline, sourceRetriever); + if(compiled.isValid()) + return compiled; + + ShaderReload.isReloadingBuiltin = true; + var vanillyOnlyDefinitions = ShaderReload.getVanillaOnlyDefinitions(); + return op.call( + pipeline, + (BiFunction)(id, type) -> + vanillyOnlyDefinitions.shaderSources().get(new ShaderLoader.ShaderSourceKey(id, type)) + ); + } + + @WrapOperation( + method = "compileShader(Lnet/minecraft/util/Identifier;Lcom/mojang/blaze3d/shaders/ShaderType;Lnet/minecraft/client/gl/Defines;Ljava/util/function/BiFunction;)Lnet/minecraft/client/gl/CompiledShader;", + at = @At( + value = "INVOKE", + target = "Ljava/util/Map;computeIfAbsent(Ljava/lang/Object;Ljava/util/function/Function;)Ljava/lang/Object;" + ) + ) + private Object shader_reload$skipCacheWhenReloadingBuiltin(Map instance, K key, Function mapping_function, Operation op) { + if(ShaderReload.isReloadingBuiltin) + return mapping_function.apply(key); + return op.call(instance, key, mapping_function); + } +} diff --git a/src/main/java/suso/shaderreload/mixin/GlProgramManagerMixin.java b/src/main/java/suso/shaderreload/mixin/GlProgramManagerMixin.java deleted file mode 100644 index 36839e5..0000000 --- a/src/main/java/suso/shaderreload/mixin/GlProgramManagerMixin.java +++ /dev/null @@ -1,20 +0,0 @@ -package suso.shaderreload.mixin; - -import com.mojang.blaze3d.platform.GlStateManager; -import net.minecraft.client.gl.GlProgramManager; -import net.minecraft.client.gl.ShaderProgramSetupView; -import net.minecraft.util.InvalidHierarchicalFileException; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(GlProgramManager.class) -public class GlProgramManagerMixin { - @Inject(method = "linkProgram", at = @At(value = "INVOKE", - target = "Lorg/slf4j/Logger;warn(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V", - remap = false)) - private static void onLinkProgram$error(ShaderProgramSetupView shader, CallbackInfo ci) throws InvalidHierarchicalFileException { - throw new InvalidHierarchicalFileException(GlStateManager.glGetProgramInfoLog(shader.getGlRef(), 32768)); - } -} diff --git a/src/main/java/suso/shaderreload/mixin/KeyboardMixin.java b/src/main/java/suso/shaderreload/mixin/KeyboardMixin.java index 3c1410b..fbf69d8 100644 --- a/src/main/java/suso/shaderreload/mixin/KeyboardMixin.java +++ b/src/main/java/suso/shaderreload/mixin/KeyboardMixin.java @@ -10,6 +10,7 @@ import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Slice; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import suso.shaderreload.ShaderReload; @@ -20,7 +21,11 @@ public abstract class KeyboardMixin { @Inject(method = "processF3", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/hud/ChatHud;addMessage(Lnet/minecraft/text/Text;)V", - ordinal = 10, shift = At.Shift.AFTER)) + ordinal = 0, + shift = At.Shift.AFTER), + slice = @Slice( + from = @At(value = "CONSTANT", + args = "stringValue=debug.reload_resourcepacks.help"))) private void onProcessF3$addHelp(int key, CallbackInfoReturnable cir) { client.inGameHud.getChatHud().addMessage(Text.translatable("debug.reload_shaders.help")); } @@ -33,8 +38,9 @@ void onProcessF3(int key, CallbackInfoReturnable cir) { } } + // processF3 isn't called when a screen is open, but shader reloading is still supposed to work in that case @Inject(method = "onKey", at = @At(value = "INVOKE", - target = "Lnet/minecraft/client/gui/screen/Screen;wrapScreenError(Ljava/lang/Runnable;Ljava/lang/String;Ljava/lang/String;)V"), + target = "Lnet/minecraft/client/gui/screen/Screen;keyPressed(III)Z"), cancellable = true) void onOnKey(long window, int key, int scancode, int action, int modifiers, CallbackInfo ci) { if (!InputUtil.isKeyPressed(window, GLFW.GLFW_KEY_F3) || key != ShaderReload.GLFW_KEY) return; @@ -43,13 +49,4 @@ void onOnKey(long window, int key, int scancode, int action, int modifiers, Call } ci.cancel(); } - - @Inject(method = "onChar", at = @At(value = "INVOKE", - target = "Lnet/minecraft/client/gui/screen/Screen;wrapScreenError(Ljava/lang/Runnable;Ljava/lang/String;Ljava/lang/String;)V", - ordinal = 0), cancellable = true) - void onOnChar(long window, int codePoint, int modifiers, CallbackInfo ci) { - if (InputUtil.isKeyPressed(window, GLFW.GLFW_KEY_F3) && InputUtil.isKeyPressed(window, ShaderReload.GLFW_KEY)) { - ci.cancel(); - } - } } diff --git a/src/main/java/suso/shaderreload/mixin/ShaderLoaderAccessor.java b/src/main/java/suso/shaderreload/mixin/ShaderLoaderAccessor.java new file mode 100644 index 0000000..91ff677 --- /dev/null +++ b/src/main/java/suso/shaderreload/mixin/ShaderLoaderAccessor.java @@ -0,0 +1,13 @@ +package suso.shaderreload.mixin; + +import net.minecraft.client.gl.ShaderLoader; +import net.minecraft.resource.ResourceManager; +import net.minecraft.util.profiler.Profiler; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(ShaderLoader.class) +public interface ShaderLoaderAccessor { + @Invoker + ShaderLoader.Definitions callPrepare(ResourceManager resourceManager, Profiler profiler); +} diff --git a/src/main/java/suso/shaderreload/mixin/ShaderLoaderGlImportProcessorMixin.java b/src/main/java/suso/shaderreload/mixin/ShaderLoaderGlImportProcessorMixin.java new file mode 100644 index 0000000..64a9876 --- /dev/null +++ b/src/main/java/suso/shaderreload/mixin/ShaderLoaderGlImportProcessorMixin.java @@ -0,0 +1,22 @@ +package suso.shaderreload.mixin; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyArg; +import suso.shaderreload.ShaderReload; + +@Mixin(targets = "net.minecraft.client.gl.ShaderLoader$1") +public class ShaderLoaderGlImportProcessorMixin { + @ModifyArg( + method = "loadImport", + at = @At( + value = "INVOKE", + target = "Lorg/slf4j/Logger;error(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V", + remap = false + ) + ) + private String shader_reload$printGLSLImportErrors(String format, Object arg1, Object arg2) { + ShaderReload.printShaderLogError(format, arg1, arg2); + return format; + } +} diff --git a/src/main/java/suso/shaderreload/mixin/ShaderLoaderMixin.java b/src/main/java/suso/shaderreload/mixin/ShaderLoaderMixin.java new file mode 100644 index 0000000..c945b8a --- /dev/null +++ b/src/main/java/suso/shaderreload/mixin/ShaderLoaderMixin.java @@ -0,0 +1,36 @@ +package suso.shaderreload.mixin; + +import net.minecraft.client.gl.ShaderLoader; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyArg; +import suso.shaderreload.ShaderReload; + +@Mixin(ShaderLoader.class) +public class ShaderLoaderMixin { + @ModifyArg( + method = "loadPostEffect(Lnet/minecraft/util/Identifier;Ljava/util/Set;)Lnet/minecraft/client/gl/PostEffectProcessor;", + at = @At( + value = "INVOKE", + target = "Lorg/slf4j/Logger;error(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V", + remap = false + ) + ) + private String shader_reload$printPostEffectShaderErrors(String format, Object arg1, Object arg2) { + ShaderReload.printShaderLogError(format + ": {}", arg1, arg2); + return format; + } + + @ModifyArg( + method = "loadPostEffect(Lnet/minecraft/util/Identifier;Lnet/minecraft/resource/Resource;Lcom/google/common/collect/ImmutableMap$Builder;)V", + at = @At( + value = "INVOKE", + target = "Lorg/slf4j/Logger;error(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V", + remap = false + ) + ) + private static String shader_reload$printPostEffectChainErrors(String format, Object arg1, Object arg2) { + ShaderReload.printShaderLogError(format + ": {}", arg1, arg2); + return format; + } +} diff --git a/src/main/java/suso/shaderreload/mixin/WorldRendererMixin.java b/src/main/java/suso/shaderreload/mixin/WorldRendererMixin.java deleted file mode 100644 index 4166c93..0000000 --- a/src/main/java/suso/shaderreload/mixin/WorldRendererMixin.java +++ /dev/null @@ -1,70 +0,0 @@ -package suso.shaderreload.mixin; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gl.Framebuffer; -import net.minecraft.client.gl.PostEffectProcessor; -import net.minecraft.client.option.GraphicsMode; -import net.minecraft.client.render.WorldRenderer; -import net.minecraft.client.texture.TextureManager; -import net.minecraft.resource.ResourceFactory; -import net.minecraft.resource.ResourceManager; -import net.minecraft.util.Identifier; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.Redirect; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import suso.shaderreload.ShaderReload; - -import java.io.IOException; - -@Mixin(WorldRenderer.class) -public abstract class WorldRendererMixin { - @Shadow @Final private MinecraftClient client; - @Shadow private PostEffectProcessor entityOutlinePostProcessor; - @Shadow private Framebuffer entityOutlinesFramebuffer; - - @Redirect(method = "loadTransparencyPostProcessor", at = @At(value = "NEW", target = "Lnet/minecraft/client/gl/PostEffectProcessor;")) - PostEffectProcessor onLoadTransparencyPostProcessor$new(TextureManager textureManager, ResourceFactory resourceFactory, - Framebuffer framebuffer, Identifier location) throws IOException { - return ShaderReload.onLoadShader$new(textureManager, resourceFactory, framebuffer, location); - } - - @Inject(method = "loadTransparencyPostProcessor", at = @At(value = "INVOKE", - target = "Lnet/minecraft/client/render/WorldRenderer$ProgramInitException;(Ljava/lang/String;Ljava/lang/Throwable;)V"), - cancellable = true) - void onLoadTransparencyShader$error(CallbackInfo ci) { - client.options.getGraphicsMode().setValue(GraphicsMode.FANCY); - client.options.write(); - ShaderReload.onLoadShader$end(); - ci.cancel(); - } - - @Inject(method = "loadTransparencyPostProcessor", at = @At("TAIL")) - void onLoadTransparencyPostProcessor$success(CallbackInfo ci) { - ShaderReload.onLoadShader$end(); - } - - @Redirect(method = "loadEntityOutlinePostProcessor", at = @At(value = "NEW", target = "Lnet/minecraft/client/gl/PostEffectProcessor;")) - PostEffectProcessor onLoadEntityOutlinePostProcessor$new(TextureManager textureManager, ResourceFactory resourceFactory, - Framebuffer framebuffer, Identifier location) throws IOException { - return ShaderReload.onLoadShader$new(textureManager, resourceFactory, framebuffer, location); - } - - @Inject(method = "loadEntityOutlinePostProcessor", at = @At(value = "INVOKE", - target = "Lorg/slf4j/Logger;warn(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V", - remap = false), cancellable = true) - void onLoadEntityOutlinePostProcessor$error(CallbackInfo ci) { - entityOutlinePostProcessor = null; - entityOutlinesFramebuffer = null; - ShaderReload.onLoadShader$end(); - ci.cancel(); - } - - @Inject(method = "loadEntityOutlinePostProcessor", at = @At("TAIL")) - void onLoadEntityOutlinePostProcessor$success(CallbackInfo ci) { - ShaderReload.onLoadShader$end(); - } -} diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 367ce89..c8af027 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -21,6 +21,7 @@ }, "license": "MIT", "icon": "assets/shaderreload/icon.png", + "accesswidener": "shaderreload.accesswidener", "environment": "client", "entrypoints": { "client": [ diff --git a/src/main/resources/shaderreload.accesswidener b/src/main/resources/shaderreload.accesswidener new file mode 100644 index 0000000..d5be4a3 --- /dev/null +++ b/src/main/resources/shaderreload.accesswidener @@ -0,0 +1,3 @@ +accessWidener v2 named + +accessible method net/minecraft/client/gl/ShaderLoader$ShaderSourceKey (Lnet/minecraft/util/Identifier;Lcom/mojang/blaze3d/shaders/ShaderType;)V \ No newline at end of file diff --git a/src/main/resources/shaderreload.mixins.json b/src/main/resources/shaderreload.mixins.json index 2428554..72935d4 100644 --- a/src/main/resources/shaderreload.mixins.json +++ b/src/main/resources/shaderreload.mixins.json @@ -4,13 +4,16 @@ "package": "suso.shaderreload.mixin", "compatibilityLevel": "JAVA_21", "client": [ - "GameRendererMixin", + "GlBackendMixin", "KeyboardInvoker", "KeyboardMixin", - "GlProgramManagerMixin", - "WorldRendererMixin" + "ShaderLoaderAccessor", + "ShaderLoaderMixin" ], "injectors": { "defaultRequire": 1 - } + }, + "mixins": [ + "ShaderLoaderGlImportProcessorMixin" + ] }