4 Commits

Author SHA1 Message Date
Martin Prokoph
fa6fd82e4d fix: move gradient z-coordinate further back 2025-04-23 10:18:55 +02:00
Martin Prokoph
528958fa8c fix: improve gradient handling 2025-04-19 09:58:54 +02:00
Martin Prokoph
552f1e619e feat: improve config screen with comments 2025-03-29 19:30:38 +01:00
Martin Prokoph
c9c630ac11 fix: less invasive gradient injection
- Should fix various compatibility issues with other mods
2025-03-29 18:45:19 +01:00
6 changed files with 71 additions and 40 deletions

View File

@@ -23,20 +23,19 @@ public class Blur {
public static boolean doFade = false; public static boolean doFade = false;
static float lastDelta; public static void onRender() {
public static void onRender(DrawContext context, int width, int height, MinecraftClient client, float delta) {
if (!BlurInfo.doTest && BlurInfo.screenChanged) { // After the tests for blur and background color have been completed if (!BlurInfo.doTest && BlurInfo.screenChanged) { // After the tests for blur and background color have been completed
Blur.onScreenChange(); Blur.onScreenChange();
BlurInfo.screenChanged = false; BlurInfo.screenChanged = false;
} }
BlurInfo.doTest = false; // Set the test state to completed, as tests will happen in the same tick.
}
public static void renderFadeout(DrawContext context, int width, int height, MinecraftClient client) {
if (BlurInfo.start >= 0 && !BlurInfo.screenHasBlur && BlurInfo.prevScreenHasBlur) { // Fade out in non-blurred screens if (BlurInfo.start >= 0 && !BlurInfo.screenHasBlur && BlurInfo.prevScreenHasBlur) { // Fade out in non-blurred screens
client.gameRenderer.renderBlur(); client.gameRenderer.renderBlur();
if (BlurInfo.prevScreenHasBackground && BlurConfig.useGradient && lastDelta != delta) Blur.renderRotatedGradient(context, width, height); if (BlurInfo.prevScreenHasBackground && BlurConfig.useGradient) Blur.renderRotatedGradient(context, width, height);
lastDelta = delta;
} }
BlurInfo.doTest = false; // Set the test state to completed, as tests will happen in the same tick.
} }
public static void onScreenChange() { public static void onScreenChange() {
@@ -79,7 +78,10 @@ public class Blur {
int b = (col.getRGB() >> 8) & 0xFF; int b = (col.getRGB() >> 8) & 0xFF;
int g = col.getRGB() & 0xFF; int g = col.getRGB() & 0xFF;
float prog = progress; float prog = progress;
a *= prog; r *= prog; g *= prog; b *= prog; a = (int) (prog * a);
r = (int) (prog * r);
g = (int) (prog * g);
b = (int) (prog * b);
return a << 24 | r << 16 | b << 8 | g; return a << 24 | r << 16 | b << 8 | g;
} }
public static int getRotation() { public static int getRotation() {
@@ -90,11 +92,12 @@ public class Blur {
float diagonal = Math.sqrt((float) width*width + height*height); float diagonal = Math.sqrt((float) width*width + height*height);
int smallestDimension = Math.min(width, height); int smallestDimension = Math.min(width, height);
context.getMatrices().push();
Matrix4f posMatrix = context.getMatrices().peek().getPositionMatrix(); Matrix4f posMatrix = context.getMatrices().peek().getPositionMatrix();
posMatrix.rotationZ(Math.toRadians(getRotation())); posMatrix.rotationZ(Math.toRadians(getRotation()));
posMatrix.setTranslation(width / 2f, height / 2f, 0); // Make the gradient's center the pivot point posMatrix.setTranslation(width / 2f, height / 2f, -1000); // Make the gradient's center the pivot point
posMatrix.scale(diagonal / smallestDimension); // Scales the gradient to the maximum diagonal value needed posMatrix.scale(diagonal / smallestDimension); // Scales the gradient to the maximum diagonal value needed
context.fillGradient(-width / 2, -height / 2, width / 2, height / 2, Blur.getBackgroundColor(false), Blur.getBackgroundColor(true)); // Actually draw the gradient context.fillGradient(-width / 2, -height / 2, width / 2, height / 2, Blur.getBackgroundColor(false), Blur.getBackgroundColor(true)); // Actually draw the gradient
posMatrix.rotationZ(0); context.getMatrices().pop();
} }
} }

View File

@@ -15,6 +15,8 @@ public class BlurConfig extends MidnightConfig {
public static final String SCREENS = "screens"; public static final String SCREENS = "screens";
@Entry @Hidden public static int configVersion = 2; @Entry @Hidden public static int configVersion = 2;
@Comment(category = SCREENS, centered = true)
public static Comment _general;
@Entry(category = SCREENS) @Entry(category = SCREENS)
public static boolean blurContainers = true; public static boolean blurContainers = true;
@Entry(category = SCREENS) @Entry(category = SCREENS)
@@ -22,14 +24,21 @@ public class BlurConfig extends MidnightConfig {
@Condition(requiredOption = "blurTitleScreen", visibleButLocked = true) @Condition(requiredOption = "blurTitleScreen", visibleButLocked = true)
@Entry(category = SCREENS) @Entry(category = SCREENS)
public static boolean darkenTitleScreen = false; public static boolean darkenTitleScreen = false;
@Entry(category = ANIMATIONS, min = 0, max = 2000, isSlider = true) @Comment(category = SCREENS, centered = true)
public static int fadeTimeMillis = 300; public static Comment _advanced;
@Entry(category = ANIMATIONS, min = 0, max = 2000, isSlider = true) @Entry(category = SCREENS) // Screens where Blur+ should not apply transition effects (mostly dynamically blurred screens)
public static int fadeOutTimeMillis = 300; public static List<String> excludedScreens = Lists.newArrayList("net.irisshaders.iris.gui.screen.ShaderPackScreen");
@Entry(category = ANIMATIONS) @Entry(category = SCREENS) // Screens where the vanilla blur effect should be force enabled
public static BlurConfig.Easing animationCurve = Easing.FLAT; public static List<String> forceEnabledScreens = Lists.newArrayList("dev.emi.emi.screen.RecipeScreen");
@Entry(category = SCREENS) // Screens where the vanilla blur effect should be force disabled
public static List<String> forceDisabledScreens = Lists.newArrayList();
@Comment(category = STYLE, centered = true)
public static Comment _blur;
@Entry(category = STYLE, isSlider = true, min = 0, max = 20) @Entry(category = STYLE, isSlider = true, min = 0, max = 20)
public static int radius = 5; public static int radius = 5;
@Comment(category = STYLE, centered = true)
public static Comment _gradient;
@Entry(category = STYLE) @Entry(category = STYLE)
public static boolean useGradient = true; public static boolean useGradient = true;
@Condition(requiredOption = "useGradient", visibleButLocked = true) @Condition(requiredOption = "useGradient", visibleButLocked = true)
@@ -49,12 +58,15 @@ public class BlurConfig extends MidnightConfig {
public static int gradientRotation = 0; public static int gradientRotation = 0;
@Entry(category = STYLE) @Entry(category = STYLE)
public static boolean rainbowMode = false; public static boolean rainbowMode = false;
@Entry(category = SCREENS) // Screens where Blur+ should not apply transition effects (mostly dynamically blurred screens)
public static List<String> excludedScreens = Lists.newArrayList("net.irisshaders.iris.gui.screen.ShaderPackScreen"); @Comment(category = ANIMATIONS, centered = true)
@Entry(category = SCREENS) // Screens where the vanilla blur effect should be force enabled public static Comment _animations;
public static List<String> forceEnabledScreens = Lists.newArrayList("dev.emi.emi.screen.RecipeScreen"); @Entry(category = ANIMATIONS, min = 0, max = 2000, isSlider = true)
@Entry(category = SCREENS) // Screens where the vanilla blur effect should be force disabled public static int fadeTimeMillis = 300;
public static List<String> forceDisabledScreens = Lists.newArrayList(); @Entry(category = ANIMATIONS, min = 0, max = 2000, isSlider = true)
public static int fadeOutTimeMillis = 300;
@Entry(category = ANIMATIONS)
public static BlurConfig.Easing animationCurve = Easing.FLAT;
@Override @Override
public void writeChanges(String modid) { public void writeChanges(String modid) {

View File

@@ -24,6 +24,6 @@ public class MixinHandledScreen extends Screen {
} }
@Inject(at = @At("HEAD"), method = "render") @Inject(at = @At("HEAD"), method = "render")
public void blur$processScreenChange(DrawContext context, int mouseX, int mouseY, float delta, CallbackInfo ci) { public void blur$processScreenChange(DrawContext context, int mouseX, int mouseY, float delta, CallbackInfo ci) {
if (PlatformFunctions.getPlatformName().equals("neoforge")) Blur.onRender(context, width, height, this.client, delta); if (PlatformFunctions.getPlatformName().equals("neoforge")) Blur.onRender();
} }
} }

View File

@@ -1,13 +1,17 @@
package eu.midnightdust.blur.mixin; package eu.midnightdust.blur.mixin;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import eu.midnightdust.blur.BlurInfo; import eu.midnightdust.blur.BlurInfo;
import eu.midnightdust.blur.config.BlurConfig; import eu.midnightdust.blur.config.BlurConfig;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.DrawContext;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
@@ -20,18 +24,16 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
public abstract class MixinScreen { public abstract class MixinScreen {
@Shadow @Final protected Text title; @Shadow @Final protected Text title;
@Shadow protected MinecraftClient client; @Shadow protected MinecraftClient client;
@Shadow public abstract void renderInGameBackground(DrawContext context);
@Shadow public int width; @Shadow public int width;
@Shadow public int height; @Shadow public int height;
@Shadow protected abstract void applyBlur();
@Inject(at = @At("HEAD"), method = "render") @Inject(at = @At("HEAD"), method = "render")
public void blur$processScreenChange(DrawContext context, int mouseX, int mouseY, float delta, CallbackInfo ci) { public void blur$processScreenChange(DrawContext context, int mouseX, int mouseY, float delta, CallbackInfo ci) {
Blur.onRender(context, width, height, this.client, delta); Blur.onRender();
} Blur.renderFadeout(context, width, height, client);
@Inject(at = @At("HEAD"), method = "renderInGameBackground")
public void blur$getBackgroundEnabled(DrawContext context, CallbackInfo ci) {
BlurInfo.screenHasBackground = true; // Test if the screen has a background
} }
@Inject(at = @At("HEAD"), method = "applyBlur", cancellable = true) @Inject(at = @At("HEAD"), method = "applyBlur", cancellable = true)
public void blur$getBlurEnabled(CallbackInfo ci) { public void blur$getBlurEnabled(CallbackInfo ci) {
if (BlurConfig.forceDisabledScreens.contains(this.getClass().getCanonicalName())) { if (BlurConfig.forceDisabledScreens.contains(this.getClass().getCanonicalName())) {
@@ -41,20 +43,23 @@ public abstract class MixinScreen {
BlurInfo.screenHasBlur = true; // Test if the screen has blur BlurInfo.screenHasBlur = true; // Test if the screen has blur
} }
@Inject(at = @At("HEAD"), method = "renderDarkening(Lnet/minecraft/client/gui/DrawContext;IIII)V", cancellable = true) @WrapOperation(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/Screen;renderBackgroundTexture(Lnet/minecraft/client/gui/DrawContext;Lnet/minecraft/util/Identifier;IIFFII)V"), method = "renderDarkening(Lnet/minecraft/client/gui/DrawContext;IIII)V")
public void blur$applyGradient(DrawContext context, int x, int y, int width, int height, CallbackInfo ci) { private void blur$applyGradient(DrawContext context, Identifier texture, int x, int y, float u, float v, int width, int height, Operation<Void> original) {
if (BlurConfig.useGradient) { // Replaces the background texture with a gradient if (BlurConfig.useGradient) {
renderInGameBackground(context); blur$renderGradient(context); // Replaces the background texture with a gradient
ci.cancel(); } else original.call(context, texture, x, y, u, v, width, height);
}
} }
@Inject(at = @At("HEAD"), method = "renderInGameBackground", cancellable = true) @WrapOperation(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;fillGradient(IIIIII)V"), method = "renderInGameBackground")
public void blur$rotatedGradient(DrawContext context, CallbackInfo ci) { public void blur$rotatedGradient(DrawContext context, int startX, int startY, int endX, int endY, int colorStart, int colorEnd, Operation<Void> original) {
blur$renderGradient(context);
}
@Unique
private void blur$renderGradient(DrawContext context) {
BlurInfo.screenHasBackground = true; // Test if the screen has a background
if (BlurConfig.forceEnabledScreens.contains(this.getClass().getCanonicalName())) if (BlurConfig.forceEnabledScreens.contains(this.getClass().getCanonicalName()))
((ScreenAccessor)this).forceApplyBlur(); this.applyBlur();
Blur.renderRotatedGradient(context, width, height); // Replaces the default gradient with our rotated one Blur.renderRotatedGradient(context, width, height); // Replaces the default gradient with our rotated one
ci.cancel();
} }
} }

View File

@@ -1,6 +1,7 @@
{ {
"blur.midnightconfig.title": "Blur+ Konfiguration", "blur.midnightconfig.title": "Blur+ Konfiguration",
"blur.midnightconfig.category.animations": "Animationen", "blur.midnightconfig.category.animations": "Animationen",
"blur.midnightconfig.category.screens": "Bildschirme",
"blur.midnightconfig.category.style": "Stil", "blur.midnightconfig.category.style": "Stil",
"blur.midnightconfig.blurContainers": "Unschärfe in Containern", "blur.midnightconfig.blurContainers": "Unschärfe in Containern",
"blur.midnightconfig.blurTitleScreen": "Unschärfe im Titelbildschirm", "blur.midnightconfig.blurTitleScreen": "Unschärfe im Titelbildschirm",
@@ -26,5 +27,10 @@
"blur.midnightconfig.gradientStartAlpha": "Farbverlauf-Anfangstransparenz", "blur.midnightconfig.gradientStartAlpha": "Farbverlauf-Anfangstransparenz",
"blur.midnightconfig.gradientEndAlpha": "Farbverlauf-Endstransparenz", "blur.midnightconfig.gradientEndAlpha": "Farbverlauf-Endstransparenz",
"blur.midnightconfig.gradientRotation": "Farbverlauf-Rotation", "blur.midnightconfig.gradientRotation": "Farbverlauf-Rotation",
"blur.midnightconfig.excludedScreens": "Ausgeschlossene Bildschirme" "blur.midnightconfig.excludedScreens": "Ausgeschlossene Bildschirme",
"blur.midnightconfig._general": "§7⛏ Generell",
"blur.midnightconfig._advanced": "§7⚒ Fortgeschritten",
"blur.midnightconfig._blur": "§7▒ Unschärfe",
"blur.midnightconfig._gradient": "§7\uD83D\uDFE2 Farbverlauf",
"blur.midnightconfig._animations": "§7\uD83D\uDCFD Animationen"
} }

View File

@@ -33,5 +33,10 @@
"blur.midnightconfig.forceEnabledScreens": "Force-enabled Screens", "blur.midnightconfig.forceEnabledScreens": "Force-enabled Screens",
"blur.midnightconfig.forceEnabledScreens.tooltip": "Screens where the vanilla blur effect should be force-enabled\nMight not work 100% of the time", "blur.midnightconfig.forceEnabledScreens.tooltip": "Screens where the vanilla blur effect should be force-enabled\nMight not work 100% of the time",
"blur.midnightconfig.forceDisabledScreens": "Force-disabled Screens", "blur.midnightconfig.forceDisabledScreens": "Force-disabled Screens",
"blur.midnightconfig.forceDisabledScreens.tooltip": "Screens where the vanilla blur effect should be force-disabled" "blur.midnightconfig.forceDisabledScreens.tooltip": "Screens where the vanilla blur effect should be force-disabled",
"blur.midnightconfig._general": "§7⛏ General",
"blur.midnightconfig._advanced": "§7⚒ Advanced",
"blur.midnightconfig._blur": "§7▒ Blur",
"blur.midnightconfig._gradient": "§7\uD83D\uDFE2 Gradient",
"blur.midnightconfig._animations": "§7\uD83D\uDCFD Animations"
} }