Merge pull request 'Add GUI scale and glass on every version' (#40) from glass-blur into master
Reviewed-on: #40
This commit was merged in pull request #40.
This commit is contained in:
+1
-1
Submodule common updated: ef0ead6bf8...7d0bfd26c9
@@ -0,0 +1,377 @@
|
||||
package org.saturnclient.impl.ui;
|
||||
|
||||
// Glass: a copy of the game behind the screen, blurred, drawn through each panel's rounded rectangle
|
||||
// texture as a mask. There's a copy for each blur strength in use (menus and widgets have their own),
|
||||
// blurred with vanilla's blur at that radius, so it holds the world or panorama without the screen's
|
||||
// own animated background blur.
|
||||
//
|
||||
// The GUI rewrites split this into three implementations:
|
||||
// - 1.21.6+: the GUI is drawn after the screen builds it, so the copy is taken from the main
|
||||
// framebuffer while the screen builds its GUI, and glass is a GUI element with its own pipeline
|
||||
// (shaders/core/glass.fsh). The blur is vanilla's effect rebuilt with the radius set.
|
||||
// - 1.21.5: the screen draws straight into the framebuffer, blurring it first, so the game is saved
|
||||
// before the blur (saveBackground). Glass is a render layer with its own pipeline
|
||||
// (shaders/core/glass_pre_1_21_6.fsh), and the blur takes the radius as it runs.
|
||||
// - 1.21.4: as 1.21.5, with GL framebuffers copied by blitting, and a shader program
|
||||
// (shaders/core/glass.json) instead of a pipeline.
|
||||
//? if >=1.21.6 {
|
||||
import java.io.Reader;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.mojang.blaze3d.pipeline.RenderPipeline;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.textures.FilterMode;
|
||||
import com.mojang.blaze3d.textures.GpuTextureView;
|
||||
import com.mojang.serialization.JsonOps;
|
||||
|
||||
import org.saturnclient.config.Config;
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
|
||||
import net.minecraft.client.gl.Framebuffer;
|
||||
import net.minecraft.client.gl.PostEffectPipeline;
|
||||
import net.minecraft.client.gl.PostEffectProcessor;
|
||||
import net.minecraft.client.gl.RenderPipelines;
|
||||
import net.minecraft.client.gl.SimpleFramebuffer;
|
||||
import net.minecraft.client.render.DefaultFramebufferSet;
|
||||
import net.minecraft.client.render.ProjectionMatrix2;
|
||||
import net.minecraft.client.texture.AbstractTexture;
|
||||
import net.minecraft.client.texture.TextureSetup;
|
||||
import net.minecraft.client.util.Pool;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public final class GlassRenderer {
|
||||
public static final RenderPipeline PIPELINE = RenderPipeline.builder(RenderPipelines.POSITION_TEX_COLOR_SNIPPET)
|
||||
.withLocation(Identifier.of("saturnclient", "pipeline/glass"))
|
||||
.withFragmentShader(Identifier.of("saturnclient", "core/glass"))
|
||||
.withSampler("Sampler1")
|
||||
.build();
|
||||
|
||||
private static final Identifier BLUR = Identifier.ofVanilla("post_effect/blur.json");
|
||||
private static final ProjectionMatrix2 PROJECTION = new ProjectionMatrix2("saturn glass", 0.1f, 1000f, false);
|
||||
// For the blurs' intermediate targets, freed once unused for a few frames
|
||||
private static final Pool POOL = new Pool(3);
|
||||
|
||||
// By blur strength. A blur that failed to load is kept as null, so it isn't retried every frame.
|
||||
private static final Map<Integer, PostEffectProcessor> BLURS = new HashMap<>();
|
||||
private static final Map<Integer, SimpleFramebuffer> BACKDROPS = new HashMap<>();
|
||||
|
||||
private GlassRenderer() {
|
||||
}
|
||||
|
||||
// Copies the main framebuffer and blurs the copy by blur. Call once a frame for each blur, while
|
||||
// the screen builds its GUI, before drawing glass with it.
|
||||
public static void captureBackdrop(int blur) {
|
||||
Framebuffer main = SaturnClient.client.getFramebuffer();
|
||||
int width = main.textureWidth;
|
||||
int height = main.textureHeight;
|
||||
|
||||
SimpleFramebuffer backdrop = BACKDROPS.get(blur);
|
||||
if (backdrop == null) {
|
||||
backdrop = new SimpleFramebuffer("Saturn glass " + blur, width, height, false);
|
||||
BACKDROPS.put(blur, backdrop);
|
||||
} else if (backdrop.textureWidth != width || backdrop.textureHeight != height) {
|
||||
backdrop.resize(width, height);
|
||||
}
|
||||
//? if <1.21.11
|
||||
//backdrop.getColorAttachment().setTextureFilter(FilterMode.LINEAR, false);
|
||||
|
||||
RenderSystem.getDevice().createCommandEncoder().copyTextureToTexture(
|
||||
main.getColorAttachment(), backdrop.getColorAttachment(), 0, 0, 0, 0, 0, width, height);
|
||||
|
||||
PostEffectProcessor processor = getBlur(blur);
|
||||
if (processor != null) {
|
||||
processor.render(backdrop, POOL);
|
||||
}
|
||||
POOL.decrementLifespan();
|
||||
release(blur);
|
||||
}
|
||||
|
||||
// The mask, then the copy blurred by blur, as the glass pipeline samples them
|
||||
public static TextureSetup textures(AbstractTexture mask, int blur) {
|
||||
GpuTextureView backdrop = BACKDROPS.get(blur).getColorAttachmentView();
|
||||
//? if >=1.21.11
|
||||
return TextureSetup.of(mask.getGlTextureView(), mask.getSampler(), backdrop, RenderSystem.getSamplerCache().get(FilterMode.LINEAR));
|
||||
//? if <1.21.11
|
||||
//return TextureSetup.of(mask.getGlTextureView(), backdrop);
|
||||
}
|
||||
|
||||
// Frees the copies and blurs of strengths that are no longer set, besides kept
|
||||
private static void release(int kept) {
|
||||
BACKDROPS.entrySet().removeIf(entry -> {
|
||||
boolean unused = entry.getKey() != kept && !isSet(entry.getKey());
|
||||
if (unused) {
|
||||
entry.getValue().delete();
|
||||
}
|
||||
return unused;
|
||||
});
|
||||
BLURS.entrySet().removeIf(entry -> {
|
||||
boolean unused = entry.getKey() != kept && !isSet(entry.getKey());
|
||||
if (unused && entry.getValue() != null) {
|
||||
entry.getValue().close();
|
||||
}
|
||||
return unused;
|
||||
});
|
||||
}
|
||||
|
||||
private static boolean isSet(int blur) {
|
||||
return blur == Config.menuBlur.value || blur == Config.widgetBlur.value;
|
||||
}
|
||||
|
||||
private static PostEffectProcessor getBlur(int blur) {
|
||||
if (!BLURS.containsKey(blur)) {
|
||||
BLURS.put(blur, loadBlur(blur));
|
||||
}
|
||||
return BLURS.get(blur);
|
||||
}
|
||||
|
||||
// Vanilla's blur, with its radius set to blur. Vanilla's own leaves it at 0, which makes the shader
|
||||
// read the menu blur setting (Saturn's animated background blur while a Saturn screen is open).
|
||||
private static PostEffectProcessor loadBlur(int blur) {
|
||||
try (Reader reader = SaturnClient.client.getResourceManager().getResourceOrThrow(BLUR).getReader()) {
|
||||
JsonElement json = JsonParser.parseReader(reader);
|
||||
setRadius(json, blur);
|
||||
|
||||
PostEffectPipeline pipeline = PostEffectPipeline.CODEC.parse(JsonOps.INSTANCE, json).getOrThrow();
|
||||
return PostEffectProcessor.parseEffect(pipeline, SaturnClient.client.getTextureManager(),
|
||||
DefaultFramebufferSet.MAIN_ONLY, Identifier.of("saturnclient", "glass_blur_" + blur), PROJECTION);
|
||||
} catch (Exception e) {
|
||||
SaturnClient.LOGGER.error("Couldn't load the glass blur", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Sets every "Radius" uniform in the effect
|
||||
private static void setRadius(JsonElement json, int radius) {
|
||||
if (json.isJsonArray()) {
|
||||
json.getAsJsonArray().forEach(element -> setRadius(element, radius));
|
||||
} else if (json.isJsonObject()) {
|
||||
JsonObject object = json.getAsJsonObject();
|
||||
if (object.has("name") && object.get("name").getAsString().equals("Radius")) {
|
||||
object.addProperty("value", (float) radius);
|
||||
}
|
||||
object.entrySet().forEach(entry -> setRadius(entry.getValue(), radius));
|
||||
}
|
||||
}
|
||||
}
|
||||
//?} else if >=1.21.5 {
|
||||
/*import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.mojang.blaze3d.pipeline.RenderPipeline;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.textures.FilterMode;
|
||||
|
||||
import org.saturnclient.config.Config;
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
|
||||
import net.minecraft.client.gl.Framebuffer;
|
||||
import net.minecraft.client.gl.PostEffectProcessor;
|
||||
import net.minecraft.client.gl.RenderPipelines;
|
||||
import net.minecraft.client.gl.SimpleFramebuffer;
|
||||
import net.minecraft.client.render.DefaultFramebufferSet;
|
||||
import net.minecraft.client.render.RenderLayer;
|
||||
import net.minecraft.client.render.RenderPhase;
|
||||
import net.minecraft.client.util.Pool;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public final class GlassRenderer {
|
||||
private static final RenderPipeline PIPELINE = RenderPipeline.builder(RenderPipelines.POSITION_TEX_COLOR_SNIPPET)
|
||||
.withLocation(Identifier.of("saturnclient", "pipeline/glass"))
|
||||
.withFragmentShader(Identifier.of("saturnclient", "core/glass_pre_1_21_6"))
|
||||
.withSampler("Sampler1")
|
||||
.build();
|
||||
|
||||
private static final Identifier BLUR = Identifier.ofVanilla("blur");
|
||||
// For the blur's intermediate target, freed once unused for a few frames
|
||||
private static final Pool POOL = new Pool(3);
|
||||
|
||||
private static final Map<Integer, SimpleFramebuffer> BACKDROPS = new HashMap<>();
|
||||
// By mask and blur
|
||||
private static final Map<String, RenderLayer> LAYERS = new HashMap<>();
|
||||
// The game behind the screen before the screen blurs it, which glass is blurred from
|
||||
private static SimpleFramebuffer background;
|
||||
|
||||
private GlassRenderer() {
|
||||
}
|
||||
|
||||
// Saves the main framebuffer for glass. Call each frame before the screen blurs its background.
|
||||
public static void saveBackground() {
|
||||
background = copy(SaturnClient.client.getFramebuffer(), background, "Saturn glass background");
|
||||
}
|
||||
|
||||
// Copies the saved background and blurs the copy by blur. Call once a frame for each blur, before
|
||||
// drawing glass with it.
|
||||
public static void captureBackdrop(int blur) {
|
||||
Framebuffer from = background != null ? background : SaturnClient.client.getFramebuffer();
|
||||
SimpleFramebuffer backdrop = copy(from, BACKDROPS.get(blur), "Saturn glass " + blur);
|
||||
BACKDROPS.put(blur, backdrop);
|
||||
|
||||
PostEffectProcessor processor = SaturnClient.client.getShaderLoader().loadPostEffect(BLUR,
|
||||
DefaultFramebufferSet.MAIN_ONLY);
|
||||
if (processor != null) {
|
||||
processor.render(backdrop, POOL, pass -> pass.setUniform("Radius", (float) blur));
|
||||
}
|
||||
POOL.decrementLifespan();
|
||||
release(blur);
|
||||
}
|
||||
|
||||
// Draws glass through mask with the copy blurred by blur
|
||||
public static RenderLayer getLayer(Identifier mask, int blur) {
|
||||
return LAYERS.computeIfAbsent(mask + " " + blur, key -> RenderLayer.of("saturn_glass", 786432, PIPELINE,
|
||||
RenderLayer.MultiPhaseParameters.builder()
|
||||
.texture(new RenderPhase.TextureBase(() -> {
|
||||
RenderSystem.setShaderTexture(0,
|
||||
SaturnClient.client.getTextureManager().getTexture(mask).getGlTexture());
|
||||
RenderSystem.setShaderTexture(1, BACKDROPS.get(blur).getColorAttachment());
|
||||
}, () -> {
|
||||
}))
|
||||
.build(false)));
|
||||
}
|
||||
|
||||
// Frees the copies of strengths that are no longer set, besides kept
|
||||
private static void release(int kept) {
|
||||
BACKDROPS.entrySet().removeIf(entry -> {
|
||||
boolean unused = entry.getKey() != kept && entry.getKey() != Config.menuBlur.value
|
||||
&& entry.getKey() != Config.widgetBlur.value;
|
||||
if (unused) {
|
||||
entry.getValue().delete();
|
||||
}
|
||||
return unused;
|
||||
});
|
||||
}
|
||||
|
||||
// Copies from into to, made or resized to match
|
||||
private static SimpleFramebuffer copy(Framebuffer from, SimpleFramebuffer to, String name) {
|
||||
int width = from.textureWidth;
|
||||
int height = from.textureHeight;
|
||||
|
||||
if (to == null) {
|
||||
to = new SimpleFramebuffer(name, width, height, false);
|
||||
} else if (to.textureWidth != width || to.textureHeight != height) {
|
||||
to.resize(width, height);
|
||||
}
|
||||
to.getColorAttachment().setTextureFilter(FilterMode.LINEAR, false);
|
||||
|
||||
RenderSystem.getDevice().createCommandEncoder().copyTextureToTexture(
|
||||
from.getColorAttachment(), to.getColorAttachment(), 0, 0, 0, 0, 0, width, height);
|
||||
return to;
|
||||
}
|
||||
}
|
||||
*///?} else {
|
||||
/*import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL30;
|
||||
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
|
||||
import org.saturnclient.config.Config;
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
|
||||
import net.minecraft.client.gl.Defines;
|
||||
import net.minecraft.client.gl.Framebuffer;
|
||||
import net.minecraft.client.gl.PostEffectProcessor;
|
||||
import net.minecraft.client.gl.ShaderProgramKey;
|
||||
import net.minecraft.client.gl.SimpleFramebuffer;
|
||||
import net.minecraft.client.render.DefaultFramebufferSet;
|
||||
import net.minecraft.client.render.RenderLayer;
|
||||
import net.minecraft.client.render.RenderPhase;
|
||||
import net.minecraft.client.render.VertexFormat;
|
||||
import net.minecraft.client.render.VertexFormats;
|
||||
import net.minecraft.client.util.Pool;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public final class GlassRenderer {
|
||||
private static final ShaderProgramKey PROGRAM = new ShaderProgramKey(Identifier.of("saturnclient", "core/glass"),
|
||||
VertexFormats.POSITION_TEXTURE_COLOR, Defines.EMPTY);
|
||||
|
||||
private static final Identifier BLUR = Identifier.ofVanilla("blur");
|
||||
// For the blur's intermediate target, freed once unused for a few frames
|
||||
private static final Pool POOL = new Pool(3);
|
||||
|
||||
private static final Map<Integer, SimpleFramebuffer> BACKDROPS = new HashMap<>();
|
||||
// By mask and blur
|
||||
private static final Map<String, RenderLayer> LAYERS = new HashMap<>();
|
||||
// The game behind the screen before the screen blurs it, which glass is blurred from
|
||||
private static SimpleFramebuffer background;
|
||||
|
||||
private GlassRenderer() {
|
||||
}
|
||||
|
||||
// Saves the main framebuffer for glass. Call each frame before the screen blurs its background.
|
||||
public static void saveBackground() {
|
||||
background = copy(SaturnClient.client.getFramebuffer(), background);
|
||||
}
|
||||
|
||||
// Copies the saved background and blurs the copy by blur. Call once a frame for each blur, before
|
||||
// drawing glass with it.
|
||||
public static void captureBackdrop(int blur) {
|
||||
Framebuffer from = background != null ? background : SaturnClient.client.getFramebuffer();
|
||||
SimpleFramebuffer backdrop = copy(from, BACKDROPS.get(blur));
|
||||
BACKDROPS.put(blur, backdrop);
|
||||
|
||||
PostEffectProcessor processor = SaturnClient.client.getShaderLoader().loadPostEffect(BLUR,
|
||||
DefaultFramebufferSet.MAIN_ONLY);
|
||||
if (processor != null) {
|
||||
processor.setUniforms("Radius", blur);
|
||||
processor.render(backdrop, POOL);
|
||||
}
|
||||
POOL.decrementLifespan();
|
||||
release(blur);
|
||||
SaturnClient.client.getFramebuffer().beginWrite(false);
|
||||
}
|
||||
|
||||
// Draws glass through mask with the copy blurred by blur
|
||||
public static RenderLayer getLayer(Identifier mask, int blur) {
|
||||
return LAYERS.computeIfAbsent(mask + " " + blur, key -> RenderLayer.of("saturn_glass",
|
||||
VertexFormats.POSITION_TEXTURE_COLOR, VertexFormat.DrawMode.QUADS, 786432,
|
||||
RenderLayer.MultiPhaseParameters.builder()
|
||||
.texture(new RenderPhase.TextureBase(() -> {
|
||||
RenderSystem.setShaderTexture(0, mask);
|
||||
RenderSystem.setShaderTexture(1, BACKDROPS.get(blur).getColorAttachment());
|
||||
}, () -> {
|
||||
}))
|
||||
.program(new RenderPhase.ShaderProgram(PROGRAM))
|
||||
.transparency(RenderPhase.TRANSLUCENT_TRANSPARENCY)
|
||||
.build(false)));
|
||||
}
|
||||
|
||||
// Frees the copies of strengths that are no longer set, besides kept
|
||||
private static void release(int kept) {
|
||||
BACKDROPS.entrySet().removeIf(entry -> {
|
||||
boolean unused = entry.getKey() != kept && entry.getKey() != Config.menuBlur.value
|
||||
&& entry.getKey() != Config.widgetBlur.value;
|
||||
if (unused) {
|
||||
entry.getValue().delete();
|
||||
}
|
||||
return unused;
|
||||
});
|
||||
}
|
||||
|
||||
// Copies from into to, made or resized to match
|
||||
private static SimpleFramebuffer copy(Framebuffer from, SimpleFramebuffer to) {
|
||||
int width = from.textureWidth;
|
||||
int height = from.textureHeight;
|
||||
|
||||
if (to == null) {
|
||||
to = new SimpleFramebuffer(width, height, false);
|
||||
} else if (to.textureWidth != width || to.textureHeight != height) {
|
||||
to.resize(width, height);
|
||||
}
|
||||
to.setTexFilter(GL11.GL_LINEAR);
|
||||
|
||||
GlStateManager._glBindFramebuffer(GL30.GL_READ_FRAMEBUFFER, from.fbo);
|
||||
GlStateManager._glBindFramebuffer(GL30.GL_DRAW_FRAMEBUFFER, to.fbo);
|
||||
GlStateManager._glBlitFrameBuffer(0, 0, width, height, 0, 0, width, height, GL11.GL_COLOR_BUFFER_BIT,
|
||||
GL11.GL_NEAREST);
|
||||
SaturnClient.client.getFramebuffer().beginWrite(false);
|
||||
return to;
|
||||
}
|
||||
}
|
||||
*///?}
|
||||
@@ -5,7 +5,9 @@ package org.saturnclient.impl.ui;
|
||||
//? if >=1.21.6 {
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.joml.Matrix3x2f;
|
||||
@@ -40,7 +42,6 @@ import net.minecraft.client.render.entity.state.EntityRenderState;
|
||||
import net.minecraft.client.render.item.KeyedItemRenderState;
|
||||
//?} else
|
||||
//import net.minecraft.client.render.item.ItemRenderState;
|
||||
//? if >=1.21.11
|
||||
import net.minecraft.client.texture.AbstractTexture;
|
||||
import net.minecraft.client.texture.Sprite;
|
||||
import net.minecraft.client.texture.TextureSetup;
|
||||
@@ -61,6 +62,8 @@ public class RenderScopeImpl implements RenderScope {
|
||||
|
||||
private ScissorStack scissorStack;
|
||||
private int opacity = 0xFF << 24;
|
||||
// The glass blurs made for this scope's frame
|
||||
private final Set<Integer> capturedBlurs = new HashSet<>();
|
||||
|
||||
public RenderScopeImpl(DrawContext context) {
|
||||
this(context.getMatrices(), ((DrawContextAccessor) (Object) context).getState());
|
||||
@@ -230,6 +233,25 @@ public class RenderScopeImpl implements RenderScope {
|
||||
this.scissorStack.peekLast()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawGlass(IdentifierRef mask, int x, int y, int width, int height, int blur) {
|
||||
int color = getColor(0xFFFFFFFF);
|
||||
if (mask == null || color >>> 24 == 0)
|
||||
return;
|
||||
|
||||
if (capturedBlurs.add(blur)) {
|
||||
GlassRenderer.captureBackdrop(blur);
|
||||
}
|
||||
|
||||
AbstractTexture maskTexture = SaturnClient.client.getTextureManager().getTexture((Identifier) (Object) mask);
|
||||
this.state.addSimpleElement(new TexturedQuadGuiElementRenderState(
|
||||
GlassRenderer.PIPELINE,
|
||||
GlassRenderer.textures(maskTexture, blur),
|
||||
new Matrix3x2f(this.matrices.stack),
|
||||
x, y, x + width, y + height, 0, 1, 0, 1, color,
|
||||
this.scissorStack.peekLast()));
|
||||
}
|
||||
|
||||
// Scissor management
|
||||
@Override
|
||||
public void enableScissor(int x1, int y1, int x2, int y2) {
|
||||
@@ -368,7 +390,9 @@ public class RenderScopeImpl implements RenderScope {
|
||||
//?} else {
|
||||
/*import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -421,6 +445,8 @@ public class RenderScopeImpl implements RenderScope {
|
||||
public VertexConsumerProvider.Immediate vertexConsumers;
|
||||
private ScissorStack scissorStack = new ScissorStack();
|
||||
private int opacity = 255 << 24;
|
||||
// The glass blurs made for this scope's frame
|
||||
private final Set<Integer> capturedBlurs = new HashSet<>();
|
||||
private final ItemRenderState itemRenderState;
|
||||
|
||||
// ----------------------------
|
||||
@@ -660,6 +686,33 @@ public class RenderScopeImpl implements RenderScope {
|
||||
matrices.pop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawGlass(IdentifierRef mask, int x, int y, int width, int height, int blur) {
|
||||
int color = getColor(0xFFFFFFFF);
|
||||
if (mask == null || color >>> 24 == 0)
|
||||
return;
|
||||
|
||||
if (capturedBlurs.add(blur)) {
|
||||
GlassRenderer.captureBackdrop(blur);
|
||||
}
|
||||
|
||||
// In quarter units, as drawTexturedQuad draws
|
||||
int x1 = x * 4;
|
||||
int x2 = (x + width) * 4;
|
||||
int y1 = y * 4;
|
||||
int y2 = (y + height) * 4;
|
||||
|
||||
matrices.push();
|
||||
matrices.scale(0.25f, 0.25f, 1.0f);
|
||||
Matrix4f matrix4f = matrices.peek().getPositionMatrix();
|
||||
VertexConsumer vertexConsumer = vertexConsumers.getBuffer(GlassRenderer.getLayer((Identifier) (Object) mask, blur));
|
||||
vertexConsumer.vertex(matrix4f, x1, y1, 0).texture(0, 0).color(color);
|
||||
vertexConsumer.vertex(matrix4f, x1, y2, 0).texture(0, 1).color(color);
|
||||
vertexConsumer.vertex(matrix4f, x2, y2, 0).texture(1, 1).color(color);
|
||||
vertexConsumer.vertex(matrix4f, x2, y1, 0).texture(1, 0).color(color);
|
||||
matrices.pop();
|
||||
}
|
||||
|
||||
// ----------------------------
|
||||
// Items
|
||||
// ----------------------------
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.saturnclient.impl.ui;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
|
||||
import org.saturnclient.config.Config;
|
||||
import org.saturnclient.ui.RenderScope;
|
||||
import org.saturnclient.ui.SaturnScreen;
|
||||
import org.saturnclient.ui.SaturnScreen.ScreenProvider;
|
||||
@@ -86,8 +87,10 @@ public class SaturnScreenFabric extends Screen implements ScreenProvider {
|
||||
}
|
||||
long elapsed = Duration.between(screen.start, Instant.now()).toMillis();
|
||||
|
||||
mouseX *= 2;
|
||||
mouseY *= 2;
|
||||
screen.updateScale();
|
||||
|
||||
mouseX = (int) (mouseX / screen.scale);
|
||||
mouseY = (int) (mouseY / screen.scale);
|
||||
|
||||
// From 1.21.6 the background, blur included, is drawn in renderBackground.
|
||||
//? if <1.21.6 {
|
||||
@@ -95,12 +98,18 @@ public class SaturnScreenFabric extends Screen implements ScreenProvider {
|
||||
ROTATING_PANORAMA_RENDERER.render(context, this.width, this.height, screen.backgroundOpacity, delta);
|
||||
}
|
||||
|
||||
PostEffectProcessor postEffectProcessor = this.client.getShaderLoader().loadPostEffect(
|
||||
// Glass is blurred from the game as it is before this screen blurs it.
|
||||
if (Config.usesGlass()) {
|
||||
context.draw();
|
||||
GlassRenderer.saveBackground();
|
||||
}
|
||||
|
||||
float radius = screen.getBackgroundBlur();
|
||||
PostEffectProcessor postEffectProcessor = radius < 1 ? null : this.client.getShaderLoader().loadPostEffect(
|
||||
Identifier.ofVanilla("blur"),
|
||||
DefaultFramebufferSet.MAIN_ONLY);
|
||||
|
||||
if (postEffectProcessor != null) {
|
||||
float radius = screen.getBackgroundBlur();
|
||||
//? if >=1.21.5
|
||||
postEffectProcessor.render(this.client.getFramebuffer(), this.pool, pass -> pass.setUniform("Radius", radius));
|
||||
//? if <1.21.5
|
||||
@@ -245,11 +254,11 @@ public class SaturnScreenFabric extends Screen implements ScreenProvider {
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
return width * 2;
|
||||
return width;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
return height * 2;
|
||||
return height;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#version 330
|
||||
|
||||
// Saturn's glass: the blurred game behind the screen, cut to a panel's shape. For 1.21.6 and
|
||||
// later; glass_pre_1_21_6.fsh (with glass.json, the program 1.21.4 loads) is for older versions.
|
||||
|
||||
// Vanilla's own, since its layout changes between versions (1.21.11 dropped LineWidth)
|
||||
#moj_import <minecraft:dynamictransforms.glsl>
|
||||
|
||||
// The panel's rounded rectangle, the same texture its background is drawn with
|
||||
uniform sampler2D Sampler0;
|
||||
// The game behind the screen, blurred, the size of the framebuffer
|
||||
uniform sampler2D Sampler1;
|
||||
|
||||
in vec2 texCoord0;
|
||||
in vec4 vertexColor;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
float mask = texture(Sampler0, texCoord0).a * vertexColor.a;
|
||||
if (mask == 0.0) {
|
||||
discard;
|
||||
}
|
||||
|
||||
// The blurred copy lines up with the framebuffer being drawn to.
|
||||
vec2 screenUv = gl_FragCoord.xy / vec2(textureSize(Sampler1, 0));
|
||||
fragColor = vec4(texture(Sampler1, screenUv).rgb, mask) * ColorModulator;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"vertex": "minecraft:core/position_tex_color",
|
||||
"fragment": "saturnclient:core/glass_pre_1_21_6",
|
||||
"samplers": [
|
||||
{ "name": "Sampler0" },
|
||||
{ "name": "Sampler1" }
|
||||
],
|
||||
"uniforms": [
|
||||
{ "name": "ModelViewMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] },
|
||||
{ "name": "ProjMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] },
|
||||
{ "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] }
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#version 150
|
||||
|
||||
// Saturn's glass (see glass.fsh), for 1.21.4 and 1.21.5, which set uniforms one by one instead of in
|
||||
// blocks.
|
||||
|
||||
uniform vec4 ColorModulator;
|
||||
|
||||
// The panel's rounded rectangle, the same texture its background is drawn with
|
||||
uniform sampler2D Sampler0;
|
||||
// The game behind the screen, blurred, the size of the framebuffer
|
||||
uniform sampler2D Sampler1;
|
||||
|
||||
in vec2 texCoord0;
|
||||
in vec4 vertexColor;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
float mask = texture(Sampler0, texCoord0).a * vertexColor.a;
|
||||
if (mask == 0.0) {
|
||||
discard;
|
||||
}
|
||||
|
||||
// The blurred copy lines up with the framebuffer being drawn to.
|
||||
vec2 screenUv = gl_FragCoord.xy / vec2(textureSize(Sampler1, 0));
|
||||
fragColor = vec4(texture(Sampler1, screenUv).rgb, mask) * ColorModulator;
|
||||
}
|
||||
Reference in New Issue
Block a user