From 9736ba19b5ae2aa9803249273be7b1df2f9c38f3 Mon Sep 17 00:00:00 2001 From: JozsefA Date: Tue, 4 May 2021 23:56:50 -0700 Subject: [PATCH] Things here and there - Move CreateClient.kineticRenderer to Backend - InstancedTileRenderers keep track of their own queuedUpdates - Sort of a listener system for some render events --- .../jozufozu/flywheel/backend/Backend.java | 63 ++++++++++-------- .../flywheel/backend/FlywheelListeners.java | 65 +++++++++++++++++++ .../core/BasicInstancedTileRenderer.java | 10 +-- .../instancing/InstancedTileRenderer.java | 43 ++++++++---- .../com/simibubi/create/CreateClient.java | 11 ++-- .../render/ContraptionKineticRenderer.java | 8 +-- .../render/ContraptionRenderDispatcher.java | 28 +++++--- .../render/RenderedContraption.java | 2 +- .../simibubi/create/events/ClientEvents.java | 2 +- .../foundation/mixin/LightUpdateMixin.java | 6 +- .../mixin/NetworkLightUpdateMixin.java | 6 +- .../foundation/mixin/RenderHooksMixin.java | 55 ++++++---------- .../mixin/StoreProjectionMatrixMixin.java | 2 +- .../foundation/mixin/TileRemoveMixin.java | 6 +- .../foundation/mixin/TileWorldHookMixin.java | 8 +-- .../flywheel/shaders/contraption/builtin.frag | 2 +- .../create/flywheel/shaders/std/builtin.frag | 2 +- .../create/flywheel/shaders/std/fog.glsl | 8 +-- 18 files changed, 208 insertions(+), 119 deletions(-) create mode 100644 src/main/java/com/jozufozu/flywheel/backend/FlywheelListeners.java diff --git a/src/main/java/com/jozufozu/flywheel/backend/Backend.java b/src/main/java/com/jozufozu/flywheel/backend/Backend.java index b406c55d0..5c7e52f22 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/Backend.java +++ b/src/main/java/com/jozufozu/flywheel/backend/Backend.java @@ -3,7 +3,6 @@ package com.jozufozu.flywheel.backend; import java.util.Collection; import java.util.HashMap; import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -11,7 +10,6 @@ import org.lwjgl.opengl.GL; import org.lwjgl.opengl.GLCapabilities; import com.jozufozu.flywheel.backend.core.BasicInstancedTileRenderer; -import com.jozufozu.flywheel.backend.core.ContraptionContext; import com.jozufozu.flywheel.backend.core.EffectsContext; import com.jozufozu.flywheel.backend.core.WorldContext; import com.jozufozu.flywheel.backend.effects.EffectsHandler; @@ -21,7 +19,6 @@ import com.jozufozu.flywheel.backend.gl.versioned.GlCompat; import com.jozufozu.flywheel.backend.instancing.IFlywheelWorld; import com.jozufozu.flywheel.backend.instancing.InstancedModel; import com.jozufozu.flywheel.backend.instancing.MaterialSpec; -import com.simibubi.create.CreateClient; import com.simibubi.create.content.contraptions.KineticDebugger; import com.simibubi.create.foundation.config.AllConfigs; import com.simibubi.create.foundation.utility.WorldAttached; @@ -42,25 +39,41 @@ public class Backend { public static final Logger log = LogManager.getLogger(Backend.class); public static final ShaderLoader shaderLoader = new ShaderLoader(); - public static EffectsHandler effects; - - public static Matrix4f projectionMatrix = new Matrix4f(); + public static final FlywheelListeners listeners = new FlywheelListeners(); public static GLCapabilities capabilities; public static GlCompat compat; - public static WorldAttached> queuedUpdates = new WorldAttached<>(ConcurrentHashMap::newKeySet); + public static EffectsHandler effects; + public static WorldAttached tileRenderer = new WorldAttached<>(BasicInstancedTileRenderer::new); + + private static Matrix4f projectionMatrix = new Matrix4f(); private static boolean instancingAvailable; private static boolean enabled; - static Map> materialRegistry = new HashMap<>(); + static final Map> materialRegistry = new HashMap<>(); static final Map> contexts = new HashMap<>(); static final Map programSpecRegistry = new HashMap<>(); static { register(WorldContext.INSTANCE); - register(ContraptionContext.INSTANCE); register(EffectsContext.INSTANCE); + + listeners.refreshListener(world -> { + if (canUseInstancing() && world != null) { + BasicInstancedTileRenderer tileRenderer = Backend.tileRenderer.get(world); + tileRenderer.invalidate(); + world.loadedTileEntityList.forEach(tileRenderer::add); + } + }); + + listeners.setupFrameListener((world, stack, info, gameRenderer, lightTexture) -> { + + Backend.tileRenderer.get(world) + .beginFrame(info); + }); + + listeners.renderLayerListener(Backend::renderLayer); } public Backend() { @@ -161,35 +174,25 @@ public class Backend { Minecraft mc = Minecraft.getInstance(); ClientWorld world = mc.world; - BasicInstancedTileRenderer kineticRenderer = CreateClient.kineticRenderer.get(world); + BasicInstancedTileRenderer instancer = tileRenderer.get(world); Entity renderViewEntity = mc.renderViewEntity; - kineticRenderer.tick(renderViewEntity.getX(), renderViewEntity.getY(), renderViewEntity.getZ()); - - ConcurrentHashMap.KeySetView map = queuedUpdates.get(world); - map - .forEach(te -> { - map.remove(te); - - kineticRenderer.update(te); - }); + instancer.tick(renderViewEntity.getX(), renderViewEntity.getY(), renderViewEntity.getZ()); } - public static void renderLayer(RenderType layer, Matrix4f viewProjection, double cameraX, double cameraY, double cameraZ) { - if (!canUseInstancing()) return; - - ClientWorld world = Minecraft.getInstance().world; - BasicInstancedTileRenderer kineticRenderer = CreateClient.kineticRenderer.get(world); + public static void renderLayer(ClientWorld world, RenderType layer, Matrix4f viewProjection, double cameraX, double cameraY, double cameraZ) { + if (!canUseInstancing(world)) return; layer.startDrawing(); - kineticRenderer.render(layer, viewProjection, cameraX, cameraY, cameraZ); + tileRenderer.get(world) + .render(layer, viewProjection, cameraX, cameraY, cameraZ); layer.endDrawing(); } public static void enqueueUpdate(TileEntity te) { - queuedUpdates.get(te.getWorld()).add(te); + tileRenderer.get(te.getWorld()).queueUpdate(te); } public static void reloadWorldRenderers() { @@ -215,4 +218,12 @@ public class Backend { public static Collection allPrograms() { return programSpecRegistry.values(); } + + public static Matrix4f getProjectionMatrix() { + return projectionMatrix; + } + + public static void setProjectionMatrix(Matrix4f projectionMatrix) { + Backend.projectionMatrix = projectionMatrix; + } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/FlywheelListeners.java b/src/main/java/com/jozufozu/flywheel/backend/FlywheelListeners.java new file mode 100644 index 000000000..f0f86b5a8 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/backend/FlywheelListeners.java @@ -0,0 +1,65 @@ +package com.jozufozu.flywheel.backend; + +import java.util.ArrayList; +import java.util.List; + +import com.mojang.blaze3d.matrix.MatrixStack; + +import net.minecraft.client.renderer.ActiveRenderInfo; +import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.client.renderer.LightTexture; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.world.ClientWorld; +import net.minecraft.util.math.vector.Matrix4f; + +public class FlywheelListeners { + + private final List setupFrameListeners = new ArrayList<>(); + private final List renderLayerListeners = new ArrayList<>(); + private final List refreshListeners = new ArrayList<>(); + + public void setupFrameListener(SetupFrame setupFrame) { + setupFrameListeners.add(setupFrame); + } + + public void renderLayerListener(RenderLayer renderLayer) { + renderLayerListeners.add(renderLayer); + } + + public void refreshListener(Refresh refresh) { + refreshListeners.add(refresh); + } + + public void setupFrame(ClientWorld world, MatrixStack stack, ActiveRenderInfo info, GameRenderer gameRenderer, LightTexture lightTexture) { + for (SetupFrame listener : setupFrameListeners) { + listener.setupFrame(world, stack, info, gameRenderer, lightTexture); + } + } + + public void renderLayer(ClientWorld world, RenderType type, Matrix4f stack, double camX, double camY, double camZ) { + for (RenderLayer listener : renderLayerListeners) { + listener.renderLayer(world, type, stack, camX, camY, camZ); + } + } + + public void refresh(ClientWorld world) { + for (Refresh listener : refreshListeners) { + listener.refresh(world); + } + } + + @FunctionalInterface + public interface SetupFrame { + void setupFrame(ClientWorld world, MatrixStack stack, ActiveRenderInfo info, GameRenderer gameRenderer, LightTexture lightTexture); + } + + @FunctionalInterface + public interface RenderLayer { + void renderLayer(ClientWorld world, RenderType type, Matrix4f viewProjection, double camX, double camY, double camZ); + } + + @FunctionalInterface + public interface Refresh { + void refresh(ClientWorld world); + } +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/core/BasicInstancedTileRenderer.java b/src/main/java/com/jozufozu/flywheel/backend/core/BasicInstancedTileRenderer.java index 2ea176ebb..0f41acf2e 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/core/BasicInstancedTileRenderer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/core/BasicInstancedTileRenderer.java @@ -27,10 +27,10 @@ public class BasicInstancedTileRenderer extends InstancedTileRenderer { - protected ArrayList queuedAdditions = new ArrayList<>(64); - - protected Map> instances = new HashMap<>(); - - protected Map tickableInstances = new HashMap<>(); - protected Map dynamicInstances = new HashMap<>(); public final WorldContext

context; - protected Map, RenderMaterial> materials = new HashMap<>(); + protected final Map, RenderMaterial> materials; + + protected final ArrayList queuedAdditions; + protected final ConcurrentHashMap.KeySetView queuedUpdates; + + protected final Map> instances; + protected final Map tickableInstances; + protected final Map dynamicInstances; protected int frame; protected int tick; @@ -42,9 +44,16 @@ public abstract class InstancedTileRenderer

{ protected InstancedTileRenderer(WorldContext

context) { this.context = context; + materials = new HashMap<>(); for (MaterialSpec spec : Backend.allMaterials()) { materials.put(spec, spec.create(this)); } + + queuedUpdates = ConcurrentHashMap.newKeySet(64); + queuedAdditions = new ArrayList<>(64); + dynamicInstances = new HashMap<>(); + tickableInstances = new HashMap<>(); + instances = new HashMap<>(); } public abstract BlockPos getOriginCoordinate(); @@ -74,9 +83,15 @@ public abstract class InstancedTileRenderer

{ instance.tick(); } } + + queuedUpdates.forEach(te -> { + queuedUpdates.remove(te); + + update(te); + }); } - public void beginFrame(ActiveRenderInfo info, double cameraX, double cameraY, double cameraZ) { + public void beginFrame(ActiveRenderInfo info) { frame++; processQueuedAdditions(); @@ -86,9 +101,9 @@ public abstract class InstancedTileRenderer

{ float lookZ = look.getZ(); // integer camera pos - int cX = (int) cameraX; - int cY = (int) cameraY; - int cZ = (int) cameraZ; + int cX = (int) info.getProjectedView().x; + int cY = (int) info.getProjectedView().y; + int cZ = (int) info.getProjectedView().z; if (dynamicInstances.size() > 0) { for (IDynamicInstance dyn : dynamicInstances.values()) { @@ -195,6 +210,12 @@ public abstract class InstancedTileRenderer

{ queuedAdditions.add(tile); } + public synchronized void queueUpdate(T tile) { + if (!Backend.canUseInstancing()) return; + + queuedUpdates.add(tile); + } + protected synchronized void processQueuedAdditions() { if (queuedAdditions.size() > 0) { queuedAdditions.forEach(this::addInternal); diff --git a/src/main/java/com/simibubi/create/CreateClient.java b/src/main/java/com/simibubi/create/CreateClient.java index fe230c877..825d900cc 100644 --- a/src/main/java/com/simibubi/create/CreateClient.java +++ b/src/main/java/com/simibubi/create/CreateClient.java @@ -9,7 +9,6 @@ import javax.annotation.Nullable; import com.jozufozu.flywheel.backend.Backend; import com.jozufozu.flywheel.backend.OptifineHandler; -import com.jozufozu.flywheel.backend.core.BasicInstancedTileRenderer; import com.jozufozu.flywheel.backend.core.PartialModel; import com.jozufozu.flywheel.backend.instancing.InstancedTileRenderer; import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer; @@ -30,7 +29,6 @@ import com.simibubi.create.foundation.ponder.elements.WorldSectionElement; import com.simibubi.create.foundation.render.AllMaterialSpecs; import com.simibubi.create.foundation.render.AllProgramSpecs; import com.simibubi.create.foundation.render.SuperByteBufferCache; -import com.simibubi.create.foundation.utility.WorldAttached; import com.simibubi.create.foundation.utility.ghost.GhostBlocks; import com.simibubi.create.foundation.utility.outliner.Outliner; @@ -66,7 +64,6 @@ public class CreateClient { public static SchematicHandler schematicHandler; public static SchematicAndQuillHandler schematicAndQuillHandler; public static SuperByteBufferCache bufferCache; - public static WorldAttached kineticRenderer; public static final Outliner outliner = new Outliner(); public static GhostBlocks ghostBlocks; @@ -84,13 +81,13 @@ public class CreateClient { modEventBus.addListener(AllParticleTypes::registerFactories); Backend.init(); + ContraptionRenderDispatcher.init(); OptifineHandler.init(); } public static void clientInit(FMLClientSetupEvent event) { AllProgramSpecs.init(); AllMaterialSpecs.init(); - kineticRenderer = new WorldAttached<>(BasicInstancedTileRenderer::new); schematicSender = new ClientSchematicLoader(); schematicHandler = new SchematicHandler(); @@ -221,10 +218,10 @@ public class CreateClient { bufferCache.invalidate(); if (world != null) { - kineticRenderer.get(world) - .invalidate(); + Backend.tileRenderer.get(world) + .invalidate(); } else { - kineticRenderer.forEach(InstancedTileRenderer::invalidate); + Backend.tileRenderer.forEach(InstancedTileRenderer::invalidate); } ContraptionRenderDispatcher.invalidateAll(); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionKineticRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionKineticRenderer.java index ae766a36c..2d4723fb8 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionKineticRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionKineticRenderer.java @@ -37,11 +37,11 @@ public class ContraptionKineticRenderer extends InstancedTileRenderer> CONTRAPTION = new Compartment<>(); protected static PlacementSimulationWorld renderWorld; + public static void init() { + Backend.register(ContraptionContext.INSTANCE); + Backend.listeners.renderLayerListener(ContraptionRenderDispatcher::renderLayer); + Backend.listeners.setupFrameListener(ContraptionRenderDispatcher::beginFrame); + Backend.listeners.refreshListener($ -> ContraptionRenderDispatcher.invalidateAll()); + } + public static void tick() { if (Minecraft.getInstance().isGamePaused()) return; @@ -65,22 +74,25 @@ public class ContraptionRenderDispatcher { } } - public static void beginFrame(ActiveRenderInfo info, double camX, double camY, double camZ) { + public static void beginFrame(ClientWorld world, MatrixStack stack, ActiveRenderInfo info, GameRenderer gameRenderer, LightTexture lightTexture) { + double camX = info.getProjectedView().x; + double camY = info.getProjectedView().y; + double camZ = info.getProjectedView().z; for (RenderedContraption renderer : renderers.values()) { renderer.beginFrame(info, camX, camY, camZ); } } - public static void renderLayer(RenderType layer, Matrix4f viewProjection, double camX, double camY, double camZ) { - removeDeadContraptions(); + public static void renderLayer(ClientWorld world, RenderType layer, Matrix4f viewProjection, double camX, double camY, double camZ) { + removeDeadContraptions(); - if (renderers.isEmpty()) return; + if (renderers.isEmpty()) return; - layer.startDrawing(); - GL11.glEnable(GL13.GL_TEXTURE_3D); - GL13.glActiveTexture(GL40.GL_TEXTURE4); // the shaders expect light volumes to be in texture 4 + layer.startDrawing(); + GL11.glEnable(GL13.GL_TEXTURE_3D); + GL13.glActiveTexture(GL40.GL_TEXTURE4); // the shaders expect light volumes to be in texture 4 - if (Backend.canUseVBOs()) { + if (Backend.canUseVBOs()) { ContraptionProgram structureShader = ContraptionContext.INSTANCE.getProgram(AllProgramSpecs.STRUCTURE); structureShader.bind(viewProjection, camX, camY, camZ, Backend.getDebugMode()); for (RenderedContraption renderer : renderers.values()) { diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/RenderedContraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/RenderedContraption.java index 16b079aa8..b7db073c9 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/RenderedContraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/RenderedContraption.java @@ -89,7 +89,7 @@ public class RenderedContraption { } public void beginFrame(ActiveRenderInfo info, double camX, double camY, double camZ) { - kinetics.beginFrame(info, camX, camY, camZ); + kinetics.beginFrame(info); AbstractContraptionEntity entity = contraption.entity; float pt = AnimationTickHolder.getPartialTicks(); diff --git a/src/main/java/com/simibubi/create/events/ClientEvents.java b/src/main/java/com/simibubi/create/events/ClientEvents.java index b71847356..0c9400ae5 100644 --- a/src/main/java/com/simibubi/create/events/ClientEvents.java +++ b/src/main/java/com/simibubi/create/events/ClientEvents.java @@ -144,7 +144,7 @@ public class ClientEvents { if (world.isRemote() && world instanceof ClientWorld && !(world instanceof WrappedClientWorld)) { CreateClient.invalidateRenderers(world); AnimationTickHolder.reset(); - BasicInstancedTileRenderer renderer = CreateClient.kineticRenderer.get(world); + BasicInstancedTileRenderer renderer = Backend.tileRenderer.get(world); renderer.invalidate(); ((ClientWorld) world).loadedTileEntityList.forEach(renderer::add); } diff --git a/src/main/java/com/simibubi/create/foundation/mixin/LightUpdateMixin.java b/src/main/java/com/simibubi/create/foundation/mixin/LightUpdateMixin.java index 4b8e08f41..1d1c99757 100644 --- a/src/main/java/com/simibubi/create/foundation/mixin/LightUpdateMixin.java +++ b/src/main/java/com/simibubi/create/foundation/mixin/LightUpdateMixin.java @@ -7,8 +7,8 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import com.jozufozu.flywheel.backend.Backend; import com.jozufozu.flywheel.backend.light.LightUpdater; -import com.simibubi.create.CreateClient; import net.minecraft.client.multiplayer.ClientChunkProvider; import net.minecraft.client.world.ClientWorld; @@ -46,8 +46,8 @@ public abstract class LightUpdateMixin extends AbstractChunkProvider { .getY()) == sectionY) .map(Map.Entry::getValue) .forEach(tile -> { - CreateClient.kineticRenderer.get(world) - .onLightUpdate(tile); + Backend.tileRenderer.get(world) + .onLightUpdate(tile); }); } diff --git a/src/main/java/com/simibubi/create/foundation/mixin/NetworkLightUpdateMixin.java b/src/main/java/com/simibubi/create/foundation/mixin/NetworkLightUpdateMixin.java index effe19da5..4b1d899a8 100644 --- a/src/main/java/com/simibubi/create/foundation/mixin/NetworkLightUpdateMixin.java +++ b/src/main/java/com/simibubi/create/foundation/mixin/NetworkLightUpdateMixin.java @@ -5,9 +5,9 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import com.jozufozu.flywheel.backend.Backend; import com.jozufozu.flywheel.backend.RenderWork; import com.jozufozu.flywheel.backend.light.LightUpdater; -import com.simibubi.create.CreateClient; import net.minecraft.client.Minecraft; import net.minecraft.client.network.play.ClientPlayNetHandler; @@ -36,8 +36,8 @@ public class NetworkLightUpdateMixin { chunk.getTileEntityMap() .values() .forEach(tile -> { - CreateClient.kineticRenderer.get(world) - .onLightUpdate(tile); + Backend.tileRenderer.get(world) + .onLightUpdate(tile); }); } diff --git a/src/main/java/com/simibubi/create/foundation/mixin/RenderHooksMixin.java b/src/main/java/com/simibubi/create/foundation/mixin/RenderHooksMixin.java index 0f44aefa3..203ea1b8a 100644 --- a/src/main/java/com/simibubi/create/foundation/mixin/RenderHooksMixin.java +++ b/src/main/java/com/simibubi/create/foundation/mixin/RenderHooksMixin.java @@ -9,11 +9,8 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import com.jozufozu.flywheel.backend.Backend; import com.jozufozu.flywheel.backend.OptifineHandler; -import com.jozufozu.flywheel.backend.core.BasicInstancedTileRenderer; import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.platform.GlStateManager; -import com.simibubi.create.CreateClient; -import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionRenderDispatcher; import net.minecraft.block.BlockState; import net.minecraft.client.renderer.ActiveRenderInfo; @@ -24,7 +21,6 @@ import net.minecraft.client.renderer.WorldRenderer; import net.minecraft.client.world.ClientWorld; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.vector.Matrix4f; -import net.minecraft.util.math.vector.Vector3d; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; @@ -35,6 +31,13 @@ public class RenderHooksMixin { @Shadow private ClientWorld world; + @Inject(at = @At(value = "INVOKE", target = "net.minecraft.client.renderer.WorldRenderer.updateChunks(J)V"), method = "render") + private void setupFrame(MatrixStack stack, float p_228426_2_, long p_228426_3_, boolean p_228426_5_, + ActiveRenderInfo info, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f p_228426_9_, + CallbackInfo ci) { + Backend.listeners.setupFrame(world, stack, info, gameRenderer, lightTexture); + } + /** * JUSTIFICATION: This method is called once per layer per frame. It allows us to perform * layer-correct custom rendering. RenderWorldLast is not refined enough for rendering world objects. @@ -42,36 +45,29 @@ public class RenderHooksMixin { */ @Inject(at = @At("TAIL"), method = "renderLayer") private void renderLayer(RenderType type, MatrixStack stack, double camX, double camY, double camZ, - CallbackInfo ci) { + CallbackInfo ci) { if (!Backend.available()) return; Matrix4f view = stack.peek() .getModel(); Matrix4f viewProjection = view.copy(); - viewProjection.multiplyBackward(Backend.projectionMatrix); - - Backend.renderLayer(type, viewProjection, camX, camY, camZ); - - ContraptionRenderDispatcher.renderLayer(type, viewProjection, camX, camY, camZ); + viewProjection.multiplyBackward(Backend.getProjectionMatrix()); + Backend.listeners.renderLayer(world, type, viewProjection, camX, camY, camZ); GL20.glUseProgram(0); } - @Inject(at = @At(value = "INVOKE", target = "net.minecraft.client.renderer.WorldRenderer.updateChunks(J)V"), method = "render") - private void setupFrame(MatrixStack p_228426_1_, float p_228426_2_, long p_228426_3_, boolean p_228426_5_, - ActiveRenderInfo info, GameRenderer p_228426_7_, LightTexture p_228426_8_, Matrix4f p_228426_9_, - CallbackInfo ci) { - Vector3d cameraPos = info.getProjectedView(); - double camX = cameraPos.getX(); - double camY = cameraPos.getY(); - double camZ = cameraPos.getZ(); + @Inject(at = @At("TAIL"), method = "loadRenderers") + private void refresh(CallbackInfo ci) { + OptifineHandler.refresh(); + Backend.refresh(); - CreateClient.kineticRenderer.get(world) - .beginFrame(info, camX, camY, camZ); - ContraptionRenderDispatcher.beginFrame(info, camX, camY, camZ); + Backend.listeners.refresh(world); } + // Effects system + @Inject(method = "render", at = @At(value = "INVOKE", ordinal = 1, target = "Lnet/minecraft/client/shader/ShaderGroup;render(F)V")) private void disableTransparencyShaderDepth(MatrixStack p_228426_1_, float p_228426_2_, long p_228426_3_, boolean p_228426_5_, ActiveRenderInfo p_228426_6_, GameRenderer p_228426_7_, LightTexture p_228426_8_, Matrix4f p_228426_9_, CallbackInfo ci) { GlStateManager.depthMask(false); @@ -82,22 +78,11 @@ public class RenderHooksMixin { Backend.effects.render(stack.peek().getModel()); } + // Instancing + @Inject(at = @At("TAIL"), method = "scheduleBlockRerenderIfNeeded") private void checkUpdate(BlockPos pos, BlockState lastState, BlockState newState, CallbackInfo ci) { - CreateClient.kineticRenderer.get(world) + Backend.tileRenderer.get(world) .update(world.getTileEntity(pos)); } - - @Inject(at = @At("TAIL"), method = "loadRenderers") - private void refresh(CallbackInfo ci) { - ContraptionRenderDispatcher.invalidateAll(); - OptifineHandler.refresh(); - Backend.refresh(); - - if (Backend.canUseInstancing() && world != null) { - BasicInstancedTileRenderer kineticRenderer = CreateClient.kineticRenderer.get(world); - kineticRenderer.invalidate(); - world.loadedTileEntityList.forEach(kineticRenderer::add); - } - } } diff --git a/src/main/java/com/simibubi/create/foundation/mixin/StoreProjectionMatrixMixin.java b/src/main/java/com/simibubi/create/foundation/mixin/StoreProjectionMatrixMixin.java index 822e05bd8..eef158e20 100644 --- a/src/main/java/com/simibubi/create/foundation/mixin/StoreProjectionMatrixMixin.java +++ b/src/main/java/com/simibubi/create/foundation/mixin/StoreProjectionMatrixMixin.java @@ -52,7 +52,7 @@ public abstract class StoreProjectionMatrixMixin { @Inject(method = "loadProjectionMatrix", at = @At("TAIL")) private void onProjectionMatrixLoad(Matrix4f projection, CallbackInfo ci) { if (shouldCopy) { - Backend.projectionMatrix = projection.copy(); + Backend.setProjectionMatrix(projection.copy()); shouldCopy = false; } } diff --git a/src/main/java/com/simibubi/create/foundation/mixin/TileRemoveMixin.java b/src/main/java/com/simibubi/create/foundation/mixin/TileRemoveMixin.java index b2907a127..4de24590a 100644 --- a/src/main/java/com/simibubi/create/foundation/mixin/TileRemoveMixin.java +++ b/src/main/java/com/simibubi/create/foundation/mixin/TileRemoveMixin.java @@ -8,7 +8,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import com.simibubi.create.CreateClient; +import com.jozufozu.flywheel.backend.Backend; import net.minecraft.client.world.ClientWorld; import net.minecraft.tileentity.TileEntity; @@ -24,7 +24,7 @@ public class TileRemoveMixin { @Inject(at = @At("TAIL"), method = "remove") private void onRemove(CallbackInfo ci) { if (world instanceof ClientWorld) - CreateClient.kineticRenderer.get(this.world) - .remove((TileEntity) (Object) this); + Backend.tileRenderer.get(this.world) + .remove((TileEntity) (Object) this); } } diff --git a/src/main/java/com/simibubi/create/foundation/mixin/TileWorldHookMixin.java b/src/main/java/com/simibubi/create/foundation/mixin/TileWorldHookMixin.java index 77b504956..59427ef6c 100644 --- a/src/main/java/com/simibubi/create/foundation/mixin/TileWorldHookMixin.java +++ b/src/main/java/com/simibubi/create/foundation/mixin/TileWorldHookMixin.java @@ -10,8 +10,8 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import com.jozufozu.flywheel.backend.Backend; import com.jozufozu.flywheel.backend.core.BasicInstancedTileRenderer; -import com.simibubi.create.CreateClient; import net.minecraft.tileentity.TileEntity; import net.minecraft.world.World; @@ -35,8 +35,8 @@ public class TileWorldHookMixin { @Inject(at = @At("TAIL"), method = "addTileEntity") private void onAddTile(TileEntity te, CallbackInfoReturnable cir) { if (isRemote) { - CreateClient.kineticRenderer.get(self) - .queueAdd(te); + Backend.tileRenderer.get(self) + .queueAdd(te); } } @@ -46,7 +46,7 @@ public class TileWorldHookMixin { @Inject(at = @At(value = "INVOKE", target = "Ljava/util/Set;clear()V", ordinal = 0), method = "tickBlockEntities") private void onChunkUnload(CallbackInfo ci) { if (isRemote) { - BasicInstancedTileRenderer kineticRenderer = CreateClient.kineticRenderer.get(self); + BasicInstancedTileRenderer kineticRenderer = Backend.tileRenderer.get(self); for (TileEntity tile : tileEntitiesToBeRemoved) { kineticRenderer.remove(tile); } diff --git a/src/main/resources/assets/create/flywheel/shaders/contraption/builtin.frag b/src/main/resources/assets/create/flywheel/shaders/contraption/builtin.frag index 09918fb48..ac2690e87 100644 --- a/src/main/resources/assets/create/flywheel/shaders/contraption/builtin.frag +++ b/src/main/resources/assets/create/flywheel/shaders/contraption/builtin.frag @@ -3,7 +3,7 @@ varying vec3 BoxCoord; uniform sampler3D uLightVolume; -void FLWFinalizeColor(vec4 color) { +void FLWFinalizeColor(inout vec4 color) { #if defined(USE_FOG) float a = color.a; float fog = clamp(FLWFogFactor(), 0., 1.); diff --git a/src/main/resources/assets/create/flywheel/shaders/std/builtin.frag b/src/main/resources/assets/create/flywheel/shaders/std/builtin.frag index e89cfaf00..4e08fae38 100644 --- a/src/main/resources/assets/create/flywheel/shaders/std/builtin.frag +++ b/src/main/resources/assets/create/flywheel/shaders/std/builtin.frag @@ -1,6 +1,6 @@ #flwinclude <"create:std/fog.glsl"> -void FLWFinalizeColor(vec4 color) { +void FLWFinalizeColor(inout vec4 color) { #if defined(USE_FOG) float a = color.a; float fog = clamp(FLWFogFactor(), 0., 1.); diff --git a/src/main/resources/assets/create/flywheel/shaders/std/fog.glsl b/src/main/resources/assets/create/flywheel/shaders/std/fog.glsl index 09cc7af18..75a68d176 100644 --- a/src/main/resources/assets/create/flywheel/shaders/std/fog.glsl +++ b/src/main/resources/assets/create/flywheel/shaders/std/fog.glsl @@ -9,15 +9,13 @@ uniform vec2 uFogRange; float FLWFogFactor() { return (uFogRange.y - FragDistance) / (uFogRange.y - uFogRange.x); } - #elif defined(USE_FOG_EXP2) + #endif + + #if defined(USE_FOG_EXP2) uniform float uFogDensity; float FLWFogFactor() { float dist = FragDistance * uFogDensity; return 1. / exp2(dist * dist); -} - #else -float FLWFogFactor() { - return 0.; } #endif