From f959648090ff27471f930b172760b7475d08e51f Mon Sep 17 00:00:00 2001 From: Ranzu <66495944+Ranzuu@users.noreply.github.com> Date: Fri, 23 Oct 2026 12:00:11 +0200 Subject: [PATCH] feat: add built-in menu blur based on Blur by tterrag --- README.MD | 4 +- .../angelica/blur/LICENSE-Blur.md | 25 +++ .../gtnewhorizons/angelica/blur/MenuBlur.java | 195 ++++++++++++++++++ .../angelica/config/AngelicaConfig.java | 26 +++ .../gtnewhorizons/angelica/mixins/Mixins.java | 8 + .../angelica/mixins/TargetedMod.java | 1 + .../client/gui/SodiumGameOptionPages.java | 23 +++ .../control/ControlValueFormatter.java | 4 + .../resources/assets/angelica/lang/en_US.lang | 6 + .../blur/MixinEntityRenderer_MenuBlur.java | 19 ++ .../blur/MixinGuiScreen_MenuBlur.java | 22 ++ 11 files changed, 332 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/gtnewhorizons/angelica/blur/LICENSE-Blur.md create mode 100644 src/main/java/com/gtnewhorizons/angelica/blur/MenuBlur.java create mode 100644 src/mixin/java/com/gtnewhorizons/angelica/mixins/early/angelica/blur/MixinEntityRenderer_MenuBlur.java create mode 100644 src/mixin/java/com/gtnewhorizons/angelica/mixins/early/angelica/blur/MixinGuiScreen_MenuBlur.java diff --git a/README.MD b/README.MD index da8bfd0ea..d88d1882e 100644 --- a/README.MD +++ b/README.MD @@ -17,7 +17,7 @@ * HUD caching * Custom fonts and text effects * MCPatcher - connected textures, custom item textures, custom colors, random mobs, better skies -* Bundled NotFine, zoom, FPS reducer +* Bundled NotFine, zoom, FPS reducer, menu blur ## Status * OpenGL + Celeritas terrain - Default @@ -129,5 +129,7 @@ Targets GL 3.3+ core profile * FFP vertex shader generation inspired by ffvertex_prog.c (Copyright 2007 VMware, Inc.) * FFP fragment shader generation inspired by ff_fragment_shader.c (Copyright 2007, 2009 VMware, Inc. / 2010-2011 Intel Corporation) * Fog parameter optimization inspired by st_nir_lower_fog.c (Copyright 2023 Google LLC) and prog_statevars.c (Copyright 1999-2007 Brian Paul) +* Blur + * tterrag for [Blur](https://github.com/tterrag1098/Blur) - Menu blur based on Blur under the MIT license * RGSS Terrain Texture Filtering * Indiesoft for [defold-sharp-sprite](https://github.com/indiesoftby/defold-sharp-sprite), used as the reference implementation under the MIT license diff --git a/src/main/java/com/gtnewhorizons/angelica/blur/LICENSE-Blur.md b/src/main/java/com/gtnewhorizons/angelica/blur/LICENSE-Blur.md new file mode 100644 index 000000000..e32d97925 --- /dev/null +++ b/src/main/java/com/gtnewhorizons/angelica/blur/LICENSE-Blur.md @@ -0,0 +1,25 @@ +The menu blur in this package is based on [Blur](https://github.com/tterrag1098/Blur), used under the following license: + +``` +MIT License + +Copyright (c) 2017 tterrag + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +``` diff --git a/src/main/java/com/gtnewhorizons/angelica/blur/MenuBlur.java b/src/main/java/com/gtnewhorizons/angelica/blur/MenuBlur.java new file mode 100644 index 000000000..6b6226c25 --- /dev/null +++ b/src/main/java/com/gtnewhorizons/angelica/blur/MenuBlur.java @@ -0,0 +1,195 @@ +package com.gtnewhorizons.angelica.blur; + +import com.gtnewhorizons.angelica.client.rendering.GlUniformFloat2v; +import com.gtnewhorizons.angelica.config.AngelicaConfig; +import com.gtnewhorizons.angelica.glsm.GLStateManager; +import com.gtnewhorizons.angelica.glsm.StateSet; +import com.gtnewhorizons.angelica.render.PanoramaRenderer; +import net.minecraft.client.Minecraft; +import net.minecraft.client.shader.Framebuffer; +import org.apache.commons.lang3.ArrayUtils; +import org.embeddedt.embeddium.impl.gl.shader.GlProgram; +import org.embeddedt.embeddium.impl.gl.shader.ShaderBindingContext; +import org.embeddedt.embeddium.impl.gl.shader.uniform.GlUniformFloat; +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL12; +import org.lwjgl.opengl.GL13; +import org.lwjgl.opengl.GL30; + +import java.nio.ByteBuffer; + +/** + * Blurs the world behind open GUIs and fades in a configurable background gradient. + * Based on Blur by tterrag (https://github.com/tterrag1098/Blur) under the MIT license, see LICENSE-Blur.md. + * Reimplemented on top of Angelica's own blur shader instead of a vanilla post-processing shader. + */ +public class MenuBlur { + + private static final Minecraft mc = Minecraft.getMinecraft(); + + private static GlProgram blurProgram; + private static StateSet allState; + private static int emptyVao; + // The blur runs on half resolution copies of the screen, which is much cheaper and looks the same once blurred + private static int horizontalFbo, horizontalTexture, verticalFbo, verticalTexture; + private static int sourceWidth, sourceHeight, halfWidth, halfHeight; + + private static boolean blurring; + private static long fadeStartMillis; + + /** Called right after the world has been drawn, before the HUD and the open GUI. */ + public static void renderBlur() { + final boolean shouldBlur = shouldBlur(); + if (shouldBlur && !blurring) { + fadeStartMillis = System.currentTimeMillis(); + } + blurring = shouldBlur; + if (!blurring) return; + + // The radius grows with the fade, so the blur gets stronger over the first moments + final float radius = (float) Math.floor(AngelicaConfig.menuBlurRadius * getProgress()); + if (radius < 1.0F) return; + + final Framebuffer mainFramebuffer = mc.getFramebuffer(); + if (blurProgram == null) init(); + + final int previousProgram = GLStateManager.getActiveProgram(); + final int previousVao = GLStateManager.glGetInteger(GL30.GL_VERTEX_ARRAY_BINDING); + final int previousFilter = mainFramebuffer.framebufferFilter; + final int stateDepth = GLStateManager.pushState(allState); + try { + ensureBlurTargets(mainFramebuffer.framebufferWidth, mainFramebuffer.framebufferHeight); + + GLStateManager.disableBlend(); + GLStateManager.disableDepthTest(); + GLStateManager.glDepthMask(false); + GLStateManager.glColorMask(true, true, true, true); + GLStateManager.disableCull(); + GLStateManager.disableScissorTest(); + GLStateManager.glActiveTexture(GL13.GL_TEXTURE0); + + blurProgram.bind(); + GLStateManager.glBindVertexArray(emptyVao); + final BlurUniforms uniforms = blurProgram.getInterface(); + // Each half resolution pixel covers two screen pixels, so half the radius gives the same strength + uniforms.radius.setFloat(radius * 0.5F); + + // Horizontal pass, shrinking the screen to half size. Linear filtering makes every + // half size pixel average the four screen pixels it covers instead of picking one. + mainFramebuffer.setFramebufferFilter(GL11.GL_LINEAR); + GLStateManager.glBindFramebuffer(GL30.GL_FRAMEBUFFER, horizontalFbo); + GLStateManager.glViewport(0, 0, halfWidth, halfHeight); + GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, mainFramebuffer.framebufferTexture); + uniforms.direction.set(1.0F / halfWidth, 0.0F); + GLStateManager.glDrawArrays(GL11.GL_TRIANGLES, 0, 3); + + // Vertical pass, still at half size + GLStateManager.glBindFramebuffer(GL30.GL_FRAMEBUFFER, verticalFbo); + GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, horizontalTexture); + uniforms.direction.set(0.0F, 1.0F / halfHeight); + GLStateManager.glDrawArrays(GL11.GL_TRIANGLES, 0, 3); + + // Stretch the result back over the screen. A radius of 0 makes the blur shader a plain copy. + mainFramebuffer.bindFramebuffer(true); + GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, verticalTexture); + uniforms.radius.setFloat(0.0F); + GLStateManager.glDrawArrays(GL11.GL_TRIANGLES, 0, 3); + } finally { + mainFramebuffer.setFramebufferFilter(previousFilter); + GLStateManager.glBindVertexArray(previousVao); + GLStateManager.glUseProgram(previousProgram); + GLStateManager.popStateTo(stateDepth); + mainFramebuffer.bindFramebuffer(true); + } + } + + /** Replaces one of the two vanilla GUI background gradient colors while the blur is showing. */ + public static int getBackgroundColor(int vanillaColor, String configuredColor) { + if (!blurring) return vanillaColor; + + final int color; + try { + color = Integer.parseUnsignedInt(configuredColor, 16); + } catch (NumberFormatException e) { + return vanillaColor; + } + + final float progress = getProgress(); + final int alpha = (int) ((color >>> 24) * progress); + final int red = (int) ((color >> 16 & 0xFF) * progress); + final int green = (int) ((color >> 8 & 0xFF) * progress); + final int blue = (int) ((color & 0xFF) * progress); + return alpha << 24 | red << 16 | green << 8 | blue; + } + + private static boolean shouldBlur() { + return AngelicaConfig.enableMenuBlur + && mc.theWorld != null + && mc.currentScreen != null + && !ArrayUtils.contains(AngelicaConfig.menuBlurExcludedGuis, mc.currentScreen.getClass().getName()); + } + + private static float getProgress() { + if (AngelicaConfig.menuBlurFadeTime <= 0) return 1.0F; + return Math.min((System.currentTimeMillis() - fadeStartMillis) / (float) AngelicaConfig.menuBlurFadeTime, 1.0F); + } + + private static void init() { + blurProgram = PanoramaRenderer.loadProgram("angelica:menu_blur", "angelica:panorama_blur", "angelica:panorama_blur", BlurUniforms::new); + allState = StateSet.forMask(GL11.GL_ALL_ATTRIB_BITS); + emptyVao = GLStateManager.glGenVertexArrays(); + } + + private static void ensureBlurTargets(int width, int height) { + if (horizontalFbo != 0 && width == sourceWidth && height == sourceHeight) return; + + if (horizontalFbo != 0) { + GLStateManager.glDeleteFramebuffers(horizontalFbo); + GLStateManager.glDeleteFramebuffers(verticalFbo); + GLStateManager.glDeleteTextures(horizontalTexture); + GLStateManager.glDeleteTextures(verticalTexture); + } + sourceWidth = width; + sourceHeight = height; + halfWidth = Math.max((width + 1) / 2, 1); + halfHeight = Math.max((height + 1) / 2, 1); + + horizontalTexture = createTexture(halfWidth, halfHeight); + horizontalFbo = createFramebuffer(horizontalTexture); + verticalTexture = createTexture(halfWidth, halfHeight); + verticalFbo = createFramebuffer(verticalTexture); + } + + private static int createTexture(int width, int height) { + final int texture = GLStateManager.glGenTextures(); + GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, texture); + GLStateManager.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA8, width, height, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, (ByteBuffer) null); + GLStateManager.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR); + GLStateManager.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR); + GLStateManager.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE); + GLStateManager.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE); + GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, 0); + return texture; + } + + private static int createFramebuffer(int colorTexture) { + final int fbo = GLStateManager.glGenFramebuffers(); + GLStateManager.glBindFramebuffer(GL30.GL_FRAMEBUFFER, fbo); + GLStateManager.glFramebufferTexture2D(GL30.GL_FRAMEBUFFER, GL30.GL_COLOR_ATTACHMENT0, GL11.GL_TEXTURE_2D, colorTexture, 0); + final int status = GLStateManager.glCheckFramebufferStatus(GL30.GL_FRAMEBUFFER); + if (status != GL30.GL_FRAMEBUFFER_COMPLETE) { + throw new RuntimeException("Menu blur FBO incomplete: 0x" + Integer.toHexString(status)); + } + return fbo; + } + + private static class BlurUniforms { + final GlUniformFloat2v direction; + final GlUniformFloat radius; + + BlurUniforms(ShaderBindingContext ctx) { + direction = ctx.bindUniform("u_Direction", GlUniformFloat2v::new); + radius = ctx.bindUniform("u_Radius", GlUniformFloat::new); + } + } +} diff --git a/src/main/java/com/gtnewhorizons/angelica/config/AngelicaConfig.java b/src/main/java/com/gtnewhorizons/angelica/config/AngelicaConfig.java index 3a218a97a..f3ac8db20 100644 --- a/src/main/java/com/gtnewhorizons/angelica/config/AngelicaConfig.java +++ b/src/main/java/com/gtnewhorizons/angelica/config/AngelicaConfig.java @@ -276,6 +276,32 @@ public class AngelicaConfig { @Config.RequiresMcRestart public static boolean enableZoom; + @Config.Comment("Blur the world behind open GUIs.") + @Config.DefaultBoolean(false) + public static boolean enableMenuBlur; + + @Config.Comment("How strong the menu blur is, in pixels.") + @Config.DefaultInt(12) + @Config.RangeInt(min = 1, max = 100) + public static int menuBlurRadius; + + @Config.Comment("How long the menu blur takes to fade in, in milliseconds.") + @Config.DefaultInt(200) + @Config.RangeInt(min = 0, max = 2000) + public static int menuBlurFadeTime; + + @Config.Comment("GUI classes that never get the menu blur.") + @Config.DefaultStringList({"net.minecraft.client.gui.GuiChat"}) + public static String[] menuBlurExcludedGuis; + + @Config.Comment("Top color of the GUI background gradient while the menu blur is showing, as ARGB hex.") + @Config.DefaultString("75000000") + public static String menuBlurGradientTopColor; + + @Config.Comment("Bottom color of the GUI background gradient while the menu blur is showing, as ARGB hex.") + @Config.DefaultString("75000000") + public static String menuBlurGradientBottomColor; + @Config.Comment("Optimizes in-world item rendering") @Config.DefaultBoolean(true) @Config.RequiresMcRestart diff --git a/src/main/java/com/gtnewhorizons/angelica/mixins/Mixins.java b/src/main/java/com/gtnewhorizons/angelica/mixins/Mixins.java index 17e03c4fc..64e931086 100644 --- a/src/main/java/com/gtnewhorizons/angelica/mixins/Mixins.java +++ b/src/main/java/com/gtnewhorizons/angelica/mixins/Mixins.java @@ -617,6 +617,14 @@ public enum Mixins implements IMixins { "angelica.zoom.MixinMouseFilter" )), + ANGELICA_MENU_BLUR(new MixinBuilder("Blur the world behind open GUIs") + .setPhase(Phase.EARLY) + .addExcludedMod(TargetedMod.BLUR) + .addClientMixins( + "angelica.blur.MixinEntityRenderer_MenuBlur", + "angelica.blur.MixinGuiScreen_MenuBlur" + )), + ANGELICA_FPS_REDUCER(new MixinBuilder("Reduce frame rate and volume while unfocused, minimized, or idle") .setPhase(Phase.EARLY) .addClientMixins( diff --git a/src/main/java/com/gtnewhorizons/angelica/mixins/TargetedMod.java b/src/main/java/com/gtnewhorizons/angelica/mixins/TargetedMod.java index 9d220d568..74eab157e 100644 --- a/src/main/java/com/gtnewhorizons/angelica/mixins/TargetedMod.java +++ b/src/main/java/com/gtnewhorizons/angelica/mixins/TargetedMod.java @@ -9,6 +9,7 @@ public enum TargetedMod implements ITargetMod { ARCHAICFIX("org.embeddedt.archaicfix.ArchaicCore", "archaicfix"), BACKHAND("xonin.backhand.coremod.BackhandLoadingPlugin", "backhand"), + BLUR("com.tterrag.blur.BlurPlugin", "blur"), CAMPFIRE_BACKPORT(null, "campfirebackport"), CHISEL(null, "chisel"), COFHCORE( "cofh.asm.LoadingPlugin", "CoFHCore"), diff --git a/src/main/java/me/jellysquid/mods/sodium/client/gui/SodiumGameOptionPages.java b/src/main/java/me/jellysquid/mods/sodium/client/gui/SodiumGameOptionPages.java index 8862ef1f0..b587f1249 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/gui/SodiumGameOptionPages.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/gui/SodiumGameOptionPages.java @@ -847,6 +847,29 @@ public class SodiumGameOptionPages { .build()); } + groups.add(OptionGroup.createBuilder() + .add(OptionImpl.createBuilder(boolean.class, angelicaOpts) + .setName(I18n.format("options.angelica.menuBlur")) + .setTooltip(I18n.format("options.angelica.menuBlur.tooltip")) + .setControl(TickBoxControl::new) + .setImpact(OptionImpact.LOW) + .setBinding((opts, value) -> AngelicaConfig.enableMenuBlur = value, opts -> AngelicaConfig.enableMenuBlur) + .build()) + .add(OptionImpl.createBuilder(int.class, angelicaOpts) + .setName(I18n.format("options.angelica.menuBlurRadius")) + .setTooltip(I18n.format("options.angelica.menuBlurRadius.tooltip")) + .setControl(option -> new SliderControl(option, 1, 100, 1, ControlValueFormatter.number())) + .setImpact(OptionImpact.LOW) + .setBinding((opts, value) -> AngelicaConfig.menuBlurRadius = value, opts -> AngelicaConfig.menuBlurRadius) + .build()) + .add(OptionImpl.createBuilder(int.class, angelicaOpts) + .setName(I18n.format("options.angelica.menuBlurFadeTime")) + .setTooltip(I18n.format("options.angelica.menuBlurFadeTime.tooltip")) + .setControl(option -> new SliderControl(option, 0, 2000, 50, ControlValueFormatter.milliseconds())) + .setBinding((opts, value) -> AngelicaConfig.menuBlurFadeTime = value, opts -> AngelicaConfig.menuBlurFadeTime) + .build()) + .build()); + return new OptionPage(I18n.format("sodium.options.pages.appearance"), ImmutableList.copyOf(groups)); } diff --git a/src/main/java/me/jellysquid/mods/sodium/client/gui/options/control/ControlValueFormatter.java b/src/main/java/me/jellysquid/mods/sodium/client/gui/options/control/ControlValueFormatter.java index 5481c8611..ba49fd7a1 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/gui/options/control/ControlValueFormatter.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/gui/options/control/ControlValueFormatter.java @@ -43,6 +43,10 @@ public interface ControlValueFormatter { return (v) -> v + "s"; } + static ControlValueFormatter milliseconds() { + return (v) -> v + "ms"; + } + static ControlValueFormatter quantity(String name) { return (v) -> I18n.format(name, v); } diff --git a/src/main/resources/assets/angelica/lang/en_US.lang b/src/main/resources/assets/angelica/lang/en_US.lang index 211f62a4b..6d1263318 100644 --- a/src/main/resources/assets/angelica/lang/en_US.lang +++ b/src/main/resources/assets/angelica/lang/en_US.lang @@ -391,6 +391,12 @@ options.angelica.disablef3=Disable F3 Additions options.angelica.disablef3.tooltip=Disables Angelica's additions to the F3 debug screen. options.angelica.verbosef3=Verbose F3 options.angelica.verbosef3.tooltip=Shows developer counters (fixed-function shaders, streaming, TESR batching, GPU transfer) on the F3 screen. Toggle in game with F3+V. +options.angelica.menuBlur=Menu Blur +options.angelica.menuBlur.tooltip=Blurs the world behind open menus like the inventory or the pause menu. Chat is never blurred. Excluded menus and background colors can be changed in the Angelica config. +options.angelica.menuBlurRadius=Menu Blur Strength +options.angelica.menuBlurRadius.tooltip=How strong the menu blur is. Higher values blur more. +options.angelica.menuBlurFadeTime=Menu Blur Fade Time +options.angelica.menuBlurFadeTime.tooltip=How long the menu blur takes to fade in after a menu opens. 0 shows it instantly. angelica.debug.verbose.on=Verbose F3: shown angelica.debug.verbose.off=Verbose F3: hidden options.angelica.texteffects.rgb_colors=RGB Colors diff --git a/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/angelica/blur/MixinEntityRenderer_MenuBlur.java b/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/angelica/blur/MixinEntityRenderer_MenuBlur.java new file mode 100644 index 000000000..fd6b8d25c --- /dev/null +++ b/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/angelica/blur/MixinEntityRenderer_MenuBlur.java @@ -0,0 +1,19 @@ +package com.gtnewhorizons.angelica.mixins.early.angelica.blur; + +import com.gtnewhorizons.angelica.blur.MenuBlur; +import net.minecraft.client.renderer.EntityRenderer; +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(EntityRenderer.class) +public class MixinEntityRenderer_MenuBlur { + + @Inject( + method = "updateCameraAndRender", + at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/EntityRenderer;renderWorld(FJ)V", shift = At.Shift.AFTER)) + private void angelica$blurWorldBehindGui(float partialTicks, CallbackInfo ci) { + MenuBlur.renderBlur(); + } +} diff --git a/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/angelica/blur/MixinGuiScreen_MenuBlur.java b/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/angelica/blur/MixinGuiScreen_MenuBlur.java new file mode 100644 index 000000000..72ad8457f --- /dev/null +++ b/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/angelica/blur/MixinGuiScreen_MenuBlur.java @@ -0,0 +1,22 @@ +package com.gtnewhorizons.angelica.mixins.early.angelica.blur; + +import com.gtnewhorizons.angelica.blur.MenuBlur; +import com.gtnewhorizons.angelica.config.AngelicaConfig; +import net.minecraft.client.gui.GuiScreen; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.Constant; +import org.spongepowered.asm.mixin.injection.ModifyConstant; + +@Mixin(GuiScreen.class) +public class MixinGuiScreen_MenuBlur { + + @ModifyConstant(method = "drawWorldBackground", constant = @Constant(intValue = 0xC0101010)) + private int angelica$blurGradientTop(int original) { + return MenuBlur.getBackgroundColor(original, AngelicaConfig.menuBlurGradientTopColor); + } + + @ModifyConstant(method = "drawWorldBackground", constant = @Constant(intValue = 0xD0101010)) + private int angelica$blurGradientBottom(int original) { + return MenuBlur.getBackgroundColor(original, AngelicaConfig.menuBlurGradientBottomColor); + } +}