aboutsummaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
authorAaron <51387595+AzureAaron@users.noreply.github.com>2023-11-13 21:33:01 -0500
committerGitHub <noreply@github.com>2023-11-13 21:33:01 -0500
commit41cc6598899c0ec3b906c75f6be6805be315e100 (patch)
tree09272777eeccc55c9f28e3c64b4d0aea61b92bf3 /src/main
parent7fd8afe2f92f2407fca51328cf8f4a2c75c716f9 (diff)
parent736db8f1b0076ebe639bf0c1590e86d05191f01f (diff)
downloadSkyblocker-41cc6598899c0ec3b906c75f6be6805be315e100.tar.gz
Skyblocker-41cc6598899c0ec3b906c75f6be6805be315e100.tar.bz2
Skyblocker-41cc6598899c0ec3b906c75f6be6805be315e100.zip
Merge pull request #415 from AzureAaron/batched-rendering
Batched Rendering + Future Sodium Compat
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/de/hysky/skyblocker/SkyblockerMod.java2
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/special/SpecialEffects.java11
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/render/RenderHelper.java88
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/render/SkyblockerRenderLayers.java36
4 files changed, 102 insertions, 35 deletions
diff --git a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java
index 65404c6c..ad3b6318 100644
--- a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java
+++ b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java
@@ -27,6 +27,7 @@ import de.hysky.skyblocker.utils.NEURepoManager;
import de.hysky.skyblocker.utils.Utils;
import de.hysky.skyblocker.utils.chat.ChatMessageListener;
import de.hysky.skyblocker.utils.discord.DiscordRPCManager;
+import de.hysky.skyblocker.utils.render.RenderHelper;
import de.hysky.skyblocker.utils.render.culling.OcclusionCulling;
import de.hysky.skyblocker.utils.render.gui.ContainerSolverManager;
import de.hysky.skyblocker.utils.render.title.TitleContainer;
@@ -115,6 +116,7 @@ public class SkyblockerMod implements ClientModInitializer {
SecretsTracker.init();
ApiUtils.init();
Debug.init();
+ RenderHelper.init();
containerSolverManager.init();
statusBarTracker.init();
Scheduler.INSTANCE.scheduleCyclic(Utils::update, 20);
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/special/SpecialEffects.java b/src/main/java/de/hysky/skyblocker/skyblock/special/SpecialEffects.java
index fba447ea..bc4f98c2 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/special/SpecialEffects.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/special/SpecialEffects.java
@@ -1,8 +1,8 @@
package de.hysky.skyblocker.skyblock.special;
-import com.mojang.blaze3d.systems.RenderSystem;
import de.hysky.skyblocker.config.SkyblockerConfigManager;
import de.hysky.skyblocker.utils.Utils;
+import de.hysky.skyblocker.utils.render.RenderHelper;
import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents;
import net.minecraft.client.MinecraftClient;
import net.minecraft.enchantment.Enchantments;
@@ -58,15 +58,10 @@ public class SpecialEffects {
ItemStack stack = getStackFromName(matcher.group("item"));
if (!stack.isEmpty()) {
- if (RenderSystem.isOnRenderThread()) {
+ RenderHelper.runOnRenderThread(() -> {
client.particleManager.addEmitter(client.player, ParticleTypes.PORTAL, 30);
client.gameRenderer.showFloatingItem(stack);
- } else {
- RenderSystem.recordRenderCall(() -> {
- client.particleManager.addEmitter(client.player, ParticleTypes.PORTAL, 30);
- client.gameRenderer.showFloatingItem(stack);
- });
- }
+ });
}
}
}
diff --git a/src/main/java/de/hysky/skyblocker/utils/render/RenderHelper.java b/src/main/java/de/hysky/skyblocker/utils/render/RenderHelper.java
index e4cfea1b..3d8213fe 100644
--- a/src/main/java/de/hysky/skyblocker/utils/render/RenderHelper.java
+++ b/src/main/java/de/hysky/skyblocker/utils/render/RenderHelper.java
@@ -1,11 +1,16 @@
package de.hysky.skyblocker.utils.render;
import com.mojang.blaze3d.systems.RenderSystem;
+import com.mojang.logging.LogUtils;
+
+import de.hysky.skyblocker.SkyblockerMod;
import de.hysky.skyblocker.mixin.accessor.BeaconBlockEntityRendererInvoker;
import de.hysky.skyblocker.utils.render.culling.OcclusionCulling;
import de.hysky.skyblocker.utils.render.title.Title;
import de.hysky.skyblocker.utils.render.title.TitleContainer;
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext;
+import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents;
+import net.fabricmc.fabric.api.event.Event;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.render.*;
@@ -14,18 +19,33 @@ import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.sound.SoundEvents;
import net.minecraft.text.OrderedText;
import net.minecraft.text.Text;
+import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.Vec3d;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+
import org.joml.Matrix3f;
import org.joml.Matrix4f;
import org.lwjgl.opengl.GL11;
+import org.slf4j.Logger;
public class RenderHelper {
+ private static final Logger LOGGER = LogUtils.getLogger();
+ private static final Identifier TRANSLUCENT_DRAW = new Identifier(SkyblockerMod.NAMESPACE, "translucent_draw");
+ private static final MethodHandle SCHEDULE_DEFERRED_RENDER_TASK = getDeferredRenderTaskHandle();
private static final Vec3d ONE = new Vec3d(1, 1, 1);
private static final int MAX_OVERWORLD_BUILD_HEIGHT = 319;
private static final MinecraftClient client = MinecraftClient.getInstance();
+ public static void init() {
+ WorldRenderEvents.AFTER_TRANSLUCENT.addPhaseOrdering(Event.DEFAULT_PHASE, TRANSLUCENT_DRAW);
+ WorldRenderEvents.AFTER_TRANSLUCENT.register(TRANSLUCENT_DRAW, RenderHelper::drawTranslucents);
+ }
+
public static void renderFilledThroughWallsWithBeaconBeam(WorldRenderContext context, BlockPos pos, float[] colorComponents, float alpha) {
renderFilledThroughWalls(context, pos, colorComponents, alpha);
renderBeaconBeam(context, pos, colorComponents);
@@ -46,33 +66,16 @@ public class RenderHelper {
private static void renderFilled(WorldRenderContext context, Vec3d pos, Vec3d dimensions, float[] colorComponents, float alpha, boolean throughWalls) {
MatrixStack matrices = context.matrixStack();
Vec3d camera = context.camera().getPos();
- Tessellator tessellator = RenderSystem.renderThreadTesselator();
- BufferBuilder buffer = tessellator.getBuffer();
matrices.push();
matrices.translate(-camera.x, -camera.y, -camera.z);
- RenderSystem.setShader(GameRenderer::getPositionColorProgram);
- RenderSystem.setShaderColor(1f, 1f, 1f, 1f);
- RenderSystem.polygonOffset(-1f, -10f);
- RenderSystem.enablePolygonOffset();
- RenderSystem.enableBlend();
- RenderSystem.defaultBlendFunc();
- RenderSystem.enableDepthTest();
- RenderSystem.depthFunc(throughWalls ? GL11.GL_ALWAYS : GL11.GL_LEQUAL);
- RenderSystem.disableCull();
+ VertexConsumerProvider consumers = context.consumers();
+ VertexConsumer buffer = consumers.getBuffer(throughWalls ? SkyblockerRenderLayers.FILLED_THROUGH_WALLS : SkyblockerRenderLayers.FILLED);
- buffer.begin(DrawMode.TRIANGLE_STRIP, VertexFormats.POSITION_COLOR);
WorldRenderer.renderFilledBox(matrices, buffer, pos.x, pos.y, pos.z, pos.x + dimensions.x, pos.y + dimensions.y, pos.z + dimensions.z, colorComponents[0], colorComponents[1], colorComponents[2], alpha);
- tessellator.draw();
matrices.pop();
- RenderSystem.polygonOffset(0f, 0f);
- RenderSystem.disablePolygonOffset();
- RenderSystem.disableBlend();
- RenderSystem.disableDepthTest();
- RenderSystem.depthFunc(GL11.GL_LEQUAL);
- RenderSystem.enableCull();
}
private static void renderBeaconBeam(WorldRenderContext context, BlockPos pos, float[] colorComponents) {
@@ -83,13 +86,8 @@ public class RenderHelper {
matrices.push();
matrices.translate(pos.getX() - camera.getX(), pos.getY() - camera.getY(), pos.getZ() - camera.getZ());
- Tessellator tessellator = RenderSystem.renderThreadTesselator();
- BufferBuilder buffer = tessellator.getBuffer();
- VertexConsumerProvider.Immediate consumer = VertexConsumerProvider.immediate(buffer);
-
- BeaconBlockEntityRendererInvoker.renderBeam(matrices, consumer, context.tickDelta(), context.world().getTime(), 0, MAX_OVERWORLD_BUILD_HEIGHT, colorComponents);
+ BeaconBlockEntityRendererInvoker.renderBeam(matrices, context.consumers(), context.tickDelta(), context.world().getTime(), 0, MAX_OVERWORLD_BUILD_HEIGHT, colorComponents);
- consumer.draw();
matrices.pop();
}
}
@@ -259,6 +257,28 @@ public class RenderHelper {
}
/**
+ * This is called after all {@link WorldRenderEvents#AFTER_TRANSLUCENT} listeners have been called so that we can draw all remaining render layers.
+ */
+ private static void drawTranslucents(WorldRenderContext context) {
+ //Draw all render layers that haven't been drawn yet - drawing a specific layer does nothing and idk why
+ ((VertexConsumerProvider.Immediate) context.consumers()).draw();
+ }
+
+ public static void runOnRenderThread(Runnable runnable) {
+ if (RenderSystem.isOnRenderThread()) {
+ runnable.run();
+ } else if (SCHEDULE_DEFERRED_RENDER_TASK != null) { //Sodium
+ try {
+ SCHEDULE_DEFERRED_RENDER_TASK.invokeExact(runnable);
+ } catch (Throwable t) {
+ LOGGER.error("[Skyblocker] Failed to schedule a render task!", t);
+ }
+ } else { //Vanilla
+ RenderSystem.recordRenderCall(runnable::run);
+ }
+ }
+
+ /**
* Adds the title to {@link TitleContainer} and {@link #playNotificationSound() plays the notification sound} if the title is not in the {@link TitleContainer} already.
* No checking needs to be done on whether the title is in the {@link TitleContainer} already by the caller.
*
@@ -284,12 +304,26 @@ public class RenderHelper {
}
private static void playNotificationSound() {
- if (MinecraftClient.getInstance().player != null) {
- MinecraftClient.getInstance().player.playSound(SoundEvents.ENTITY_EXPERIENCE_ORB_PICKUP, 100f, 0.1f);
+ if (client.player != null) {
+ client.player.playSound(SoundEvents.ENTITY_EXPERIENCE_ORB_PICKUP, 100f, 0.1f);
}
}
public static boolean pointIsInArea(double x, double y, double x1, double y1, double x2, double y2) {
return x >= x1 && x <= x2 && y >= y1 && y <= y2;
}
+
+ // TODO Get rid of reflection once the new Sodium is released
+ private static MethodHandle getDeferredRenderTaskHandle() {
+ try {
+ Class<?> deferredTaskClass = Class.forName("me.jellysquid.mods.sodium.client.render.util.DeferredRenderTask");
+
+ MethodHandles.Lookup lookup = MethodHandles.publicLookup();
+ MethodType mt = MethodType.methodType(void.class, Runnable.class);
+
+ return lookup.findStatic(deferredTaskClass, "schedule", mt);
+ } catch (Throwable ignored) {}
+
+ return null;
+ }
}
diff --git a/src/main/java/de/hysky/skyblocker/utils/render/SkyblockerRenderLayers.java b/src/main/java/de/hysky/skyblocker/utils/render/SkyblockerRenderLayers.java
new file mode 100644
index 00000000..ee113cc4
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/utils/render/SkyblockerRenderLayers.java
@@ -0,0 +1,36 @@
+package de.hysky.skyblocker.utils.render;
+
+import com.mojang.blaze3d.systems.RenderSystem;
+
+import net.minecraft.client.render.RenderLayer;
+import net.minecraft.client.render.RenderLayer.MultiPhase;
+import net.minecraft.client.render.RenderLayer.MultiPhaseParameters;
+import net.minecraft.client.render.RenderPhase;
+import net.minecraft.client.render.RenderPhase.Cull;
+import net.minecraft.client.render.RenderPhase.DepthTest;
+import net.minecraft.client.render.RenderPhase.Transparency;
+import net.minecraft.client.render.VertexFormat.DrawMode;
+import net.minecraft.client.render.VertexFormats;
+
+public class SkyblockerRenderLayers {
+ private static final Transparency DEFAULT_TRANSPARENCY = new Transparency("default_transparency", () -> {
+ RenderSystem.enableBlend();
+ RenderSystem.defaultBlendFunc();
+ }, RenderSystem::disableBlend);
+
+ public static final MultiPhase FILLED = RenderLayer.of("filled", VertexFormats.POSITION_COLOR, DrawMode.TRIANGLE_STRIP, RenderLayer.CUTOUT_BUFFER_SIZE, false, true, MultiPhaseParameters.builder()
+ .program(RenderPhase.COLOR_PROGRAM)
+ .cull(Cull.DISABLE_CULLING)
+ .layering(RenderPhase.POLYGON_OFFSET_LAYERING)
+ .transparency(DEFAULT_TRANSPARENCY)
+ .depthTest(DepthTest.LEQUAL_DEPTH_TEST)
+ .build(false));
+
+ public static final MultiPhase FILLED_THROUGH_WALLS = RenderLayer.of("filled_through_walls", VertexFormats.POSITION_COLOR, DrawMode.TRIANGLE_STRIP, RenderLayer.CUTOUT_BUFFER_SIZE, false, true, MultiPhaseParameters.builder()
+ .program(RenderPhase.COLOR_PROGRAM)
+ .cull(Cull.DISABLE_CULLING)
+ .layering(RenderPhase.POLYGON_OFFSET_LAYERING)
+ .transparency(DEFAULT_TRANSPARENCY)
+ .depthTest(DepthTest.ALWAYS_DEPTH_TEST)
+ .build(false));
+}