diff options
author | Juuz <6596629+Juuxel@users.noreply.github.com> | 2023-03-18 16:25:38 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-18 16:25:38 +0200 |
commit | c3600612a83442eeadf99a1602ab07537b071b66 (patch) | |
tree | 1d88bdedd4c00c332fa4f4e7f78b9c0ee842a2a9 /src/main/java/io | |
parent | 91e4e6401089d6dc5b92589fa1fb1501b7217cf0 (diff) | |
download | LibGui-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
Diffstat (limited to 'src/main/java/io')
3 files changed, 81 insertions, 0 deletions
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); + } + } } |