From 0bc6b11c5b9fbc8ce411d7c9176861bb53676676 Mon Sep 17 00:00:00 2001 From: JozsefA Date: Thu, 14 Jan 2021 13:59:26 -0800 Subject: [PATCH] be smart about rebuilding things not smart enough about contraptions yet things mostly render in the correct layers --- .../content/contraptions/KineticNetwork.java | 8 +- .../contraptions/base/KineticTileEntity.java | 20 +-- .../base/KineticTileEntityRenderer.java | 21 +++- .../clock/CuckooClockTileEntity.java | 11 +- .../crafter/MechanicalCrafterTileEntity.java | 23 ++-- .../components/crank/HandCrankTileEntity.java | 5 +- .../components/deployer/DeployerRenderer.java | 25 ++-- .../deployer/DeployerTileEntity.java | 23 ++-- .../components/fan/EncasedFanRenderer.java | 20 ++- .../flywheel/FlywheelTileEntity.java | 5 +- .../mixer/MechanicalMixerRenderer.java | 13 +- .../components/saw/SawRenderer.java | 21 +++- .../components/saw/SawTileEntity.java | 28 ++--- .../contraptions/fluids/PumpTileEntity.java | 29 ++--- .../fluids/actors/HosePulleyTileEntity.java | 9 +- .../processing/BasinOperatingTileEntity.java | 13 +- .../advanced/SpeedControllerRenderer.java | 13 +- .../relays/belt/BeltRenderer.java | 90 +++++++++++-- .../relays/belt/BeltTileEntity.java | 35 +++--- .../relays/encased/SplitShaftRenderer.java | 19 ++- .../relays/gauge/GaugeTileEntity.java | 9 +- .../relays/gearbox/GearboxRenderer.java | 47 +++++-- .../block/mechanicalArm/ArmTileEntity.java | 14 ++- .../simibubi/create/events/ClientEvents.java | 20 +-- .../mixin/CancelTileEntityRenderMixin.java | 44 +++++++ .../foundation/mixin/LightUpdateMixin.java | 20 ++- .../foundation/mixin/OnRemoveTileMixin.java | 28 +++++ .../foundation/mixin/RenderInLayerMixin.java | 16 ++- .../render/FastContraptionRenderer.java | 57 +++++---- .../render/FastKineticRenderer.java | 51 +++----- .../render/FastRenderDispatcher.java | 118 ++++++++++++++++++ .../render/TileEntityRenderHelper.java | 8 +- .../render/instancing/IInstanceRendered.java | 3 + .../IInstancedTileEntityRenderer.java | 4 +- .../render/instancing/InstanceBuffer.java | 5 +- .../resources/META-INF/accesstransformer.cfg | 7 +- .../assets/create/shader/contraption.frag | 2 +- .../assets/create/shader/instanced.frag | 2 +- src/main/resources/create.mixins.json | 5 +- 39 files changed, 618 insertions(+), 273 deletions(-) create mode 100644 src/main/java/com/simibubi/create/foundation/mixin/CancelTileEntityRenderMixin.java create mode 100644 src/main/java/com/simibubi/create/foundation/mixin/OnRemoveTileMixin.java create mode 100644 src/main/java/com/simibubi/create/foundation/render/FastRenderDispatcher.java diff --git a/src/main/java/com/simibubi/create/content/contraptions/KineticNetwork.java b/src/main/java/com/simibubi/create/content/contraptions/KineticNetwork.java index bbbe8e585..60ca8abb3 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/KineticNetwork.java +++ b/src/main/java/com/simibubi/create/content/contraptions/KineticNetwork.java @@ -1,13 +1,13 @@ package com.simibubi.create.content.contraptions; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.components.flywheel.FlywheelTileEntity; import com.simibubi.create.foundation.advancement.AllTriggers; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + public class KineticNetwork { public Long id; diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntity.java index f4271e366..90b76469d 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntity.java @@ -1,12 +1,5 @@ package com.simibubi.create.content.contraptions.base; -import static net.minecraft.util.text.TextFormatting.GOLD; -import static net.minecraft.util.text.TextFormatting.GRAY; - -import java.util.List; - -import javax.annotation.Nullable; - import com.simibubi.create.Create; import com.simibubi.create.content.contraptions.KineticNetwork; import com.simibubi.create.content.contraptions.RotationPropagator; @@ -17,11 +10,11 @@ import com.simibubi.create.content.contraptions.goggles.IHaveHoveringInformation import com.simibubi.create.foundation.advancement.AllTriggers; import com.simibubi.create.foundation.config.AllConfigs; import com.simibubi.create.foundation.item.TooltipHelper; +import com.simibubi.create.foundation.render.FastRenderDispatcher; +import com.simibubi.create.foundation.render.instancing.IInstanceRendered; import com.simibubi.create.foundation.tileEntity.SmartTileEntity; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; import com.simibubi.create.foundation.utility.Lang; - -import com.simibubi.create.foundation.render.instancing.IInstanceRendered; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.client.resources.I18n; @@ -37,6 +30,12 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.text.TextFormatting; import net.minecraft.world.World; +import javax.annotation.Nullable; +import java.util.List; + +import static net.minecraft.util.text.TextFormatting.GOLD; +import static net.minecraft.util.text.TextFormatting.GRAY; + public abstract class KineticTileEntity extends SmartTileEntity implements ITickableTileEntity, IHaveGoggleInformation, IHaveHoveringInformation, IInstanceRendered { @@ -245,6 +244,9 @@ public abstract class KineticTileEntity extends SmartTileEntity if (clientPacket && overStressedBefore != overStressed && speed != 0) effects.triggerOverStressedEffect(); + + if (clientPacket) + FastRenderDispatcher.markForRebuild(this); } public float getGeneratedSpeed() { diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntityRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntityRenderer.java index 0b2eee618..c064f762e 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntityRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntityRenderer.java @@ -4,13 +4,15 @@ import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.AllBlocks; import com.simibubi.create.content.contraptions.KineticDebugger; import com.simibubi.create.content.contraptions.relays.elementary.CogWheelBlock; +import com.simibubi.create.foundation.render.SuperByteBuffer; +import com.simibubi.create.foundation.render.SuperByteBufferCache.Compartment; +import com.simibubi.create.foundation.render.instancing.IInstancedTileEntityRenderer; +import com.simibubi.create.foundation.render.instancing.InstanceBuffer; +import com.simibubi.create.foundation.render.instancing.InstanceContext; +import com.simibubi.create.foundation.render.instancing.RotatingData; import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer; import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.ColorHelper; -import com.simibubi.create.foundation.render.instancing.*; -import com.simibubi.create.foundation.render.SuperByteBuffer; -import com.simibubi.create.foundation.render.SuperByteBufferCache.Compartment; - import net.minecraft.block.BlockState; import net.minecraft.client.renderer.IRenderTypeBuffer; import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher; @@ -45,7 +47,7 @@ public class KineticTileEntityRenderer extends SafeTileEntityRenderer(te)); +// addInstanceData(new InstanceContext.World<>(te)); } @Override @@ -53,11 +55,20 @@ public class KineticTileEntityRenderer extends SafeTileEntityRenderer ctx) { + getRotatedModel(ctx).clearInstanceData(); + } + public static void renderRotatingKineticBlock(InstanceContext ctx, BlockState renderedState) { InstanceBuffer instancedRenderer = ctx.getKinetics().renderBlockInstanced(KINETIC_TILE, renderedState); renderRotatingBuffer(ctx, instancedRenderer); } + public static void markForRebuild(InstanceContext ctx, BlockState renderedState) { + ctx.getKinetics().renderBlockInstanced(KINETIC_TILE, renderedState).clearInstanceData(); + } + public static void renderRotatingBuffer(InstanceContext ctx, InstanceBuffer instancer) { instancer.setupInstance(data -> { T te = ctx.te; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/clock/CuckooClockTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/clock/CuckooClockTileEntity.java index dad7b19ce..2d0a4c1ec 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/clock/CuckooClockTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/clock/CuckooClockTileEntity.java @@ -1,9 +1,5 @@ package com.simibubi.create.content.contraptions.components.clock; -import static com.simibubi.create.foundation.utility.AngleHelper.deg; -import static com.simibubi.create.foundation.utility.AngleHelper.getShortestAngleDiff; -import static com.simibubi.create.foundation.utility.AngleHelper.rad; - import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.foundation.advancement.AllTriggers; import com.simibubi.create.foundation.gui.widgets.InterpolatedChasingValue; @@ -11,7 +7,6 @@ import com.simibubi.create.foundation.gui.widgets.InterpolatedValue; import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.NBTHelper; import com.simibubi.create.foundation.utility.VecHelper; - import net.minecraft.nbt.CompoundNBT; import net.minecraft.particles.ParticleTypes; import net.minecraft.tileentity.TileEntityType; @@ -22,6 +17,8 @@ import net.minecraft.util.SoundEvents; import net.minecraft.util.math.Vec3d; import net.minecraft.world.Explosion; +import static com.simibubi.create.foundation.utility.AngleHelper.*; + public class CuckooClockTileEntity extends KineticTileEntity { public static DamageSource CUCKOO_SURPRISE = new DamageSource("create.cuckoo_clock_explosion").setExplosion(); @@ -172,4 +169,8 @@ public class CuckooClockTileEntity extends KineticTileEntity { world.playSound(vec.x, vec.y, vec.z, sound, SoundCategory.BLOCKS, volume, pitch, false); } + @Override + public boolean shouldRenderAsTE() { + return true; + } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/crafter/MechanicalCrafterTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/crafter/MechanicalCrafterTileEntity.java index 457611032..67dee0db5 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/crafter/MechanicalCrafterTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/crafter/MechanicalCrafterTileEntity.java @@ -1,14 +1,5 @@ package com.simibubi.create.content.contraptions.components.crafter; -import static com.simibubi.create.content.contraptions.base.HorizontalKineticBlock.HORIZONTAL_FACING; - -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; -import java.util.Map.Entry; - -import org.apache.commons.lang3.tuple.Pair; - import com.simibubi.create.AllBlocks; import com.simibubi.create.AllItems; import com.simibubi.create.content.contraptions.base.KineticTileEntity; @@ -22,7 +13,6 @@ import com.simibubi.create.foundation.tileEntity.behaviour.inventory.InvManipula import com.simibubi.create.foundation.utility.BlockFace; import com.simibubi.create.foundation.utility.Pointing; import com.simibubi.create.foundation.utility.VecHelper; - import net.minecraft.block.BlockState; import net.minecraft.entity.item.ItemEntity; import net.minecraft.item.ItemStack; @@ -39,6 +29,14 @@ import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; +import org.apache.commons.lang3.tuple.Pair; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Map.Entry; + +import static com.simibubi.create.content.contraptions.base.HorizontalKineticBlock.HORIZONTAL_FACING; public class MechanicalCrafterTileEntity extends KineticTileEntity { @@ -490,4 +488,9 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { return inventory; } + @Override + public boolean shouldRenderAsTE() { + return true; + } + } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/crank/HandCrankTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/crank/HandCrankTileEntity.java index d861d3cac..2a7b0a1d1 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/crank/HandCrankTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/crank/HandCrankTileEntity.java @@ -2,7 +2,6 @@ package com.simibubi.create.content.contraptions.components.crank; import com.simibubi.create.AllBlocks; import com.simibubi.create.content.contraptions.base.GeneratingKineticTileEntity; - import net.minecraft.block.Block; import net.minecraft.nbt.CompoundNBT; import net.minecraft.tileentity.TileEntityType; @@ -73,4 +72,8 @@ public class HandCrankTileEntity extends GeneratingKineticTileEntity { return AllBlocks.HAND_CRANK.get(); } + @Override + public boolean shouldRenderAsTE() { + return true; + } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerRenderer.java index 3525f6c3c..a95b8ccbc 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerRenderer.java @@ -1,8 +1,5 @@ package com.simibubi.create.content.contraptions.components.deployer; -import static com.simibubi.create.content.contraptions.base.DirectionalAxisKineticBlock.AXIS_ALONG_FIRST_COORDINATE; -import static com.simibubi.create.content.contraptions.base.DirectionalKineticBlock.FACING; - import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.vertex.IVertexBuilder; import com.simibubi.create.AllBlockPartials; @@ -11,24 +8,18 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer; import com.simibubi.create.content.contraptions.components.deployer.DeployerTileEntity.Mode; import com.simibubi.create.content.contraptions.components.deployer.DeployerTileEntity.State; import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext; +import com.simibubi.create.foundation.render.SuperByteBuffer; +import com.simibubi.create.foundation.render.instancing.IInstancedTileEntityRenderer; +import com.simibubi.create.foundation.render.instancing.InstanceContext; import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringRenderer; import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer; import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.NBTHelper; -import com.simibubi.create.foundation.render.SuperByteBuffer; import com.simibubi.create.foundation.utility.VecHelper; - -import com.simibubi.create.foundation.render.instancing.IInstancedTileEntityRenderer; -import com.simibubi.create.foundation.render.instancing.InstanceContext; import net.minecraft.block.BlockState; import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.IRenderTypeBuffer; -import net.minecraft.client.renderer.ItemRenderer; -import net.minecraft.client.renderer.Matrix4f; -import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.Vector3f; -import net.minecraft.client.renderer.WorldRenderer; +import net.minecraft.client.renderer.*; import net.minecraft.client.renderer.model.ItemCameraTransforms.TransformType; import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher; import net.minecraft.item.BlockItem; @@ -39,6 +30,9 @@ import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; +import static com.simibubi.create.content.contraptions.base.DirectionalAxisKineticBlock.AXIS_ALONG_FIRST_COORDINATE; +import static com.simibubi.create.content.contraptions.base.DirectionalKineticBlock.FACING; + public class DeployerRenderer extends SafeTileEntityRenderer implements IInstancedTileEntityRenderer { public DeployerRenderer(TileEntityRendererDispatcher dispatcher) { @@ -59,6 +53,11 @@ public class DeployerRenderer extends SafeTileEntityRenderer KineticTileEntityRenderer.renderRotatingKineticBlock(ctx, getRenderedBlockState(ctx.te)); } + @Override + public void markForRebuild(InstanceContext ctx) { + KineticTileEntityRenderer.markForRebuild(ctx, getRenderedBlockState(ctx.te)); + } + protected void renderItem(DeployerTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay) { BlockState deployerState = te.getBlockState(); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerTileEntity.java index 65beab8e3..d0d0ea8cf 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerTileEntity.java @@ -1,10 +1,5 @@ package com.simibubi.create.content.contraptions.components.deployer; -import static com.simibubi.create.content.contraptions.base.DirectionalKineticBlock.FACING; - -import java.util.ArrayList; -import java.util.List; - import com.simibubi.create.AllBlockPartials; import com.simibubi.create.AllBlocks; import com.simibubi.create.content.contraptions.base.KineticTileEntity; @@ -15,7 +10,6 @@ import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour; import com.simibubi.create.foundation.utility.NBTHelper; import com.simibubi.create.foundation.utility.VecHelper; - import net.minecraft.entity.player.ServerPlayerEntity; import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundNBT; @@ -24,20 +18,20 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.Direction; import net.minecraft.util.Hand; -import net.minecraft.util.math.AxisAlignedBB; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.BlockRayTraceResult; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.RayTraceContext; +import net.minecraft.util.math.*; import net.minecraft.util.math.RayTraceContext.BlockMode; import net.minecraft.util.math.RayTraceContext.FluidMode; -import net.minecraft.util.math.Vec3d; import net.minecraft.world.server.ServerWorld; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.util.Constants.NBT; import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.items.IItemHandlerModifiable; +import java.util.ArrayList; +import java.util.List; + +import static com.simibubi.create.content.contraptions.base.DirectionalKineticBlock.FACING; + public class DeployerTileEntity extends KineticTileEntity { protected State state; @@ -383,4 +377,9 @@ public class DeployerTileEntity extends KineticTileEntity { return true; } + @Override + public boolean shouldRenderAsTE() { + return true; + } + } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanRenderer.java index 5ab2bbd49..4fbce8fb9 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanRenderer.java @@ -1,13 +1,10 @@ package com.simibubi.create.content.contraptions.components.fan; -import static net.minecraft.state.properties.BlockStateProperties.FACING; - import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.AllBlockPartials; import com.simibubi.create.content.contraptions.base.IRotate; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer; - import com.simibubi.create.foundation.render.instancing.InstanceBuffer; import com.simibubi.create.foundation.render.instancing.InstanceContext; import com.simibubi.create.foundation.render.instancing.RotatingData; @@ -18,6 +15,8 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.world.LightType; +import static net.minecraft.state.properties.BlockStateProperties.FACING; + public class EncasedFanRenderer extends KineticTileEntityRenderer { public EncasedFanRenderer(TileEntityRendererDispatcher dispatcher) { @@ -85,4 +84,19 @@ public class EncasedFanRenderer extends KineticTileEntityRenderer { } }); } + + @Override + public void markForRebuild(InstanceContext ctx) { + KineticTileEntity te = ctx.te; + Direction direction = te.getBlockState() + .get(FACING); + + InstanceBuffer shaftHalf = + AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(ctx, te.getBlockState(), direction.getOpposite()); + InstanceBuffer fanInner = + AllBlockPartials.ENCASED_FAN_INNER.renderOnDirectionalSouthRotating(ctx, te.getBlockState(), direction.getOpposite()); + + shaftHalf.clearInstanceData(); + fanInner.clearInstanceData(); + } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlywheelTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlywheelTileEntity.java index 05283aebd..b55c81d63 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlywheelTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlywheelTileEntity.java @@ -2,7 +2,6 @@ package com.simibubi.create.content.contraptions.components.flywheel; import com.simibubi.create.content.contraptions.base.GeneratingKineticTileEntity; import com.simibubi.create.foundation.gui.widgets.InterpolatedChasingValue; - import net.minecraft.nbt.CompoundNBT; import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.math.AxisAlignedBB; @@ -101,4 +100,8 @@ public class FlywheelTileEntity extends GeneratingKineticTileEntity { } } + @Override + public boolean shouldRenderAsTE() { + return true; + } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/mixer/MechanicalMixerRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/mixer/MechanicalMixerRenderer.java index 04231f98d..2ab2d8e75 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/mixer/MechanicalMixerRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/mixer/MechanicalMixerRenderer.java @@ -5,9 +5,11 @@ import com.mojang.blaze3d.vertex.IVertexBuilder; import com.simibubi.create.AllBlockPartials; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer; -import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.render.SuperByteBuffer; - +import com.simibubi.create.foundation.render.instancing.InstanceBuffer; +import com.simibubi.create.foundation.render.instancing.InstanceContext; +import com.simibubi.create.foundation.render.instancing.RotatingData; +import com.simibubi.create.foundation.utility.AnimationTickHolder; import net.minecraft.block.BlockState; import net.minecraft.client.renderer.IRenderTypeBuffer; import net.minecraft.client.renderer.RenderType; @@ -31,9 +33,6 @@ public class MechanicalMixerRenderer extends KineticTileEntityRenderer { IVertexBuilder vb = buffer.getBuffer(RenderType.getSolid()); - SuperByteBuffer superBuffer = AllBlockPartials.SHAFTLESS_COGWHEEL.renderOn(blockState); - standardKineticRotationTransform(superBuffer, te, light).renderInto(ms, vb); - int packedLightmapCoords = WorldRenderer.getLightmapCoordinates(te.getWorld(), blockState, pos); float renderedHeadOffset = mixer.getRenderedHeadOffset(partialTicks); float speed = mixer.getRenderedHeadRotationSpeed(partialTicks); @@ -52,4 +51,8 @@ public class MechanicalMixerRenderer extends KineticTileEntityRenderer { .renderInto(ms, vb); } + @Override + protected InstanceBuffer getRotatedModel(InstanceContext ctx) { + return AllBlockPartials.SHAFTLESS_COGWHEEL.renderOnRotating(ctx, ctx.te.getBlockState()); + } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/saw/SawRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/saw/SawRenderer.java index 2bd9b9a10..75536539d 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/saw/SawRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/saw/SawRenderer.java @@ -1,18 +1,20 @@ package com.simibubi.create.content.contraptions.components.saw; -import static net.minecraft.state.properties.BlockStateProperties.FACING; - import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.AllBlockPartials; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer; import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext; +import com.simibubi.create.foundation.render.SuperByteBuffer; +import com.simibubi.create.foundation.render.instancing.IInstancedTileEntityRenderer; +import com.simibubi.create.foundation.render.instancing.InstanceBuffer; +import com.simibubi.create.foundation.render.instancing.InstanceContext; +import com.simibubi.create.foundation.render.instancing.RotatingData; import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringRenderer; import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer; -import com.simibubi.create.foundation.utility.*; - -import com.simibubi.create.foundation.render.instancing.*; -import com.simibubi.create.foundation.render.SuperByteBuffer; +import com.simibubi.create.foundation.utility.AngleHelper; +import com.simibubi.create.foundation.utility.MatrixStacker; +import com.simibubi.create.foundation.utility.VecHelper; import net.minecraft.block.BlockState; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.IRenderTypeBuffer; @@ -28,6 +30,8 @@ import net.minecraft.util.Rotation; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; +import static net.minecraft.state.properties.BlockStateProperties.FACING; + public class SawRenderer extends SafeTileEntityRenderer implements IInstancedTileEntityRenderer { public SawRenderer(TileEntityRendererDispatcher dispatcher) { @@ -48,6 +52,11 @@ public class SawRenderer extends SafeTileEntityRenderer implement KineticTileEntityRenderer.renderRotatingBuffer(ctx, getRotatedModel(ctx)); } + @Override + public void markForRebuild(InstanceContext ctx) { + getRotatedModel(ctx).clearInstanceData(); + } + protected void renderBlade(SawTileEntity te, MatrixStack ms, IRenderTypeBuffer buffer, int light){ BlockState blockState = te.getBlockState(); SuperByteBuffer superBuffer; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/saw/SawTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/saw/SawTileEntity.java index 64a448598..2cf10642d 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/saw/SawTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/saw/SawTileEntity.java @@ -1,11 +1,5 @@ package com.simibubi.create.content.contraptions.components.saw; -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; -import java.util.Random; -import java.util.stream.Collectors; - import com.google.common.base.Predicate; import com.simibubi.create.AllRecipeTypes; import com.simibubi.create.content.contraptions.components.actors.BlockBreakingKineticTileEntity; @@ -21,16 +15,7 @@ import com.simibubi.create.foundation.utility.TreeCutter.Tree; import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.recipe.RecipeConditions; import com.simibubi.create.foundation.utility.recipe.RecipeFinder; - -import net.minecraft.block.BambooBlock; -import net.minecraft.block.Block; -import net.minecraft.block.BlockState; -import net.minecraft.block.CactusBlock; -import net.minecraft.block.ChorusPlantBlock; -import net.minecraft.block.KelpBlock; -import net.minecraft.block.KelpTopBlock; -import net.minecraft.block.StemGrownBlock; -import net.minecraft.block.SugarCaneBlock; +import net.minecraft.block.*; import net.minecraft.entity.item.ItemEntity; import net.minecraft.item.BlockItem; import net.minecraft.item.ItemStack; @@ -53,6 +38,12 @@ import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Random; +import java.util.stream.Collectors; + public class SawTileEntity extends BlockBreakingKineticTileEntity { private static final Object cuttingRecipesKey = new Object(); @@ -393,4 +384,9 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity { return false; } + @Override + public boolean shouldRenderAsTE() { + return true; + } + } diff --git a/src/main/java/com/simibubi/create/content/contraptions/fluids/PumpTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/fluids/PumpTileEntity.java index 901059d71..ff0bad252 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/fluids/PumpTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/fluids/PumpTileEntity.java @@ -1,28 +1,10 @@ package com.simibubi.create.content.contraptions.fluids; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.IdentityHashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import javax.annotation.Nullable; - -import org.apache.commons.lang3.mutable.MutableBoolean; - import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.foundation.tileEntity.SmartTileEntity; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; -import com.simibubi.create.foundation.utility.BlockFace; -import com.simibubi.create.foundation.utility.Couple; -import com.simibubi.create.foundation.utility.Iterate; -import com.simibubi.create.foundation.utility.LerpedFloat; +import com.simibubi.create.foundation.utility.*; import com.simibubi.create.foundation.utility.LerpedFloat.Chaser; -import com.simibubi.create.foundation.utility.Pair; - import net.minecraft.block.BlockState; import net.minecraft.nbt.CompoundNBT; import net.minecraft.tileentity.TileEntity; @@ -34,6 +16,11 @@ import net.minecraft.world.IWorld; import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.fluids.capability.CapabilityFluidHandler; import net.minecraftforge.fluids.capability.IFluidHandler; +import org.apache.commons.lang3.mutable.MutableBoolean; + +import javax.annotation.Nullable; +import java.util.*; +import java.util.Map.Entry; public class PumpTileEntity extends KineticTileEntity { @@ -374,4 +361,8 @@ public class PumpTileEntity extends KineticTileEntity { } + @Override + public boolean shouldRenderAsTE() { + return true; + } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/fluids/actors/HosePulleyTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/fluids/actors/HosePulleyTileEntity.java index 436b111f9..698f36e3f 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/fluids/actors/HosePulleyTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/fluids/actors/HosePulleyTileEntity.java @@ -1,14 +1,11 @@ package com.simibubi.create.content.contraptions.fluids.actors; -import java.util.List; - import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.foundation.fluid.SmartFluidTank; import com.simibubi.create.foundation.item.TooltipHelper; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; import com.simibubi.create.foundation.utility.LerpedFloat; import com.simibubi.create.foundation.utility.ServerSpeedProvider; - import net.minecraft.nbt.CompoundNBT; import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.Direction; @@ -20,6 +17,8 @@ import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.capability.IFluidHandler; +import java.util.List; + public class HosePulleyTileEntity extends KineticTileEntity { LerpedFloat offset; @@ -191,4 +190,8 @@ public class HosePulleyTileEntity extends KineticTileEntity { return super.getCapability(cap, side); } + @Override + public boolean shouldRenderAsTE() { + return true; + } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/processing/BasinOperatingTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/processing/BasinOperatingTileEntity.java index 20383e4f4..7c711358f 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/processing/BasinOperatingTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/processing/BasinOperatingTileEntity.java @@ -1,21 +1,20 @@ package com.simibubi.create.content.contraptions.processing; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; - import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.foundation.advancement.AllTriggers; import com.simibubi.create.foundation.advancement.ITriggerable; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; import com.simibubi.create.foundation.tileEntity.behaviour.simple.DeferralBehaviour; import com.simibubi.create.foundation.utility.recipe.RecipeFinder; - import net.minecraft.inventory.IInventory; import net.minecraft.item.crafting.IRecipe; import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntityType; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + public abstract class BasinOperatingTileEntity extends KineticTileEntity { public DeferralBehaviour basinChecker; @@ -144,4 +143,8 @@ public abstract class BasinOperatingTileEntity extends KineticTileEntity { protected abstract Object getRecipeCacheKey(); + @Override + public boolean shouldRenderAsTE() { + return true; + } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/SpeedControllerRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/SpeedControllerRenderer.java index 65f440f1a..073a6a792 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/SpeedControllerRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/SpeedControllerRenderer.java @@ -2,9 +2,11 @@ package com.simibubi.create.content.contraptions.relays.advanced; import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer; +import com.simibubi.create.foundation.render.instancing.IInstancedTileEntityRenderer; +import com.simibubi.create.foundation.render.instancing.InstanceBuffer; +import com.simibubi.create.foundation.render.instancing.InstanceContext; +import com.simibubi.create.foundation.render.instancing.RotatingData; import com.simibubi.create.foundation.tileEntity.renderer.SmartTileEntityRenderer; - -import com.simibubi.create.foundation.render.instancing.*; import net.minecraft.client.renderer.IRenderTypeBuffer; import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher; @@ -18,7 +20,7 @@ public class SpeedControllerRenderer extends SmartTileEntityRenderer(tileEntityIn)); +// addInstanceData(new InstanceContext.World<>(tileEntityIn)); } @Override @@ -26,6 +28,11 @@ public class SpeedControllerRenderer extends SmartTileEntityRenderer ctx) { + getRotatedModel(ctx).clearInstanceData(); + } + private InstanceBuffer getRotatedModel(InstanceContext ctx) { return ctx.getKinetics().renderBlockInstanced(KineticTileEntityRenderer.KINETIC_TILE, KineticTileEntityRenderer.shaft(KineticTileEntityRenderer.getRotationAxisOf(ctx.te))); diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltRenderer.java index fe0388464..bc8628880 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltRenderer.java @@ -1,7 +1,5 @@ package com.simibubi.create.content.contraptions.relays.belt; -import java.util.Random; - import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.AllBlockPartials; import com.simibubi.create.AllBlocks; @@ -9,16 +7,17 @@ import com.simibubi.create.AllSpriteShifts; import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer; import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack; import com.simibubi.create.foundation.block.render.SpriteShiftEntry; +import com.simibubi.create.foundation.render.FastKineticRenderer; +import com.simibubi.create.foundation.render.ShadowRenderHelper; +import com.simibubi.create.foundation.render.instancing.*; import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer; import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.MatrixStacker; -import com.simibubi.create.foundation.render.FastKineticRenderer; -import com.simibubi.create.foundation.render.instancing.*; -import com.simibubi.create.foundation.render.ShadowRenderHelper; - import net.minecraft.block.BlockState; import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.*; +import net.minecraft.client.renderer.IRenderTypeBuffer; +import net.minecraft.client.renderer.ItemRenderer; +import net.minecraft.client.renderer.Vector3f; import net.minecraft.client.renderer.model.ItemCameraTransforms.TransformType; import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher; import net.minecraft.entity.Entity; @@ -30,6 +29,8 @@ import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3i; import net.minecraft.world.LightType; +import java.util.Random; + public class BeltRenderer extends SafeTileEntityRenderer implements IInstancedTileEntityRenderer { public BeltRenderer(TileEntityRendererDispatcher dispatcher) { @@ -49,7 +50,7 @@ public class BeltRenderer extends SafeTileEntityRenderer impleme if (!AllBlocks.BELT.has(blockState)) return; - addInstanceData(new InstanceContext.World<>(te)); +// addInstanceData(new InstanceContext.World<>(te)); renderItems(te, partialTicks, ms, buffer, light, overlay); } @@ -105,8 +106,11 @@ public class BeltRenderer extends SafeTileEntityRenderer impleme vertical) speed = -speed; + if (sideways && (facing == Direction.SOUTH || facing == Direction.WEST)) + speed = -speed; + float rotX = !diagonal && beltSlope != BeltSlope.HORIZONTAL ? 90 : 0; - float rotY = facing.getHorizontalAngle() + (upward ? 180 : 0) + (sideways ? 270 : 0); + float rotY = facing.getHorizontalAngle() + (upward ? 180 : 0) + (sideways ? 90 : 0); float rotZ = sideways ? 90 : (vertical ? 180 : 0); data.setTileEntity(te) @@ -143,7 +147,75 @@ public class BeltRenderer extends SafeTileEntityRenderer impleme .renderDirectionalPartialInstanced(AllBlockPartials.BELT_PULLEY, blockState, dir, modelTransform); KineticTileEntityRenderer.renderRotatingBuffer(ctx, rotatingBuffer); } + } + @Override + public void markForRebuild(InstanceContext ctx) { + BeltTileEntity te = ctx.te; + FastKineticRenderer fastKineticRenderer = ctx.getKinetics(); + + BlockState blockState = te.getBlockState(); + if (!AllBlocks.BELT.has(blockState)) + return; + + BeltSlope beltSlope = blockState.get(BeltBlock.SLOPE); + BeltPart part = blockState.get(BeltBlock.PART); + Direction facing = blockState.get(BeltBlock.HORIZONTAL_FACING); + AxisDirection axisDirection = facing.getAxisDirection(); + + boolean downward = beltSlope == BeltSlope.DOWNWARD; + boolean upward = beltSlope == BeltSlope.UPWARD; + boolean diagonal = downward || upward; + boolean start = part == BeltPart.START; + boolean end = part == BeltPart.END; + boolean sideways = beltSlope == BeltSlope.SIDEWAYS; + boolean vertical = beltSlope == BeltSlope.VERTICAL; + + if (downward || vertical && axisDirection == AxisDirection.POSITIVE) { + boolean b = start; + start = end; + end = b; + } + + for (boolean bottom : Iterate.trueAndFalse) { + + AllBlockPartials beltPartial = diagonal + ? start ? AllBlockPartials.BELT_DIAGONAL_START + : end ? AllBlockPartials.BELT_DIAGONAL_END : AllBlockPartials.BELT_DIAGONAL_MIDDLE + : bottom + ? start ? AllBlockPartials.BELT_START_BOTTOM + : end ? AllBlockPartials.BELT_END_BOTTOM : AllBlockPartials.BELT_MIDDLE_BOTTOM + : start ? AllBlockPartials.BELT_START + : end ? AllBlockPartials.BELT_END : AllBlockPartials.BELT_MIDDLE; + + InstanceBuffer beltBuffer = beltPartial.renderOnBelt(ctx, blockState); + + beltBuffer.clearInstanceData(); + + // Diagonal belt do not have a separate bottom model + if (diagonal) + break; + } + + // TODO 1.15 find a way to cache this model matrix computation + MatrixStack modelTransform = new MatrixStack(); + Direction dir = blockState.get(BeltBlock.HORIZONTAL_FACING) + .rotateY(); + if (sideways) + dir = Direction.UP; + MatrixStacker msr = MatrixStacker.of(modelTransform); + msr.centre(); + if (dir.getAxis() == Axis.X) + msr.rotateY(90); + if (dir.getAxis() == Axis.Y) + msr.rotateX(90); + msr.rotateX(90); + msr.unCentre(); + + InstanceBuffer rotatingBuffer = fastKineticRenderer + .renderDirectionalPartialInstanced(AllBlockPartials.BELT_PULLEY, blockState, dir, modelTransform); + + rotatingBuffer.clearInstanceData(); } protected void renderItems(BeltTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer, diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltTileEntity.java index c84217cd8..c3ee377bf 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltTileEntity.java @@ -1,24 +1,9 @@ package com.simibubi.create.content.contraptions.relays.belt; -import static com.simibubi.create.content.contraptions.relays.belt.BeltPart.MIDDLE; -import static com.simibubi.create.content.contraptions.relays.belt.BeltSlope.HORIZONTAL; -import static net.minecraft.util.Direction.AxisDirection.NEGATIVE; -import static net.minecraft.util.Direction.AxisDirection.POSITIVE; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.function.Function; - import com.simibubi.create.AllBlocks; import com.simibubi.create.content.contraptions.base.KineticTileEntity; -import com.simibubi.create.content.contraptions.relays.belt.transport.BeltInventory; -import com.simibubi.create.content.contraptions.relays.belt.transport.BeltMovementHandler; +import com.simibubi.create.content.contraptions.relays.belt.transport.*; import com.simibubi.create.content.contraptions.relays.belt.transport.BeltMovementHandler.TransportedEntityInfo; -import com.simibubi.create.content.contraptions.relays.belt.transport.BeltTunnelInteractionHandler; -import com.simibubi.create.content.contraptions.relays.belt.transport.ItemHandlerBeltSegment; -import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack; import com.simibubi.create.content.logistics.block.belts.tunnel.BrassTunnelTileEntity; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour; @@ -26,7 +11,6 @@ import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemS import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour.TransportedResult; import com.simibubi.create.foundation.utility.ColorHelper; import com.simibubi.create.foundation.utility.NBTHelper; - import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.entity.Entity; @@ -51,6 +35,17 @@ import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +import static com.simibubi.create.content.contraptions.relays.belt.BeltPart.MIDDLE; +import static com.simibubi.create.content.contraptions.relays.belt.BeltSlope.HORIZONTAL; +import static net.minecraft.util.Direction.AxisDirection.NEGATIVE; +import static net.minecraft.util.Direction.AxisDirection.POSITIVE; + public class BeltTileEntity extends KineticTileEntity { public Map passengers; @@ -471,4 +466,10 @@ public class BeltTileEntity extends KineticTileEntity { .build(); } + @Override + public boolean shouldRenderAsTE() { + // Since only the controller does the item rendering, we potentially + // save a *lot* of time by not processing the other belts. + return isController(); + } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SplitShaftRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SplitShaftRenderer.java index 72f258b8d..cf0affbfc 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SplitShaftRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SplitShaftRenderer.java @@ -5,11 +5,10 @@ import com.simibubi.create.AllBlockPartials; import com.simibubi.create.content.contraptions.base.IRotate; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer; -import com.simibubi.create.foundation.utility.Iterate; - import com.simibubi.create.foundation.render.instancing.InstanceBuffer; import com.simibubi.create.foundation.render.instancing.InstanceContext; import com.simibubi.create.foundation.render.instancing.RotatingData; +import com.simibubi.create.foundation.utility.Iterate; import net.minecraft.block.Block; import net.minecraft.client.renderer.IRenderTypeBuffer; import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher; @@ -53,7 +52,6 @@ public class SplitShaftRenderer extends KineticTileEntityRenderer { if (boxAxis != axis) continue; - InstanceBuffer shaft = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(ctx, te.getBlockState(), direction); shaft.setupInstance(data -> { @@ -75,4 +73,19 @@ public class SplitShaftRenderer extends KineticTileEntityRenderer { }); } } + + @Override + public void markForRebuild(InstanceContext ctx) { + KineticTileEntity te = ctx.te; + Block block = te.getBlockState().getBlock(); + final Axis boxAxis = ((IRotate) block).getRotationAxis(te.getBlockState()); + + for (Direction direction : Iterate.directions) { + Axis axis = direction.getAxis(); + if (boxAxis != axis) continue; + + InstanceBuffer shaft = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(ctx, te.getBlockState(), direction); + shaft.clearInstanceData(); + } + } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/gauge/GaugeTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/relays/gauge/GaugeTileEntity.java index 3969af754..ac4e4664a 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/gauge/GaugeTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/gauge/GaugeTileEntity.java @@ -1,14 +1,13 @@ package com.simibubi.create.content.contraptions.relays.gauge; -import java.util.List; - import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.goggles.IHaveGoggleInformation; import com.simibubi.create.foundation.utility.Lang; - import net.minecraft.nbt.CompoundNBT; import net.minecraft.tileentity.TileEntityType; +import java.util.List; + public class GaugeTileEntity extends KineticTileEntity implements IHaveGoggleInformation { public float dialTarget; @@ -50,4 +49,8 @@ public class GaugeTileEntity extends KineticTileEntity implements IHaveGoggleInf return true; } + @Override + public boolean shouldRenderAsTE() { + return true; + } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearboxRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearboxRenderer.java index f4c7b33ba..0a01c1bd6 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearboxRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearboxRenderer.java @@ -1,14 +1,15 @@ package com.simibubi.create.content.contraptions.relays.gearbox; +import com.google.common.collect.Lists; import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.AllBlockPartials; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer; -import com.simibubi.create.foundation.utility.Iterate; - import com.simibubi.create.foundation.render.instancing.InstanceBuffer; import com.simibubi.create.foundation.render.instancing.InstanceContext; import com.simibubi.create.foundation.render.instancing.RotatingData; +import com.simibubi.create.foundation.utility.Iterate; +import com.simibubi.create.foundation.utility.Pair; import net.minecraft.client.renderer.IRenderTypeBuffer; import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher; import net.minecraft.state.properties.BlockStateProperties; @@ -17,6 +18,8 @@ import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.BlockPos; import net.minecraft.world.LightType; +import java.util.List; + public class GearboxRenderer extends KineticTileEntityRenderer { public GearboxRenderer(TileEntityRendererDispatcher dispatcher) { @@ -32,7 +35,6 @@ public class GearboxRenderer extends KineticTileEntityRenderer { @Override public void addInstanceData(InstanceContext ctx) { KineticTileEntity te = ctx.te; - final Axis boxAxis = te.getBlockState().get(BlockStateProperties.AXIS); final BlockPos pos = te.getPos(); int blockLight; @@ -46,20 +48,16 @@ public class GearboxRenderer extends KineticTileEntityRenderer { skyLight = 0; } - for (Direction direction : Iterate.directions) { - final Axis axis = direction.getAxis(); - if (boxAxis == axis) - continue; - - InstanceBuffer shaft = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(ctx, te.getBlockState(), direction); - - shaft.setupInstance(data -> { + for (Pair> shaft : getBuffers(ctx)) { + shaft.getSecond().setupInstance(data -> { float speed = te.getSpeed(); + Direction direction = shaft.getFirst(); + Axis axis = direction.getAxis(); if (te.getSpeed() != 0 && te.hasSource()) { BlockPos source = te.source.subtract(te.getPos()); Direction sourceFacing = Direction.getFacingFromVector(source.getX(), source.getY(), source.getZ()); - if (sourceFacing.getAxis() == direction.getAxis()) + if (sourceFacing.getAxis() == axis) speed *= sourceFacing == direction ? 1 : -1; else if (sourceFacing.getAxisDirection() == direction.getAxisDirection()) speed *= -1; @@ -74,4 +72,29 @@ public class GearboxRenderer extends KineticTileEntityRenderer { }); } } + + @Override + public void markForRebuild(InstanceContext ctx) { + getBuffers(ctx).stream().map(Pair::getSecond).forEach(InstanceBuffer::clearInstanceData); + } + + private List>> getBuffers(InstanceContext ctx) { + KineticTileEntity te = ctx.te; + final Axis boxAxis = te.getBlockState().get(BlockStateProperties.AXIS); + + List>> buffers = Lists.newArrayListWithCapacity(4); + + for (Direction direction : Iterate.directions) { + final Axis axis = direction.getAxis(); + if (boxAxis == axis) + continue; + + InstanceBuffer buffer = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(ctx, te.getBlockState(), direction); + Pair> pair = Pair.of(direction, buffer); + + buffers.add(pair); + } + + return buffers; + } } diff --git a/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmTileEntity.java b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmTileEntity.java index 7d72c4ff1..0c56559d3 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmTileEntity.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmTileEntity.java @@ -1,10 +1,5 @@ package com.simibubi.create.content.logistics.block.mechanicalArm; -import java.util.ArrayList; -import java.util.List; - -import javax.annotation.Nullable; - import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.logistics.block.mechanicalArm.ArmInteractionPoint.Jukebox; import com.simibubi.create.content.logistics.block.mechanicalArm.ArmInteractionPoint.Mode; @@ -21,7 +16,6 @@ import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.NBTHelper; import com.simibubi.create.foundation.utility.VecHelper; - import net.minecraft.block.BlockState; import net.minecraft.block.JukeboxBlock; import net.minecraft.item.ItemStack; @@ -37,6 +31,10 @@ import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.common.util.Constants.NBT; +import javax.annotation.Nullable; +import java.util.ArrayList; +import java.util.List; + public class ArmTileEntity extends KineticTileEntity { // Server @@ -515,4 +513,8 @@ public class ArmTileEntity extends KineticTileEntity { } } + @Override + public boolean shouldRenderAsTE() { + return true; + } } diff --git a/src/main/java/com/simibubi/create/events/ClientEvents.java b/src/main/java/com/simibubi/create/events/ClientEvents.java index 30385556d..45858e93d 100644 --- a/src/main/java/com/simibubi/create/events/ClientEvents.java +++ b/src/main/java/com/simibubi/create/events/ClientEvents.java @@ -24,6 +24,8 @@ import com.simibubi.create.foundation.gui.ScreenOpener; import com.simibubi.create.foundation.item.TooltipHelper; import com.simibubi.create.foundation.networking.AllPackets; import com.simibubi.create.foundation.networking.LeftClickPacket; +import com.simibubi.create.foundation.render.FastRenderDispatcher; +import com.simibubi.create.foundation.render.RenderWork; import com.simibubi.create.foundation.renderState.SuperRenderTypeBuffer; import com.simibubi.create.foundation.tileEntity.behaviour.edgeInteraction.EdgeInteractionRenderer; import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringRenderer; @@ -32,12 +34,9 @@ import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.ScrollVal import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.ServerSpeedProvider; import com.simibubi.create.foundation.utility.placement.PlacementHelpers; -import com.simibubi.create.foundation.render.FastContraptionRenderer; -import com.simibubi.create.foundation.render.RenderWork; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.ActiveRenderInfo; import net.minecraft.client.renderer.IRenderTypeBuffer; -import net.minecraft.client.renderer.Matrix4f; import net.minecraft.client.renderer.texture.OverlayTexture; import net.minecraft.fluid.Fluid; import net.minecraft.fluid.IFluidState; @@ -74,13 +73,10 @@ public class ClientEvents { if (event.phase == Phase.START) return; - AnimationTickHolder.tick(); - if (!isGameActive()) return; - CreateClient.kineticRenderer.tick(); - FastContraptionRenderer.tick(); + AnimationTickHolder.tick(); CreateClient.schematicSender.tick(); CreateClient.schematicAndQuillHandler.tick(); @@ -114,20 +110,13 @@ public class ClientEvents { @SubscribeEvent public static void onLoadWorld(WorldEvent.Load event) { CreateClient.invalidateRenderers(); + AnimationTickHolder.ticks = 0; } @SubscribeEvent public static void onRenderWorld(RenderWorldLastEvent event) { - Matrix4f projection = event.getProjectionMatrix(); - // view matrix Vec3d cameraPos = Minecraft.getInstance().gameRenderer.getActiveRenderInfo().getProjectedView(); - Matrix4f view = Matrix4f.translate((float) -cameraPos.x, (float) -cameraPos.y, (float) -cameraPos.z); - view.multiplyBackward(event.getMatrixStack().peek().getModel()); - - CreateClient.kineticRenderer.renderInstancesAsWorld(projection, view); - FastContraptionRenderer.renderAll(projection, view); - MatrixStack ms = event.getMatrixStack(); ActiveRenderInfo info = Minecraft.getInstance().gameRenderer.getActiveRenderInfo(); ms.push(); @@ -143,6 +132,7 @@ public class ClientEvents { ms.pop(); RenderWork.runAll(); + FastRenderDispatcher.endFrame(); } @SubscribeEvent diff --git a/src/main/java/com/simibubi/create/foundation/mixin/CancelTileEntityRenderMixin.java b/src/main/java/com/simibubi/create/foundation/mixin/CancelTileEntityRenderMixin.java new file mode 100644 index 000000000..6b9c41924 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/mixin/CancelTileEntityRenderMixin.java @@ -0,0 +1,44 @@ +package com.simibubi.create.foundation.mixin; + +import com.simibubi.create.foundation.render.instancing.IInstanceRendered; +import net.minecraft.client.renderer.chunk.ChunkRenderDispatcher; +import net.minecraft.tileentity.TileEntity; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.ArrayList; +import java.util.List; + +@OnlyIn(Dist.CLIENT) +@Mixin(ChunkRenderDispatcher.CompiledChunk.class) +public class CancelTileEntityRenderMixin { + + /** + * JUSTIFICATION: when instanced rendering is enabled, many tile entities no longer need + * to be processed by the normal game renderer. This method is only called to retrieve the + * list of tile entities to render. By filtering the output here, we prevent the game from + * doing unnecessary light lookups and frustum checks. + */ + @Inject(at = @At("RETURN"), method = "getTileEntities", cancellable = true) + private void noRenderInstancedTiles(CallbackInfoReturnable> cir) { + List tiles = cir.getReturnValue(); + + List out = new ArrayList<>(tiles.size()); + + for (TileEntity tile : tiles) { + if (tile instanceof IInstanceRendered) { + IInstanceRendered instanceRendered = (IInstanceRendered) tile; + + if (!instanceRendered.shouldRenderAsTE()) continue; + } + + out.add(tile); + } + + cir.setReturnValue(out); + } +} 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 c19a3018b..38e2053d2 100644 --- a/src/main/java/com/simibubi/create/foundation/mixin/LightUpdateMixin.java +++ b/src/main/java/com/simibubi/create/foundation/mixin/LightUpdateMixin.java @@ -1,19 +1,29 @@ package com.simibubi.create.foundation.mixin; +import com.simibubi.create.foundation.render.FastRenderDispatcher; import net.minecraft.client.multiplayer.ClientChunkProvider; import net.minecraft.util.math.SectionPos; import net.minecraft.world.LightType; +import net.minecraft.world.chunk.AbstractChunkProvider; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +@OnlyIn(Dist.CLIENT) @Mixin(ClientChunkProvider.class) -public class LightUpdateMixin { - @Shadow - @Inject(at = @At("HEAD"), method = "markLightChanged(Lnet/minecraft/world/LightType;Lnet/minecraft/util/math/SectionPos;)V") - private void onLightUpdate(LightType type, SectionPos pos, CallbackInfo ci) { +public abstract class LightUpdateMixin extends AbstractChunkProvider { + /** + * JUSTIFICATION: This method is called after a lighting tick once per subchunk where a + * lighting change occurred that tick. On the client, Minecraft uses this method to inform + * the rendering system that it needs to redraw a chunk. It does all that work asynchronously, + * and we should too. + */ + @Inject(at = @At("HEAD"), method = "markLightChanged") + private void onLightUpdate(LightType type, SectionPos pos, CallbackInfo ci) { + FastRenderDispatcher.notifyLightUpdate(((ClientChunkProvider) (Object) this), type, pos); } } diff --git a/src/main/java/com/simibubi/create/foundation/mixin/OnRemoveTileMixin.java b/src/main/java/com/simibubi/create/foundation/mixin/OnRemoveTileMixin.java new file mode 100644 index 000000000..3c838af98 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/mixin/OnRemoveTileMixin.java @@ -0,0 +1,28 @@ +package com.simibubi.create.foundation.mixin; + +import com.simibubi.create.foundation.render.FastRenderDispatcher; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; + +@OnlyIn(Dist.CLIENT) +@Mixin(World.class) +public class OnRemoveTileMixin { + + /** + * JUSTIFICATION: This method is called whenever a tile entity is removed due + * to a change in block state, even on the client. By hooking into this method, + * we gain easy access to the information while having no impact on performance. + */ + @Inject(at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/world/World;getTileEntity(Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/tileentity/TileEntity;"), method = "removeTileEntity", locals = LocalCapture.CAPTURE_FAILHARD) + private void onRemoveTile(BlockPos pos, CallbackInfo ci, TileEntity te) { + FastRenderDispatcher.markForRebuild(te); + } +} diff --git a/src/main/java/com/simibubi/create/foundation/mixin/RenderInLayerMixin.java b/src/main/java/com/simibubi/create/foundation/mixin/RenderInLayerMixin.java index b008ba822..5c019b01e 100644 --- a/src/main/java/com/simibubi/create/foundation/mixin/RenderInLayerMixin.java +++ b/src/main/java/com/simibubi/create/foundation/mixin/RenderInLayerMixin.java @@ -1,19 +1,27 @@ package com.simibubi.create.foundation.mixin; import com.mojang.blaze3d.matrix.MatrixStack; +import com.simibubi.create.foundation.render.FastRenderDispatcher; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.WorldRenderer; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +@OnlyIn(Dist.CLIENT) @Mixin(WorldRenderer.class) public class RenderInLayerMixin { - @Shadow - @Inject(at = @At("HEAD"), method = "renderLayer") // (Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/matrix/MatrixStack;DDD)V") - private void renderLayer(RenderType type, MatrixStack stack, double cameraX, double cameraY, double cameraZ, CallbackInfo ci) { + /** + * 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. + * This should probably be a forge event. + */ + @Inject(at = @At("HEAD"), method = "renderLayer") + private void renderLayer(RenderType type, MatrixStack stack, double cameraX, double cameraY, double cameraZ, CallbackInfo ci) { + FastRenderDispatcher.renderLayer(type, stack, cameraX, cameraY, cameraZ); } } diff --git a/src/main/java/com/simibubi/create/foundation/render/FastContraptionRenderer.java b/src/main/java/com/simibubi/create/foundation/render/FastContraptionRenderer.java index 2625da228..05589b6b4 100644 --- a/src/main/java/com/simibubi/create/foundation/render/FastContraptionRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/render/FastContraptionRenderer.java @@ -10,7 +10,9 @@ import com.simibubi.create.foundation.render.shader.Shader; import com.simibubi.create.foundation.render.shader.ShaderCallback; import com.simibubi.create.foundation.render.shader.ShaderHelper; import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.*; +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.client.renderer.Matrix4f; +import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.tileentity.TileEntityRenderer; import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher; import net.minecraft.tileentity.TileEntity; @@ -28,7 +30,7 @@ public class FastContraptionRenderer extends ContraptionRenderer { private static final HashMap renderers = new HashMap<>(); - private ArrayList renderLayers = new ArrayList<>(); + private HashMap renderLayers = new HashMap<>(); private ContraptionLighter lighter; @@ -48,7 +50,7 @@ public class FastContraptionRenderer extends ContraptionRenderer { } private void buildLayers(Contraption c) { - for (ContraptionBuffer buffer : renderLayers) { + for (ContraptionBuffer buffer : renderLayers.values()) { buffer.delete(); } @@ -57,7 +59,7 @@ public class FastContraptionRenderer extends ContraptionRenderer { List blockLayers = RenderType.getBlockLayers(); for (RenderType layer : blockLayers) { - renderLayers.add(buildStructureBuffer(c, layer)); + renderLayers.put(layer, buildStructureBuffer(c, layer)); } } @@ -123,15 +125,14 @@ public class FastContraptionRenderer extends ContraptionRenderer { } private void invalidate() { - for (ContraptionBuffer buffer : renderLayers) { + for (ContraptionBuffer buffer : renderLayers.values()) { buffer.delete(); } + renderLayers.clear(); lighter.delete(); kinetics.invalidate(); - - renderLayers.clear(); } public static void markForRendering(World world, Contraption c, MatrixStack model) { @@ -151,46 +152,48 @@ public class FastContraptionRenderer extends ContraptionRenderer { return renderer; } - public static void renderAll(Matrix4f projectionMat, Matrix4f viewMat) { + public static void renderLayer(RenderType renderType, Matrix4f projectionMat, Matrix4f viewMat) { removeDeadContraptions(); if (renderers.isEmpty()) return; - GameRenderer gameRenderer = Minecraft.getInstance().gameRenderer; - FastKineticRenderer.setup(gameRenderer); + FastKineticRenderer.setup(Minecraft.getInstance().gameRenderer); GL11.glEnable(GL13.GL_TEXTURE_3D); - GL13.glActiveTexture(GL40.GL_TEXTURE4); + GL13.glActiveTexture(GL40.GL_TEXTURE4); // the shaders expect light volumes to be in texture 4 ShaderCallback callback = ShaderHelper.getViewProjectionCallback(projectionMat, viewMat); - int structureShader = ShaderHelper.useShader(Shader.CONTRAPTION_STRUCTURE, callback); for (FastContraptionRenderer renderer : renderers.values()) { - renderer.setup(structureShader); - for (ContraptionBuffer layer : renderer.renderLayers) { - layer.render(); + ContraptionBuffer buffer = renderer.renderLayers.get(renderType); + if (buffer != null) { + renderer.setup(structureShader); + buffer.render(); + renderer.teardown(); } - renderer.teardown(); } - int rotatingShader = ShaderHelper.useShader(Shader.CONTRAPTION_ROTATING, callback); - for (FastContraptionRenderer renderer : renderers.values()) { - renderer.setup(rotatingShader); - renderer.kinetics.renderRotating(); - renderer.teardown(); - } + if (renderType == FastKineticRenderer.getKineticRenderLayer()) { + int rotatingShader = ShaderHelper.useShader(Shader.CONTRAPTION_ROTATING, callback); + for (FastContraptionRenderer renderer : renderers.values()) { + renderer.setup(rotatingShader); + renderer.kinetics.renderRotating(); + renderer.teardown(); + } - int beltShader = ShaderHelper.useShader(Shader.CONTRAPTION_BELT, callback); - for (FastContraptionRenderer renderer : renderers.values()) { - renderer.setup(beltShader); - renderer.kinetics.renderBelts(); - renderer.teardown(); + int beltShader = ShaderHelper.useShader(Shader.CONTRAPTION_BELT, callback); + for (FastContraptionRenderer renderer : renderers.values()) { + renderer.setup(beltShader); + renderer.kinetics.renderBelts(); + renderer.teardown(); + } } ShaderHelper.releaseShader(); GL11.glDisable(GL13.GL_TEXTURE_3D); FastKineticRenderer.teardown(); + GL13.glActiveTexture(GL40.GL_TEXTURE0); } public static void removeDeadContraptions() { diff --git a/src/main/java/com/simibubi/create/foundation/render/FastKineticRenderer.java b/src/main/java/com/simibubi/create/foundation/render/FastKineticRenderer.java index c3ec9e269..c485f6ed5 100644 --- a/src/main/java/com/simibubi/create/foundation/render/FastKineticRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/render/FastKineticRenderer.java @@ -26,9 +26,10 @@ import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL13; import org.lwjgl.opengl.GL40; -import java.util.*; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; import java.util.function.Supplier; import static com.simibubi.create.foundation.render.SuperByteBufferCache.PARTIAL; @@ -37,12 +38,11 @@ public class FastKineticRenderer { Map, Cache>> rotating; Map, Cache>> belts; - boolean rebuild; + public boolean dirty = false; public FastKineticRenderer() { rotating = new HashMap<>(); belts = new HashMap<>(); - registerCompartment(SuperByteBufferCache.GENERIC_TILE); registerCompartment(SuperByteBufferCache.PARTIAL); registerCompartment(SuperByteBufferCache.DIRECTIONAL_PARTIAL); registerCompartment(KineticTileEntityRenderer.KINETIC_TILE); @@ -92,25 +92,6 @@ public class FastKineticRenderer { } } - public void tick() { - // TODO: (later) detect changes in lighting with a mixin (or forge hook) to ClientChunkProvider.markLightChanged() - for (Cache> cache : rotating.values()) { - for (InstanceBuffer renderer : cache.asMap().values()) { - renderer.clearInstanceData(); - } - } - - for (Cache> cache : belts.values()) { - for (InstanceBuffer renderer : cache.asMap().values()) { - renderer.clearInstanceData(); - } - } - - //buildTileEntityBuffers(Minecraft.getInstance().world); - - rebuild = true; - } - void renderBelts() { for (Cache> cache : belts.values()) { for (InstanceBuffer type : cache.asMap().values()) { @@ -131,15 +112,15 @@ public class FastKineticRenderer { } } - public void renderInstancesAsWorld(Matrix4f projection, Matrix4f view) { - GameRenderer gameRenderer = Minecraft.getInstance().gameRenderer; - - if (rebuild) { + public void renderInstancesAsWorld(RenderType layer, Matrix4f projection, Matrix4f view) { + if (dirty) { + buildTileEntityBuffers(Minecraft.getInstance().world); markAllDirty(); - rebuild = false; + + dirty = false; } - setup(gameRenderer); + layer.startDrawing(); ShaderCallback callback = ShaderHelper.getViewProjectionCallback(projection, view); @@ -151,7 +132,7 @@ public class FastKineticRenderer { ShaderHelper.releaseShader(); - teardown(); + layer.endDrawing(); } public static void setup(GameRenderer gameRenderer) { @@ -206,11 +187,6 @@ public class FastKineticRenderer { belts.put(instance, CacheBuilder.newBuilder().build()); } - public void registerCompartment(SuperByteBufferCache.Compartment instance, long ticksUntilExpired) { - rotating.put(instance, CacheBuilder.newBuilder().expireAfterAccess(ticksUntilExpired * 50, TimeUnit.MILLISECONDS).build()); - belts.put(instance, CacheBuilder.newBuilder().expireAfterAccess(ticksUntilExpired * 50, TimeUnit.MILLISECONDS).build()); - } - public InstanceBuffer renderPartialRotating(AllBlockPartials partial, BlockState referenceState) { return getRotating(PARTIAL, partial, () -> rotatingInstancedRenderer(partial.get(), referenceState)); } @@ -249,7 +225,6 @@ public class FastKineticRenderer { } } - private InstanceBuffer rotatingInstancedRenderer(BlockState renderedState) { BlockRendererDispatcher dispatcher = Minecraft.getInstance().getBlockRendererDispatcher(); return rotatingInstancedRenderer(dispatcher.getModelForState(renderedState), renderedState); @@ -286,4 +261,8 @@ public class FastKineticRenderer { cache.invalidateAll(); } } + + public static RenderType getKineticRenderLayer() { + return RenderType.getCutoutMipped(); + } } diff --git a/src/main/java/com/simibubi/create/foundation/render/FastRenderDispatcher.java b/src/main/java/com/simibubi/create/foundation/render/FastRenderDispatcher.java new file mode 100644 index 000000000..fca350101 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/render/FastRenderDispatcher.java @@ -0,0 +1,118 @@ +package com.simibubi.create.foundation.render; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.simibubi.create.CreateClient; +import com.simibubi.create.foundation.render.instancing.IInstanceRendered; +import com.simibubi.create.foundation.render.instancing.IInstancedTileEntityRenderer; +import com.simibubi.create.foundation.render.instancing.InstanceContext; +import com.simibubi.create.foundation.utility.AnimationTickHolder; +import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.player.ClientPlayerEntity; +import net.minecraft.client.multiplayer.ClientChunkProvider; +import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.client.renderer.Matrix4f; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.Vector3f; +import net.minecraft.client.renderer.tileentity.TileEntityRenderer; +import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher; +import net.minecraft.potion.Effects; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.SectionPos; +import net.minecraft.world.LightType; +import net.minecraft.world.chunk.Chunk; + +import java.util.Map; + +public class FastRenderDispatcher { + + private static Matrix4f projectionMatrixThisFrame = null; + + public static void endFrame() { + projectionMatrixThisFrame = null; + } + + public static void renderLayer(RenderType type, MatrixStack stack, double cameraX, double cameraY, double cameraZ) { + Matrix4f view = Matrix4f.translate((float) -cameraX, (float) -cameraY, (float) -cameraZ); + view.multiplyBackward(stack.peek().getModel()); + + Matrix4f projection = getProjectionMatrix(); + + if (type == FastKineticRenderer.getKineticRenderLayer()) { + CreateClient.kineticRenderer.renderInstancesAsWorld(type, projection, view); + } + + FastContraptionRenderer.renderLayer(type, projection, view); + } + + public static void notifyLightUpdate(ClientChunkProvider world, LightType type, SectionPos pos) { + FastContraptionRenderer.tick(); + + Chunk chunk = world.getChunk(pos.getSectionX(), pos.getSectionZ(), false); + + int sectionY = pos.getSectionY(); + + if (chunk != null) { + chunk.getTileEntityMap() + .entrySet() + .stream() + .filter(entry -> SectionPos.toChunk(entry.getKey().getY()) == sectionY) + .map(Map.Entry::getValue) + .forEach(FastRenderDispatcher::markForRebuild); + } + } + + public static void markForRebuild(TileEntity te) { + if (te instanceof IInstanceRendered) { + TileEntityRenderer renderer = TileEntityRendererDispatcher.instance.getRenderer(te); + + if (renderer instanceof IInstancedTileEntityRenderer) { + markForRebuild(te, (IInstancedTileEntityRenderer) renderer); + } + } + } + + private static void markForRebuild(T te, IInstancedTileEntityRenderer renderer) { + CreateClient.kineticRenderer.dirty = true; + renderer.markForRebuild(new InstanceContext.World<>(te)); + } + + // copied from GameRenderer.renderWorld + private static Matrix4f getProjectionMatrix() { + if (projectionMatrixThisFrame != null) return projectionMatrixThisFrame; + + float partialTicks = AnimationTickHolder.getPartialTicks(); + Minecraft mc = Minecraft.getInstance(); + GameRenderer gameRenderer = mc.gameRenderer; + ClientPlayerEntity player = mc.player; + + MatrixStack matrixstack = new MatrixStack(); + matrixstack.peek().getModel().multiply(gameRenderer.func_228382_a_(gameRenderer.getActiveRenderInfo(), partialTicks, true)); + gameRenderer.bobViewWhenHurt(matrixstack, partialTicks); + if (mc.gameSettings.viewBobbing) { + gameRenderer.bobView(matrixstack, partialTicks); + } + + float portalTime = MathHelper.lerp(partialTicks, player.prevTimeInPortal, player.timeInPortal); + if (portalTime > 0.0F) { + int i = 20; + if (player.isPotionActive(Effects.NAUSEA)) { + i = 7; + } + + float f1 = 5.0F / (portalTime * portalTime + 5.0F) - portalTime * 0.04F; + f1 = f1 * f1; + Vector3f vector3f = new Vector3f(0.0F, MathHelper.SQRT_2 / 2.0F, MathHelper.SQRT_2 / 2.0F); + matrixstack.multiply(vector3f.getDegreesQuaternion(((float)gameRenderer.rendererUpdateCount + partialTicks) * (float)i)); + matrixstack.scale(1.0F / f1, 1.0F, 1.0F); + float f2 = -((float)gameRenderer.rendererUpdateCount + partialTicks) * (float)i; + matrixstack.multiply(vector3f.getDegreesQuaternion(f2)); + } + + Matrix4f matrix4f = matrixstack.peek().getModel(); + gameRenderer.func_228379_a_(matrix4f); + + projectionMatrixThisFrame = matrix4f; + return projectionMatrixThisFrame; + } +} diff --git a/src/main/java/com/simibubi/create/foundation/render/TileEntityRenderHelper.java b/src/main/java/com/simibubi/create/foundation/render/TileEntityRenderHelper.java index d457bb8e0..d52ccf02b 100644 --- a/src/main/java/com/simibubi/create/foundation/render/TileEntityRenderHelper.java +++ b/src/main/java/com/simibubi/create/foundation/render/TileEntityRenderHelper.java @@ -1,13 +1,9 @@ package com.simibubi.create.foundation.render; -import java.util.Iterator; - import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.Create; import com.simibubi.create.foundation.config.AllConfigs; - import com.simibubi.create.foundation.utility.MatrixStacker; -import com.simibubi.create.foundation.render.instancing.IInstanceRendered; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.IRenderTypeBuffer; import net.minecraft.client.renderer.Matrix4f; @@ -20,6 +16,8 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; +import java.util.Iterator; + public class TileEntityRenderHelper { public static void renderTileEntities(World world, Iterable customRenderTEs, MatrixStack ms, @@ -31,7 +29,7 @@ public class TileEntityRenderHelper { for (Iterator iterator = customRenderTEs.iterator(); iterator.hasNext();) { TileEntity tileEntity = iterator.next(); - if (tileEntity instanceof IInstanceRendered) continue; // TODO: some things still need to render + //if (tileEntity instanceof IInstanceRendered) continue; // TODO: some things still need to render TileEntityRenderer renderer = TileEntityRendererDispatcher.instance.getRenderer(tileEntity); if (renderer == null) { diff --git a/src/main/java/com/simibubi/create/foundation/render/instancing/IInstanceRendered.java b/src/main/java/com/simibubi/create/foundation/render/instancing/IInstanceRendered.java index bd825757b..e169de311 100644 --- a/src/main/java/com/simibubi/create/foundation/render/instancing/IInstanceRendered.java +++ b/src/main/java/com/simibubi/create/foundation/render/instancing/IInstanceRendered.java @@ -1,4 +1,7 @@ package com.simibubi.create.foundation.render.instancing; public interface IInstanceRendered { + default boolean shouldRenderAsTE() { + return false; + } } diff --git a/src/main/java/com/simibubi/create/foundation/render/instancing/IInstancedTileEntityRenderer.java b/src/main/java/com/simibubi/create/foundation/render/instancing/IInstancedTileEntityRenderer.java index 176acb724..4b9ccaa1b 100644 --- a/src/main/java/com/simibubi/create/foundation/render/instancing/IInstancedTileEntityRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/render/instancing/IInstancedTileEntityRenderer.java @@ -4,5 +4,7 @@ import net.minecraft.tileentity.TileEntity; public interface IInstancedTileEntityRenderer { - void addInstanceData(InstanceContext te); + void addInstanceData(InstanceContext ctx); + + void markForRebuild(InstanceContext ctx); } diff --git a/src/main/java/com/simibubi/create/foundation/render/instancing/InstanceBuffer.java b/src/main/java/com/simibubi/create/foundation/render/instancing/InstanceBuffer.java index 74d90d8d1..54bca6390 100644 --- a/src/main/java/com/simibubi/create/foundation/render/instancing/InstanceBuffer.java +++ b/src/main/java/com/simibubi/create/foundation/render/instancing/InstanceBuffer.java @@ -84,12 +84,11 @@ public abstract class InstanceBuffer extends TemplateBuf } public void clearInstanceData() { - instanceCount = 0; shouldBuild = true; } public void markDirty() { - rebuffer = true; + if (shouldBuild) rebuffer = true; } public void delete() { @@ -140,7 +139,7 @@ public abstract class InstanceBuffer extends TemplateBuf } private void finishBuffering() { - if (!rebuffer || isEmpty()) return; + if (!rebuffer || data.isEmpty()) return; instanceCount = data.size(); diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg index fdc144a8b..440395e69 100644 --- a/src/main/resources/META-INF/accesstransformer.cfg +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -27,4 +27,9 @@ public net.minecraft.world.server.ServerTickList field_205375_e # pendingTickLis # Lightmap information for instanced rendering public net.minecraft.client.renderer.LightTexture field_205112_c #resourceLocation -public net.minecraft.client.Minecraft field_193996_ah #renderPartialTicksPaused \ No newline at end of file +public net.minecraft.client.Minecraft field_193996_ah #renderPartialTicksPaused + +# Functions needed to setup a projection matrix +public net.minecraft.client.renderer.GameRenderer field_78529_t #rendererUpdateCount +public net.minecraft.client.renderer.GameRenderer func_228380_a_(Lcom/mojang/blaze3d/matrix/MatrixStack;F)V #bobViewWhenHurt +public net.minecraft.client.renderer.GameRenderer func_228383_b_(Lcom/mojang/blaze3d/matrix/MatrixStack;F)V #bobView \ No newline at end of file diff --git a/src/main/resources/assets/create/shader/contraption.frag b/src/main/resources/assets/create/shader/contraption.frag index 9ec3cc530..c493e4c4e 100644 --- a/src/main/resources/assets/create/shader/contraption.frag +++ b/src/main/resources/assets/create/shader/contraption.frag @@ -8,7 +8,7 @@ in vec3 BoxCoord; out vec4 fragColor; layout(binding=0) uniform sampler2D BlockAtlas; -layout(binding=1) uniform sampler2D LightMap; +layout(binding=2) uniform sampler2D LightMap; layout(binding=4) uniform sampler3D LightVolume; vec4 light() { diff --git a/src/main/resources/assets/create/shader/instanced.frag b/src/main/resources/assets/create/shader/instanced.frag index fae8b8494..1dc3b376b 100644 --- a/src/main/resources/assets/create/shader/instanced.frag +++ b/src/main/resources/assets/create/shader/instanced.frag @@ -8,7 +8,7 @@ in vec4 Color; out vec4 fragColor; layout(binding=0) uniform sampler2D BlockAtlas; -layout(binding=1) uniform sampler2D LightMap; +layout(binding=2) uniform sampler2D LightMap; vec4 light() { vec2 lm = Light * 0.9375 + 0.03125; diff --git a/src/main/resources/create.mixins.json b/src/main/resources/create.mixins.json index c4bf6f100..f674ecc82 100644 --- a/src/main/resources/create.mixins.json +++ b/src/main/resources/create.mixins.json @@ -3,10 +3,7 @@ "package": "com.simibubi.create.foundation.mixin", "compatibilityLevel": "JAVA_8", "refmap": "create.refmap.json", - "client": [ - "LightUpdateMixin", - "RenderInLayerMixin" - ], + "client": ["CancelTileEntityRenderMixin", "LightUpdateMixin", "OnRemoveTileMixin", "RenderInLayerMixin"], "injectors": { "defaultRequire": 1 },