aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuuz <6596629+Juuxel@users.noreply.github.com>2023-03-18 16:25:38 +0200
committerGitHub <noreply@github.com>2023-03-18 16:25:38 +0200
commitc3600612a83442eeadf99a1602ab07537b071b66 (patch)
tree1d88bdedd4c00c332fa4f4e7f78b9c0ee842a2a9
parent91e4e6401089d6dc5b92589fa1fb1501b7217cf0 (diff)
downloadLibGui-c3600612a83442eeadf99a1602ab07537b071b66.tar.gz
LibGui-c3600612a83442eeadf99a1602ab07537b071b66.tar.bz2
LibGui-c3600612a83442eeadf99a1602ab07537b071b66.zip
Improve tiled NinePatchBackgroundPainter performance (#185)
* Improve tiled NinePatchBackgroundPainter performance * Use Fabric API's CoreShaderRegistrationCallback * Switch to LibNinePatch release build * Rename libgui:tiled -> libgui:tiled_rectangle * Fix grammar
-rw-r--r--gradle.properties4
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/impl/client/LibGuiClient.java2
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/impl/client/LibGuiShaders.java33
-rw-r--r--src/main/java/io/github/cottonmc/cotton/gui/impl/client/NinePatchTextureRendererImpl.java46
-rw-r--r--src/main/resources/assets/libgui/shaders/core/tiled_rectangle.fsh32
-rw-r--r--src/main/resources/assets/libgui/shaders/core/tiled_rectangle.json20
-rw-r--r--src/main/resources/assets/libgui/shaders/core/tiled_rectangle.vsh15
-rw-r--r--src/main/resources/fabric.mod.json4
8 files changed, 152 insertions, 4 deletions
diff --git a/gradle.properties b/gradle.properties
index a658910..9348b8a 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -14,7 +14,7 @@ fabric.loom.multiProjectOptimisation = true
archives_base_name = LibGui
# Dependencies
- fabric_version=0.68.1+1.19.3
+ fabric_version=0.76.0+1.19.3
jankson_version=5.0.0+j1.2.1
modmenu_version=5.0.2
- libninepatch_version=1.1.0
+ libninepatch_version=1.2.0
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/impl/client/LibGuiClient.java b/src/main/java/io/github/cottonmc/cotton/gui/impl/client/LibGuiClient.java
index 6bc69fe..526fe96 100644
--- a/src/main/java/io/github/cottonmc/cotton/gui/impl/client/LibGuiClient.java
+++ b/src/main/java/io/github/cottonmc/cotton/gui/impl/client/LibGuiClient.java
@@ -30,6 +30,8 @@ public class LibGuiClient implements ClientModInitializer {
ClientPlayNetworking.registerGlobalReceiver(ScreenNetworkingImpl.SCREEN_MESSAGE_S2C, (client, networkHandler, buf, responseSender) -> {
ScreenNetworkingImpl.handle(client, client.player, buf);
});
+
+ LibGuiShaders.register();
}
public static LibGuiConfig loadConfig() {
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/impl/client/LibGuiShaders.java b/src/main/java/io/github/cottonmc/cotton/gui/impl/client/LibGuiShaders.java
new file mode 100644
index 0000000..fbbad66
--- /dev/null
+++ b/src/main/java/io/github/cottonmc/cotton/gui/impl/client/LibGuiShaders.java
@@ -0,0 +1,33 @@
+package io.github.cottonmc.cotton.gui.impl.client;
+
+import net.fabricmc.fabric.api.client.rendering.v1.CoreShaderRegistrationCallback;
+import net.minecraft.client.gl.ShaderProgram;
+import net.minecraft.client.render.VertexFormats;
+import net.minecraft.util.Identifier;
+
+import io.github.cottonmc.cotton.gui.impl.LibGuiCommon;
+import org.jetbrains.annotations.Nullable;
+
+public final class LibGuiShaders {
+ private static @Nullable ShaderProgram tiledRectangle;
+
+ static void register() {
+ CoreShaderRegistrationCallback.EVENT.register(context -> {
+ // Register our core shaders.
+ // The tiled rectangle shader is used for performant tiled texture rendering.
+ context.register(new Identifier(LibGuiCommon.MOD_ID, "tiled_rectangle"), VertexFormats.POSITION, program -> tiledRectangle = program);
+ });
+ }
+
+ private static ShaderProgram assertPresent(ShaderProgram program, String name) {
+ if (program == null) {
+ throw new NullPointerException("Shader libgui:" + name + " not initialised!");
+ }
+
+ return program;
+ }
+
+ public static ShaderProgram getTiledRectangle() {
+ return assertPresent(tiledRectangle, "tiled_rectangle");
+ }
+}
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/impl/client/NinePatchTextureRendererImpl.java b/src/main/java/io/github/cottonmc/cotton/gui/impl/client/NinePatchTextureRendererImpl.java
index 7161373..9227f94 100644
--- a/src/main/java/io/github/cottonmc/cotton/gui/impl/client/NinePatchTextureRendererImpl.java
+++ b/src/main/java/io/github/cottonmc/cotton/gui/impl/client/NinePatchTextureRendererImpl.java
@@ -1,10 +1,20 @@
package io.github.cottonmc.cotton.gui.impl.client;
+import com.mojang.blaze3d.systems.RenderCall;
+import com.mojang.blaze3d.systems.RenderSystem;
+import net.minecraft.client.gl.ShaderProgram;
+import net.minecraft.client.render.BufferBuilder;
+import net.minecraft.client.render.BufferRenderer;
+import net.minecraft.client.render.Tessellator;
+import net.minecraft.client.render.VertexFormat;
+import net.minecraft.client.render.VertexFormats;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.Identifier;
import io.github.cottonmc.cotton.gui.client.ScreenDrawing;
import juuxel.libninepatch.ContextualTextureRenderer;
+import org.jetbrains.annotations.Nullable;
+import org.joml.Matrix4f;
/**
* An implementation of LibNinePatch's {@link ContextualTextureRenderer} for identifiers.
@@ -16,4 +26,40 @@ public enum NinePatchTextureRendererImpl implements ContextualTextureRenderer<Id
public void draw(Identifier texture, MatrixStack matrices, int x, int y, int width, int height, float u1, float v1, float u2, float v2) {
ScreenDrawing.texturedRect(matrices, x, y, width, height, texture, u1, v1, u2, v2, 0xFF_FFFFFF);
}
+
+ @Override
+ public void drawTiled(Identifier texture, MatrixStack matrices, int x, int y, int regionWidth, int regionHeight, int tileWidth, int tileHeight, float u1, float v1, float u2, float v2) {
+ RenderSystem.setShader(LibGuiShaders::getTiledRectangle);
+ RenderSystem.setShaderTexture(0, texture);
+ RenderSystem.setShaderColor(1, 1, 1, 1);
+ Matrix4f positionMatrix = matrices.peek().getPositionMatrix();
+ onRenderThread(() -> {
+ @Nullable ShaderProgram program = RenderSystem.getShader();
+ if (program != null) {
+ program.getUniformOrDefault("LibGuiRectanglePos").set((float) x, (float) y);
+ program.getUniformOrDefault("LibGuiTileDimensions").set((float) tileWidth, (float) tileHeight);
+ program.getUniformOrDefault("LibGuiTileUvs").set(u1, v1, u2, v2);
+ program.getUniformOrDefault("LibGuiPositionMatrix").set(positionMatrix);
+ }
+ });
+
+ Tessellator tessellator = Tessellator.getInstance();
+ BufferBuilder buffer = tessellator.getBuffer();
+ RenderSystem.enableBlend();
+ buffer.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION);
+ buffer.vertex(positionMatrix, x, y, 0).next();
+ buffer.vertex(positionMatrix, x, y + regionHeight, 0).next();
+ buffer.vertex(positionMatrix, x + regionWidth, y + regionHeight, 0).next();
+ buffer.vertex(positionMatrix, x + regionWidth, y, 0).next();
+ BufferRenderer.drawWithGlobalProgram(buffer.end());
+ RenderSystem.disableBlend();
+ }
+
+ private static void onRenderThread(RenderCall renderCall) {
+ if (RenderSystem.isOnRenderThread()) {
+ renderCall.execute();
+ } else {
+ RenderSystem.recordRenderCall(renderCall);
+ }
+ }
}
diff --git a/src/main/resources/assets/libgui/shaders/core/tiled_rectangle.fsh b/src/main/resources/assets/libgui/shaders/core/tiled_rectangle.fsh
new file mode 100644
index 0000000..15e3185
--- /dev/null
+++ b/src/main/resources/assets/libgui/shaders/core/tiled_rectangle.fsh
@@ -0,0 +1,32 @@
+#version 150
+
+uniform sampler2D Sampler0;
+uniform vec4 ColorModulator;
+
+uniform vec2 LibGuiRectanglePos;
+uniform vec2 LibGuiTileDimensions;
+uniform vec4 LibGuiTileUvs;
+
+in vec2 vertexPosition;
+out vec4 fragColor;
+
+float lerp(float time, float a, float b) {
+ return (1 - time) * a + time * b;
+}
+
+vec2 getTextureCoords(vec2 pos) {
+ float deltaX = mod(pos.x - LibGuiRectanglePos.x, LibGuiTileDimensions.x) / LibGuiTileDimensions.x;
+ float deltaY = mod(pos.y - LibGuiRectanglePos.y, LibGuiTileDimensions.y) / LibGuiTileDimensions.y;
+ return vec2(
+ lerp(deltaX, LibGuiTileUvs.x, LibGuiTileUvs.z),
+ lerp(deltaY, LibGuiTileUvs.y, LibGuiTileUvs.w)
+ );
+}
+
+void main() {
+ vec4 color = texture(Sampler0, getTextureCoords(vertexPosition));
+ if (color.a < 0.1) {
+ discard;
+ }
+ fragColor = color * ColorModulator;
+}
diff --git a/src/main/resources/assets/libgui/shaders/core/tiled_rectangle.json b/src/main/resources/assets/libgui/shaders/core/tiled_rectangle.json
new file mode 100644
index 0000000..2ca0af3
--- /dev/null
+++ b/src/main/resources/assets/libgui/shaders/core/tiled_rectangle.json
@@ -0,0 +1,20 @@
+{
+ "blend": {
+ "func": "add",
+ "srcrgb": "srcalpha",
+ "dstrgb": "1-srcalpha"
+ },
+ "vertex": "libgui:tiled_rectangle",
+ "fragment": "libgui:tiled_rectangle",
+ "attributes": ["Position"],
+ "samplers": [{ "name": "Sampler0" }],
+ "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 ] },
+ { "name": "LibGuiRectanglePos", "type": "float", "count": 2, "values": [ 0.0, 0.0 ] },
+ { "name": "LibGuiTileDimensions", "type": "float", "count": 2, "values": [ 0.0, 0.0 ] },
+ { "name": "LibGuiTileUvs", "type": "float", "count": 4, "values": [ 0.0, 0.0, 1.0, 1.0 ] },
+ { "name": "LibGuiPositionMatrix", "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 ] }
+ ]
+}
diff --git a/src/main/resources/assets/libgui/shaders/core/tiled_rectangle.vsh b/src/main/resources/assets/libgui/shaders/core/tiled_rectangle.vsh
new file mode 100644
index 0000000..6a1209d
--- /dev/null
+++ b/src/main/resources/assets/libgui/shaders/core/tiled_rectangle.vsh
@@ -0,0 +1,15 @@
+#version 150
+
+in vec3 Position;
+
+uniform mat4 ModelViewMat;
+uniform mat4 ProjMat;
+uniform mat4 LibGuiPositionMatrix;
+
+out vec2 vertexPosition;
+
+void main() {
+ gl_Position = ProjMat * ModelViewMat * vec4(Position, 1.0);
+ vec4 rawPos = inverse(LibGuiPositionMatrix) * vec4(Position, 1.0);
+ vertexPosition = rawPos.xy;
+}
diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json
index 22868a2..b5d1caf 100644
--- a/src/main/resources/fabric.mod.json
+++ b/src/main/resources/fabric.mod.json
@@ -28,10 +28,10 @@
"fabric-api-base": ">=0.4.4",
"fabric-lifecycle-events-v1": "^2.0.2",
"fabric-networking-api-v1": "^1.0.21",
- "fabric-rendering-v1": "^1.10.7",
+ "fabric-rendering-v1": "^1.13.0",
"minecraft": ">=1.19.3",
"jankson": "^5.0.0",
- "libninepatch": "^1.1.0"
+ "libninepatch": "^1.2.0"
},
"suggests": {
"flamingo": "*"