diff --git a/src/main/java/com/simibubi/create/AllTileEntities.java b/src/main/java/com/simibubi/create/AllTileEntities.java index 5b0c1e96b..b194f3204 100644 --- a/src/main/java/com/simibubi/create/AllTileEntities.java +++ b/src/main/java/com/simibubi/create/AllTileEntities.java @@ -51,8 +51,10 @@ import com.simibubi.create.content.contraptions.components.structureMovement.bea import com.simibubi.create.content.contraptions.components.structureMovement.bearing.MechanicalBearingTileEntity; import com.simibubi.create.content.contraptions.components.structureMovement.bearing.WindmillBearingTileEntity; import com.simibubi.create.content.contraptions.components.structureMovement.chassis.ChassisTileEntity; +import com.simibubi.create.content.contraptions.components.structureMovement.chassis.StickerInstance; import com.simibubi.create.content.contraptions.components.structureMovement.chassis.StickerRenderer; import com.simibubi.create.content.contraptions.components.structureMovement.chassis.StickerTileEntity; +import com.simibubi.create.content.contraptions.components.structureMovement.gantry.GantryPinionInstance; import com.simibubi.create.content.contraptions.components.structureMovement.gantry.GantryPinionRenderer; import com.simibubi.create.content.contraptions.components.structureMovement.gantry.GantryPinionTileEntity; import com.simibubi.create.content.contraptions.components.structureMovement.mounted.CartAssemblerTileEntity; @@ -250,7 +252,7 @@ public class AllTileEntities { .tileEntity("gantry_pinion", GantryPinionTileEntity::new) .validBlocks(AllBlocks.GANTRY_PINION) .renderer(() -> GantryPinionRenderer::new) - .onRegister(ShaftInstance::register) + .onRegister(GantryPinionInstance::register) .register(); public static final TileEntityEntry MECHANICAL_PUMP = Create.registrate() @@ -405,6 +407,7 @@ public class AllTileEntities { .tileEntity("sticker", StickerTileEntity::new) .validBlocks(AllBlocks.STICKER) .renderer(() -> StickerRenderer::new) + .onRegister(StickerInstance::register) .register(); public static final TileEntityEntry DRILL = Create.registrate() diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileInstance.java b/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileInstance.java index 69f53613c..861d51752 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileInstance.java @@ -5,11 +5,8 @@ import java.util.function.Consumer; import com.simibubi.create.AllBlocks; import com.simibubi.create.content.contraptions.relays.elementary.CogWheelBlock; import com.simibubi.create.content.contraptions.relays.elementary.ShaftBlock; -import com.simibubi.create.foundation.render.backend.instancing.InstanceKey; +import com.simibubi.create.foundation.render.backend.instancing.*; import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; -import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; -import com.simibubi.create.foundation.render.backend.instancing.RenderMaterial; -import com.simibubi.create.foundation.render.backend.instancing.TileEntityInstance; import net.minecraft.block.BlockState; import net.minecraft.util.Direction; diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/KineticVertexAttributes.java b/src/main/java/com/simibubi/create/content/contraptions/base/KineticVertexAttributes.java index 46f8740f4..bb6585755 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/KineticVertexAttributes.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/KineticVertexAttributes.java @@ -1,6 +1,7 @@ package com.simibubi.create.content.contraptions.base; import com.simibubi.create.foundation.render.backend.gl.attrib.CommonAttributes; +import com.simibubi.create.foundation.render.backend.gl.attrib.IAttribSpec; import com.simibubi.create.foundation.render.backend.gl.attrib.IVertexAttrib; import com.simibubi.create.foundation.render.backend.gl.attrib.VertexAttribSpec; @@ -26,7 +27,7 @@ public enum KineticVertexAttributes implements IVertexAttrib { } @Override - public VertexAttribSpec attribSpec() { + public IAttribSpec attribSpec() { return spec; } diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/RotatingVertexAttributes.java b/src/main/java/com/simibubi/create/content/contraptions/base/RotatingVertexAttributes.java index 677b18190..e264731cc 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/RotatingVertexAttributes.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/RotatingVertexAttributes.java @@ -1,6 +1,7 @@ package com.simibubi.create.content.contraptions.base; import com.simibubi.create.foundation.render.backend.gl.attrib.CommonAttributes; +import com.simibubi.create.foundation.render.backend.gl.attrib.IAttribSpec; import com.simibubi.create.foundation.render.backend.gl.attrib.IVertexAttrib; import com.simibubi.create.foundation.render.backend.gl.attrib.VertexAttribSpec; @@ -22,7 +23,7 @@ public enum RotatingVertexAttributes implements IVertexAttrib { } @Override - public VertexAttribSpec attribSpec() { + public IAttribSpec attribSpec() { return spec; } diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/SingleRotatingInstance.java b/src/main/java/com/simibubi/create/content/contraptions/base/SingleRotatingInstance.java index 65996958c..baa9d10f2 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/SingleRotatingInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/SingleRotatingInstance.java @@ -28,7 +28,7 @@ public class SingleRotatingInstance extends KineticTileInstance model = renderMaterial.getModel(AllBlockPartials.DRILL_HEAD, state); - model.setupInstance(data -> { + model.createInstance(data -> { Direction facing = state.get(DrillBlock.FACING); float eulerX = AngleHelper.verticalAngle(facing) + ((facing.getAxis() == Direction.Axis.Y) ? 180 : 0); float eulerY = facing.getHorizontalAngle(); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/HarvesterRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/HarvesterRenderer.java index 1dcdabde2..017fea6b9 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/HarvesterRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/HarvesterRenderer.java @@ -46,7 +46,7 @@ public class HarvesterRenderer extends SafeTileEntityRenderer model = renderMaterial.getModel(AllBlockPartials.HARVESTER_BLADE, state); - model.setupInstance(data -> { + model.createInstance(data -> { Direction facing = state.get(HORIZONTAL_FACING); float originOffset = 1 / 16f; Vector3f rotOffset = new Vector3f(0.5f, -2 * originOffset + 0.5f, originOffset + 0.5f); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/fan/FanInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/fan/FanInstance.java index c2fbf6d56..804dd22e6 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/fan/FanInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/fan/FanInstance.java @@ -42,7 +42,7 @@ public class FanInstance extends KineticTileInstance { InstancedModel fanInner = AllBlockPartials.ENCASED_FAN_INNER.renderOnDirectionalSouthRotating(modelManager, lastState, direction.getOpposite()); - shaft = shaftHalf.setupInstance(data -> { + shaft = shaftHalf.createInstance(data -> { BlockPos behind = pos.offset(direction.getOpposite()); int blockLight = world.getLightLevel(LightType.BLOCK, behind); int skyLight = world.getLightLevel(LightType.SKY, behind); @@ -54,7 +54,7 @@ public class FanInstance extends KineticTileInstance { .setBlockLight(blockLight) .setSkyLight(skyLight); }); - fan = fanInner.setupInstance(data -> { + fan = fanInner.createInstance(data -> { BlockPos inFront = pos.offset(direction); int blockLight = world.getLightLevel(LightType.BLOCK, inFront); int skyLight = world.getLightLevel(LightType.SKY, inFront); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlyWheelInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlyWheelInstance.java index f49c7dbef..2dcde88a6 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlyWheelInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlyWheelInstance.java @@ -40,7 +40,7 @@ public class FlyWheelInstance extends KineticTileInstance { Direction.Axis axis = ((IRotate) lastState.getBlock()).getRotationAxis(lastState); Consumer setup = setupFunc(tile.getSpeed(), axis); - shaft = shaftModel().setupInstance(setup); + shaft = shaftModel().createInstance(setup); // wheel = wheelModel().setupInstance(setup); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/StickerInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/StickerInstance.java new file mode 100644 index 000000000..60c9e199d --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/StickerInstance.java @@ -0,0 +1,80 @@ +package com.simibubi.create.content.contraptions.components.structureMovement.chassis; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.simibubi.create.AllBlockPartials; +import com.simibubi.create.foundation.render.backend.RenderMaterials; +import com.simibubi.create.foundation.render.backend.instancing.*; +import com.simibubi.create.foundation.render.backend.instancing.impl.TransformData; +import com.simibubi.create.foundation.utility.AngleHelper; +import com.simibubi.create.foundation.utility.AnimationTickHolder; +import com.simibubi.create.foundation.utility.MatrixStacker; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.LightTexture; +import net.minecraft.tileentity.TileEntityType; +import net.minecraft.util.Direction; +import net.minecraft.world.LightType; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.fml.DistExecutor; + +public class StickerInstance extends TileEntityInstance implements ITickableInstance { + public static void register(TileEntityType type) { + DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> + InstancedTileRenderRegistry.instance.register(type, StickerInstance::new)); + } + + float lastOffset = Float.NaN; + + private InstanceKey head; + + public StickerInstance(InstancedTileRenderer modelManager, StickerTileEntity tile) { + super(modelManager, tile); + } + + @Override + protected void init() { + head = modelManager.getMaterial(RenderMaterials.MODELS).getModel(AllBlockPartials.STICKER_HEAD, lastState).createInstance(); + + updateLight(); + } + + @Override + public void tick() { + lastState = world.getBlockState(pos); + + float offset = tile.piston.getValue(AnimationTickHolder.getPartialTicks()); + + if (tile.getWorld() != Minecraft.getInstance().world) + offset = lastState.get(StickerBlock.EXTENDED) ? 1 : 0; + + if (Math.abs(offset - lastOffset) < 1e-4) + return; + + Direction facing = lastState.get(StickerBlock.FACING); + MatrixStack stack = new MatrixStack(); + MatrixStacker.of(stack) + .translate(getFloatingPos()) + .nudge(tile.hashCode()) + .centre() + .rotateY(AngleHelper.horizontalAngle(facing)) + .rotateX(AngleHelper.verticalAngle(facing) + 90) + .unCentre() + .translate(0, (offset * offset) * 4 / 16f, 0); + + head.getInstance() + .setTransform(stack); + + lastOffset = offset; + } + + @Override + public void updateLight() { + head.getInstance() + .setBlockLight((byte) (world.getLightLevel(LightType.BLOCK, pos) << 4)) + .setSkyLight((byte) (world.getLightLevel(LightType.SKY, pos) << 4)); + } + + @Override + public void remove() { + head.delete(); + } +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/StickerRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/StickerRenderer.java index e1b3e2741..91064b937 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/StickerRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/StickerRenderer.java @@ -3,6 +3,7 @@ package com.simibubi.create.content.contraptions.components.structureMovement.ch import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.AllBlockPartials; import com.simibubi.create.foundation.render.SuperByteBuffer; +import com.simibubi.create.foundation.render.backend.FastRenderDispatcher; import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer; import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.AnimationTickHolder; @@ -24,6 +25,9 @@ public class StickerRenderer extends SafeTileEntityRenderer { @Override protected void renderSafe(StickerTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay) { + + if (FastRenderDispatcher.available(te.getWorld())) return; + BlockState state = te.getBlockState(); SuperByteBuffer head = AllBlockPartials.STICKER_HEAD.renderOn(state); float offset = te.piston.getValue(AnimationTickHolder.getPartialTicks()); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/StickerTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/StickerTileEntity.java index b79977b04..8d0886951 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/StickerTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/StickerTileEntity.java @@ -4,8 +4,10 @@ import java.util.List; import com.simibubi.create.AllBlocks; import com.simibubi.create.AllSoundEvents; +import com.simibubi.create.CreateClient; import com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueEntity; import com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueItem; +import com.simibubi.create.foundation.render.backend.instancing.IInstanceRendered; import com.simibubi.create.foundation.tileEntity.SmartTileEntity; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; import com.simibubi.create.foundation.utility.LerpedFloat; @@ -21,7 +23,7 @@ import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.fml.DistExecutor; -public class StickerTileEntity extends SmartTileEntity { +public class StickerTileEntity extends SmartTileEntity implements IInstanceRendered { LerpedFloat piston; boolean update; @@ -41,6 +43,7 @@ public class StickerTileEntity extends SmartTileEntity { if (!world.isRemote) return; piston.startWithValue(isBlockStateExtended() ? 1 : 0); + CreateClient.kineticRenderer.add(this); } public boolean isBlockStateExtended() { @@ -91,4 +94,8 @@ public class StickerTileEntity extends SmartTileEntity { 0.35F, attach ? 0.75F : 0.2f); } + @Override + public void onChunkLightUpdate() { + CreateClient.kineticRenderer.onLightUpdate(this); + } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryPinionInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryPinionInstance.java new file mode 100644 index 000000000..adb7cc56f --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryPinionInstance.java @@ -0,0 +1,99 @@ +package com.simibubi.create.content.contraptions.components.structureMovement.gantry; + +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.relays.encased.ShaftInstance; +import com.simibubi.create.foundation.render.backend.RenderMaterials; +import com.simibubi.create.foundation.render.backend.instancing.ITickableInstance; +import com.simibubi.create.foundation.render.backend.instancing.InstanceKey; +import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderRegistry; +import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; +import com.simibubi.create.foundation.render.backend.instancing.impl.TransformData; +import com.simibubi.create.foundation.utility.AngleHelper; +import com.simibubi.create.foundation.utility.Iterate; +import com.simibubi.create.foundation.utility.MatrixStacker; +import net.minecraft.client.renderer.LightTexture; +import net.minecraft.client.renderer.Vector3f; +import net.minecraft.tileentity.TileEntityType; +import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.LightType; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.fml.DistExecutor; + +public class GantryPinionInstance extends ShaftInstance implements ITickableInstance { + public static void register(TileEntityType type) { + DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> + InstancedTileRenderRegistry.instance.register(type, GantryPinionInstance::new)); + } + + private InstanceKey gantryCogs; + + public GantryPinionInstance(InstancedTileRenderer dispatcher, KineticTileEntity tile) { + super(dispatcher, tile); + } + + @Override + protected void init() { + super.init(); + + gantryCogs = modelManager.getMaterial(RenderMaterials.MODELS) + .getModel(AllBlockPartials.GANTRY_COGS, lastState) + .createInstance(); + + updateLight(); + } + + @Override + public void tick() { + lastState = world.getBlockState(pos); + Direction facing = lastState.get(GantryPinionBlock.FACING); + Boolean alongFirst = lastState.get(GantryPinionBlock.AXIS_ALONG_FIRST_COORDINATE); + Direction.Axis rotationAxis = KineticTileEntityRenderer.getRotationAxisOf(tile); + BlockPos visualPos = facing.getAxisDirection() == Direction.AxisDirection.POSITIVE ? tile.getPos() + : tile.getPos() + .offset(facing.getOpposite()); + float angleForTe = GantryPinionRenderer.getAngleForTe(tile, visualPos, rotationAxis); + + Direction.Axis gantryAxis = Direction.Axis.X; + for (Direction.Axis axis : Iterate.axes) + if (axis != rotationAxis && axis != facing.getAxis()) + gantryAxis = axis; + + if (gantryAxis == Direction.Axis.Z) + if (facing == Direction.DOWN) + angleForTe *= -1; + if (gantryAxis == Direction.Axis.Y) + if (facing == Direction.NORTH || facing == Direction.EAST) + angleForTe *= -1; + + MatrixStack ms = new MatrixStack(); + MatrixStacker.of(ms) + .translate(getFloatingPos()) + .centre() + .rotateY(AngleHelper.horizontalAngle(facing)) + .rotateX(facing == Direction.UP ? 0 : facing == Direction.DOWN ? 180 : 90) + .rotateY(alongFirst ^ facing.getAxis() == Direction.Axis.Z ? 90 : 0) + .translate(0, -9 / 16f, 0) + .multiply(Vector3f.POSITIVE_X.getRadialQuaternion(-angleForTe)) + .translate(0, 9 / 16f, 0) + .unCentre(); + + gantryCogs.getInstance().setTransform(ms); + } + + @Override + public void updateLight() { + gantryCogs.getInstance() + .setBlockLight((byte) (world.getLightLevel(LightType.BLOCK, pos) << 4)) + .setSkyLight((byte) (world.getLightLevel(LightType.SKY, pos) << 4)); + } + + @Override + public void remove() { + super.remove(); + gantryCogs.delete(); + } +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryPinionRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryPinionRenderer.java index eb5be4809..b92e2aa8b 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryPinionRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryPinionRenderer.java @@ -5,6 +5,7 @@ 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.render.SuperByteBuffer; +import com.simibubi.create.foundation.render.backend.FastRenderDispatcher; import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.Iterate; @@ -30,6 +31,9 @@ public class GantryPinionRenderer extends KineticTileEntityRenderer { protected void renderSafe(KineticTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay) { super.renderSafe(te, partialTicks, ms, buffer, light, overlay); + + if (FastRenderDispatcher.available(te.getWorld())) return; + BlockState state = te.getBlockState(); Direction facing = state.get(GantryPinionBlock.FACING); Boolean alongFirst = state.get(GantryPinionBlock.AXIS_ALONG_FIRST_COORDINATE); 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 f5fe4a9b9..6cd01e76b 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 @@ -6,19 +6,23 @@ import com.simibubi.create.content.contraptions.components.actors.RotatingActorM import com.simibubi.create.content.contraptions.relays.belt.BeltInstancedModel; import com.simibubi.create.content.logistics.block.FlapInstancedModel; import com.simibubi.create.foundation.render.AllProgramSpecs; +import com.simibubi.create.foundation.render.backend.RenderMaterials; import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; import com.simibubi.create.foundation.render.backend.instancing.RenderMaterial; +import com.simibubi.create.foundation.render.backend.instancing.impl.TransformedInstancedModel; import net.minecraft.util.math.BlockPos; public class ContraptionKineticRenderer extends InstancedTileRenderer { @Override public void registerMaterials() { - materials.put(KineticRenderMaterials.BELTS, new RenderMaterial<>(this, AllProgramSpecs.CONTRAPTION_BELT, BeltInstancedModel::new)); - materials.put(KineticRenderMaterials.ROTATING, new RenderMaterial<>(this, AllProgramSpecs.CONTRAPTION_ROTATING, RotatingInstancedModel::new)); - materials.put(KineticRenderMaterials.FLAPS, new RenderMaterial<>(this, AllProgramSpecs.CONTRAPTION_FLAPS, FlapInstancedModel::new)); - materials.put(KineticRenderMaterials.ACTORS, new RenderMaterial<>(this, AllProgramSpecs.CONTRAPTION_ACTOR, RotatingActorModel::new)); + materials.put(RenderMaterials.MODELS, new RenderMaterial<>(this, AllProgramSpecs.C_MODEL, TransformedInstancedModel::new)); + + materials.put(KineticRenderMaterials.BELTS, new RenderMaterial<>(this, AllProgramSpecs.C_BELT, BeltInstancedModel::new)); + materials.put(KineticRenderMaterials.ROTATING, new RenderMaterial<>(this, AllProgramSpecs.C_ROTATING, RotatingInstancedModel::new)); + materials.put(KineticRenderMaterials.FLAPS, new RenderMaterial<>(this, AllProgramSpecs.C_FLAPS, FlapInstancedModel::new)); + materials.put(KineticRenderMaterials.ACTORS, new RenderMaterial<>(this, AllProgramSpecs.C_ACTOR, RotatingActorModel::new)); } @Override diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionRenderDispatcher.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionRenderDispatcher.java index 346c3e244..aeff61450 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionRenderDispatcher.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionRenderDispatcher.java @@ -56,8 +56,6 @@ public class ContraptionRenderDispatcher { public static final Compartment> CONTRAPTION = new Compartment<>(); protected static PlacementSimulationWorld renderWorld; - private static boolean firstLayer = true; - public static void notifyLightUpdate(ILightReader world, LightType type, SectionPos pos) { for (RenderedContraption renderer : renderers.values()) { renderer.getLighter().lightVolume.notifyLightUpdate(world, type, pos); @@ -70,10 +68,6 @@ public class ContraptionRenderDispatcher { } } - public static void renderTick() { - firstLayer = true; - } - public static void renderTileEntities(World world, Contraption c, MatrixStack ms, MatrixStack msLocal, IRenderTypeBuffer buffer) { PlacementSimulationWorld renderWorld = null; @@ -120,7 +114,7 @@ public class ContraptionRenderDispatcher { GL13.glActiveTexture(GL40.GL_TEXTURE4); // the shaders expect light volumes to be in texture 4 if (Backend.canUseVBOs()) { - ContraptionProgram structureShader = Backend.getProgram(AllProgramSpecs.CONTRAPTION_STRUCTURE); + ContraptionProgram structureShader = Backend.getProgram(AllProgramSpecs.C_STRUCTURE); structureShader.bind(viewProjection, camX, camY, camZ, FastRenderDispatcher.getDebugMode()); for (RenderedContraption renderer : renderers.values()) { renderer.doRenderLayer(layer, structureShader); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionVertexAttributes.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionVertexAttributes.java index 6bfbf8af7..53e9931f9 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionVertexAttributes.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionVertexAttributes.java @@ -1,6 +1,7 @@ package com.simibubi.create.content.contraptions.components.structureMovement.render; import com.simibubi.create.foundation.render.backend.gl.attrib.CommonAttributes; +import com.simibubi.create.foundation.render.backend.gl.attrib.IAttribSpec; import com.simibubi.create.foundation.render.backend.gl.attrib.IVertexAttrib; import com.simibubi.create.foundation.render.backend.gl.attrib.VertexAttribSpec; @@ -26,7 +27,7 @@ public enum ContraptionVertexAttributes implements IVertexAttrib { } @Override - public VertexAttribSpec attribSpec() { + public IAttribSpec attribSpec() { return spec; } 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 c86f70336..23cdc0c55 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 @@ -5,6 +5,7 @@ import java.util.HashMap; import java.util.List; import java.util.Random; +import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; import org.apache.commons.lang3.tuple.MutablePair; import org.lwjgl.opengl.GL11; @@ -19,7 +20,6 @@ import com.simibubi.create.content.contraptions.components.structureMovement.Mov import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext; import com.simibubi.create.foundation.render.backend.Backend; import com.simibubi.create.foundation.render.backend.instancing.IInstanceRendered; -import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; import com.simibubi.create.foundation.render.backend.instancing.RenderMaterial; import com.simibubi.create.foundation.render.backend.light.GridAlignedBB; import com.simibubi.create.foundation.utility.AnimationTickHolder; @@ -100,6 +100,8 @@ public class RenderedContraption { } public void beginFrame(double camX, double camY, double camZ) { + kinetics.beginFrame(camX, camY, camZ); + AbstractContraptionEntity entity = contraption.entity; float pt = AnimationTickHolder.getPartialTicks(); diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltInstance.java b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltInstance.java index 7b8c7997a..3e28761c9 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltInstance.java @@ -74,7 +74,7 @@ public class BeltInstance extends KineticTileInstance { InstancedModel beltModel = beltPartial.renderOnBelt(modelManager, lastState); Consumer setupFunc = setupFunc(bottom, spriteShift); - keys.add(beltModel.setupInstance(setupFunc)); + keys.add(beltModel.createInstance(setupFunc)); if (diagonal) break; } @@ -82,7 +82,7 @@ public class BeltInstance extends KineticTileInstance { if (tile.hasPulley()) { InstancedModel pulleyModel = getPulleyModel(); - pulleyKey = pulleyModel.setupInstance(setupFunc(tile.getSpeed(), getRotationAxis())); + pulleyKey = pulleyModel.createInstance(setupFunc(tile.getSpeed(), getRotationAxis())); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltVertexAttributes.java b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltVertexAttributes.java index ca2125848..678b29c73 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltVertexAttributes.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltVertexAttributes.java @@ -1,6 +1,7 @@ package com.simibubi.create.content.contraptions.relays.belt; import com.simibubi.create.foundation.render.backend.gl.attrib.CommonAttributes; +import com.simibubi.create.foundation.render.backend.gl.attrib.IAttribSpec; import com.simibubi.create.foundation.render.backend.gl.attrib.IVertexAttrib; import com.simibubi.create.foundation.render.backend.gl.attrib.VertexAttribSpec; @@ -25,7 +26,7 @@ public enum BeltVertexAttributes implements IVertexAttrib { } @Override - public VertexAttribSpec attribSpec() { + public IAttribSpec attribSpec() { return spec; } diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SplitShaftInstance.java b/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SplitShaftInstance.java index 1ac7476bb..f21f5d4ff 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SplitShaftInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SplitShaftInstance.java @@ -45,7 +45,7 @@ public class SplitShaftInstance extends KineticTileInstance { InstancedModel shaft = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(modelManager, lastState, direction); - InstanceKey key = shaft.setupInstance(data -> { + InstanceKey key = shaft.createInstance(data -> { data.setBlockLight(blockLight) .setSkyLight(skyLight) .setRotationalSpeed(getSpeed(direction)) diff --git a/src/main/java/com/simibubi/create/content/logistics/block/FlapVertexAttributes.java b/src/main/java/com/simibubi/create/content/logistics/block/FlapVertexAttributes.java index d32768a3f..6bf8a85d5 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/FlapVertexAttributes.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/FlapVertexAttributes.java @@ -1,6 +1,7 @@ package com.simibubi.create.content.logistics.block; import com.simibubi.create.foundation.render.backend.gl.attrib.CommonAttributes; +import com.simibubi.create.foundation.render.backend.gl.attrib.IAttribSpec; import com.simibubi.create.foundation.render.backend.gl.attrib.IVertexAttrib; import com.simibubi.create.foundation.render.backend.gl.attrib.VertexAttribSpec; @@ -29,7 +30,7 @@ public enum FlapVertexAttributes implements IVertexAttrib { } @Override - public VertexAttribSpec attribSpec() { + public IAttribSpec attribSpec() { return spec; } diff --git a/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BeltTunnelInstance.java b/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BeltTunnelInstance.java index afbfcc6a0..d2f6fa318 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BeltTunnelInstance.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BeltTunnelInstance.java @@ -53,7 +53,7 @@ public class BeltTunnelInstance extends TileEntityInstance float intensity = segment == 3 ? 1.5f : segment + 1; float segmentOffset = -3 / 16f * segment; - flaps.add(model.setupInstance(flapData -> { + flaps.add(model.createInstance(flapData -> { flapData.setPosition(pos) .setSegmentOffset(segmentOffset, 0, 0) .setBlockLight(blockLight) diff --git a/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelInstance.java b/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelInstance.java index b91a5b37f..cf5b54e6a 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelInstance.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelInstance.java @@ -48,15 +48,15 @@ public class FunnelInstance extends TileEntityInstance impleme float intensity = segment == 3 ? 1.5f : segment + 1; float segmentOffset = -3 / 16f * segment; - flaps.add(model.setupInstance(flapData -> flapData.setPosition(pos) - .setSegmentOffset(segmentOffset, 0, -tile.getFlapOffset()) - .setBlockLight(blockLight) - .setSkyLight(skyLight) - .setHorizontalAngle(horizontalAngle) - .setFlapness(flapness) - .setFlapScale(-1) - .setPivotVoxelSpace(0, 10, 9.5f) - .setIntensity(intensity))); + flaps.add(model.createInstance(flapData -> flapData.setPosition(pos) + .setSegmentOffset(segmentOffset, 0, -tile.getFlapOffset()) + .setBlockLight(blockLight) + .setSkyLight(skyLight) + .setHorizontalAngle(horizontalAngle) + .setFlapness(flapness) + .setFlapScale(-1) + .setPivotVoxelSpace(0, 10, 9.5f) + .setIntensity(intensity))); } } diff --git a/src/main/java/com/simibubi/create/foundation/render/AllProgramSpecs.java b/src/main/java/com/simibubi/create/foundation/render/AllProgramSpecs.java index d943724d0..a07a85727 100644 --- a/src/main/java/com/simibubi/create/foundation/render/AllProgramSpecs.java +++ b/src/main/java/com/simibubi/create/foundation/render/AllProgramSpecs.java @@ -11,6 +11,7 @@ import com.simibubi.create.content.contraptions.components.structureMovement.ren import com.simibubi.create.content.contraptions.relays.belt.BeltVertexAttributes; import com.simibubi.create.content.logistics.block.FlapVertexAttributes; import com.simibubi.create.foundation.render.backend.gl.BasicProgram; +import com.simibubi.create.foundation.render.backend.gl.attrib.InstanceVertexAttributes; import com.simibubi.create.foundation.render.backend.gl.attrib.ModelVertexAttributes; import com.simibubi.create.foundation.render.backend.gl.shader.ProgramSpec; import com.simibubi.create.foundation.render.backend.gl.shader.ShaderConstants; @@ -18,12 +19,19 @@ import com.simibubi.create.foundation.render.backend.gl.shader.ShaderConstants; import net.minecraft.util.ResourceLocation; public class AllProgramSpecs { + public static final ProgramSpec MODEL = register(ProgramSpec.builder("model", BasicProgram::new) + .addAttributes(ModelVertexAttributes.class) + .addAttributes(InstanceVertexAttributes.class) + .setVert(Locations.MODEL_VERT) + .setFrag(Locations.MODEL_FRAG) + .createProgramSpec()); + public static final ProgramSpec ROTATING = register(ProgramSpec.builder("rotating", BasicProgram::new) .addAttributes(ModelVertexAttributes.class) .addAttributes(KineticVertexAttributes.class) .addAttributes(RotatingVertexAttributes.class) .setVert(Locations.ROTATING) - .setFrag(Locations.INSTANCED) + .setFrag(Locations.MODEL_FRAG) .createProgramSpec()); public static final ProgramSpec BELT = register(ProgramSpec.builder("belt", BasicProgram::new) @@ -31,58 +39,65 @@ public class AllProgramSpecs { .addAttributes(KineticVertexAttributes.class) .addAttributes(BeltVertexAttributes.class) .setVert(Locations.BELT) - .setFrag(Locations.INSTANCED) + .setFrag(Locations.MODEL_FRAG) .createProgramSpec()); public static final ProgramSpec FLAPS = register(ProgramSpec.builder("flap", BasicProgram::new) .addAttributes(ModelVertexAttributes.class) .addAttributes(FlapVertexAttributes.class) .setVert(Locations.FLAP) - .setFrag(Locations.INSTANCED) + .setFrag(Locations.MODEL_FRAG) .createProgramSpec()); + public static final ProgramSpec C_STRUCTURE = register(ProgramSpec.builder("contraption_structure", ContraptionProgram::new) + .addAttributes(ContraptionVertexAttributes.class) + .setVert(Locations.CONTRAPTION_STRUCTURE) + .setFrag(Locations.CONTRAPTION) + .createProgramSpec()); + public static final ProgramSpec C_MODEL = register(ProgramSpec.builder("contraption_model", ContraptionProgram::new) + .addAttributes(ModelVertexAttributes.class) + .addAttributes(InstanceVertexAttributes.class) + .setVert(Locations.MODEL_VERT) + .setFrag(Locations.CONTRAPTION) + .setDefines(ShaderConstants.define("CONTRAPTION")) + .createProgramSpec()); + public static final ProgramSpec C_ROTATING = register(ProgramSpec.builder("contraption_rotating", ContraptionProgram::new) + .addAttributes(ModelVertexAttributes.class) + .addAttributes(KineticVertexAttributes.class) + .addAttributes(RotatingVertexAttributes.class) + .setVert(Locations.ROTATING) + .setFrag(Locations.CONTRAPTION) + .setDefines(ShaderConstants.define("CONTRAPTION")) + .createProgramSpec()); + public static final ProgramSpec C_BELT = register(ProgramSpec.builder("contraption_belt", ContraptionProgram::new) + .addAttributes(ModelVertexAttributes.class) + .addAttributes(KineticVertexAttributes.class) + .addAttributes(BeltVertexAttributes.class) + .setVert(Locations.BELT) + .setFrag(Locations.CONTRAPTION) + .setDefines(ShaderConstants.define("CONTRAPTION")) + .createProgramSpec()); + public static final ProgramSpec C_FLAPS = register(ProgramSpec.builder("contraption_flap", ContraptionProgram::new) + .addAttributes(ModelVertexAttributes.class) + .addAttributes(FlapVertexAttributes.class) + .setVert(Locations.FLAP) + .setFrag(Locations.CONTRAPTION) + .setDefines(ShaderConstants.define("CONTRAPTION")) + .createProgramSpec()); + public static final ProgramSpec C_ACTOR = register(ProgramSpec.builder("contraption_actor", ContraptionProgram::new) + .addAttributes(ModelVertexAttributes.class) + .addAttributes(ActorVertexAttributes.class) + .setVert(Locations.CONTRAPTION_ACTOR) + .setFrag(Locations.CONTRAPTION) + .createProgramSpec()); - public static final ProgramSpec CONTRAPTION_STRUCTURE = register(ProgramSpec.builder("contraption_structure", ContraptionProgram::new) - .addAttributes(ContraptionVertexAttributes.class) - .setVert(Locations.CONTRAPTION_STRUCTURE) - .setFrag(Locations.CONTRAPTION) - .createProgramSpec()); + public static class Contraption { - public static final ProgramSpec CONTRAPTION_ROTATING = register(ProgramSpec.builder("contraption_rotating", ContraptionProgram::new) - .addAttributes(ModelVertexAttributes.class) - .addAttributes(KineticVertexAttributes.class) - .addAttributes(RotatingVertexAttributes.class) - .setVert(Locations.ROTATING) - .setFrag(Locations.CONTRAPTION) - .setDefines(ShaderConstants.define("CONTRAPTION")) - .createProgramSpec()); - - public static final ProgramSpec CONTRAPTION_BELT = register(ProgramSpec.builder("contraption_belt", ContraptionProgram::new) - .addAttributes(ModelVertexAttributes.class) - .addAttributes(KineticVertexAttributes.class) - .addAttributes(BeltVertexAttributes.class) - .setVert(Locations.BELT) - .setFrag(Locations.CONTRAPTION) - .setDefines(ShaderConstants.define("CONTRAPTION")) - .createProgramSpec()); - - public static final ProgramSpec CONTRAPTION_FLAPS = register(ProgramSpec.builder("contraption_flap", ContraptionProgram::new) - .addAttributes(ModelVertexAttributes.class) - .addAttributes(FlapVertexAttributes.class) - .setVert(Locations.FLAP) - .setFrag(Locations.CONTRAPTION) - .setDefines(ShaderConstants.define("CONTRAPTION")) - .createProgramSpec()); - - public static final ProgramSpec CONTRAPTION_ACTOR = register(ProgramSpec.builder("contraption_actor", ContraptionProgram::new) - .addAttributes(ModelVertexAttributes.class) - .addAttributes(ActorVertexAttributes.class) - .setVert(Locations.CONTRAPTION_ACTOR) - .setFrag(Locations.CONTRAPTION) - .createProgramSpec()); + } public static class Locations { - public static final ResourceLocation INSTANCED = loc("instanced.frag"); + public static final ResourceLocation MODEL_FRAG = loc("model.frag"); + public static final ResourceLocation MODEL_VERT = loc("model.vert"); public static final ResourceLocation CONTRAPTION = loc("contraption.frag"); public static final ResourceLocation ROTATING = loc("rotating.vert"); diff --git a/src/main/java/com/simibubi/create/foundation/render/KineticRenderer.java b/src/main/java/com/simibubi/create/foundation/render/KineticRenderer.java index 68cb7367e..7446f86ff 100644 --- a/src/main/java/com/simibubi/create/foundation/render/KineticRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/render/KineticRenderer.java @@ -6,11 +6,13 @@ import com.simibubi.create.content.contraptions.base.KineticRenderMaterials; import com.simibubi.create.content.contraptions.base.RotatingInstancedModel; import com.simibubi.create.content.contraptions.relays.belt.BeltInstancedModel; import com.simibubi.create.content.logistics.block.FlapInstancedModel; +import com.simibubi.create.foundation.render.backend.RenderMaterials; import com.simibubi.create.foundation.render.backend.gl.BasicProgram; import com.simibubi.create.foundation.render.backend.gl.shader.ShaderCallback; import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; import com.simibubi.create.foundation.render.backend.instancing.RenderMaterial; +import com.simibubi.create.foundation.render.backend.instancing.impl.TransformedInstancedModel; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.Matrix4f; import net.minecraft.client.renderer.RenderType; @@ -25,6 +27,8 @@ public class KineticRenderer extends InstancedTileRenderer { @Override public void registerMaterials() { + materials.put(RenderMaterials.MODELS, new RenderMaterial<>(this, AllProgramSpecs.MODEL, TransformedInstancedModel::new)); + materials.put(KineticRenderMaterials.BELTS, new RenderMaterial<>(this, AllProgramSpecs.BELT, BeltInstancedModel::new)); materials.put(KineticRenderMaterials.ROTATING, new RenderMaterial<>(this, AllProgramSpecs.ROTATING, RotatingInstancedModel::new)); materials.put(KineticRenderMaterials.FLAPS, new RenderMaterial<>(this, AllProgramSpecs.FLAPS, FlapInstancedModel::new)); diff --git a/src/main/java/com/simibubi/create/foundation/render/RenderMath.java b/src/main/java/com/simibubi/create/foundation/render/RenderMath.java deleted file mode 100644 index 3839ff718..000000000 --- a/src/main/java/com/simibubi/create/foundation/render/RenderMath.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.simibubi.create.foundation.render; - -public class RenderMath { - public static int nextPowerOf2(int a) { - int h = Integer.highestOneBit(a); - return (h == a) ? h : (h << 1); - } - - public static boolean isPowerOf2(int n) { - int b = n & (n - 1); - return b == 0 && n != 0; - } -} diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/Backend.java b/src/main/java/com/simibubi/create/foundation/render/backend/Backend.java index f495f3054..159122f24 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/Backend.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/Backend.java @@ -31,7 +31,7 @@ import net.minecraftforge.resource.ISelectiveResourceReloadListener; import net.minecraftforge.resource.VanillaResourceType; public class Backend { - public static final Boolean SHADER_DEBUG_OUTPUT = false; + public static final Boolean SHADER_DEBUG_OUTPUT = true; public static final Logger log = LogManager.getLogger(Backend.class); public static final FloatBuffer MATRIX_BUFFER = MemoryUtil.memAllocFloat(16); diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/RenderMaterials.java b/src/main/java/com/simibubi/create/foundation/render/backend/RenderMaterials.java new file mode 100644 index 000000000..7cc06e520 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/render/backend/RenderMaterials.java @@ -0,0 +1,10 @@ +package com.simibubi.create.foundation.render.backend; + +import com.simibubi.create.content.contraptions.components.actors.ContraptionActorData; +import com.simibubi.create.foundation.render.backend.instancing.MaterialType; +import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; +import com.simibubi.create.foundation.render.backend.instancing.impl.TransformData; + +public class RenderMaterials { + public static final MaterialType> MODELS = new MaterialType<>(); +} diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/RenderUtil.java b/src/main/java/com/simibubi/create/foundation/render/backend/RenderUtil.java new file mode 100644 index 000000000..b0de2dea6 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/render/backend/RenderUtil.java @@ -0,0 +1,56 @@ +package com.simibubi.create.foundation.render.backend; + +import net.minecraft.client.renderer.Matrix3f; +import net.minecraft.client.renderer.Matrix4f; + +import java.nio.ByteBuffer; +import java.nio.FloatBuffer; + +public class RenderUtil { + public static int nextPowerOf2(int a) { + int h = Integer.highestOneBit(a); + return (h == a) ? h : (h << 1); + } + + public static boolean isPowerOf2(int n) { + int b = n & (n - 1); + return b == 0 && n != 0; + } + + // GPUs want matrices in column major order. + + public static void writeMat3(ByteBuffer buf, Matrix3f mat) { + buf.putFloat(mat.a00); + buf.putFloat(mat.a10); + buf.putFloat(mat.a20); + buf.putFloat(mat.a01); + buf.putFloat(mat.a11); + buf.putFloat(mat.a21); + buf.putFloat(mat.a02); + buf.putFloat(mat.a12); + buf.putFloat(mat.a22); + } + + public static void writeMat4(ByteBuffer buf, Matrix4f mat) { + buf.putFloat(mat.a00); + buf.putFloat(mat.a10); + buf.putFloat(mat.a20); + buf.putFloat(mat.a30); + buf.putFloat(mat.a01); + buf.putFloat(mat.a11); + buf.putFloat(mat.a21); + buf.putFloat(mat.a31); + buf.putFloat(mat.a02); + buf.putFloat(mat.a12); + buf.putFloat(mat.a22); + buf.putFloat(mat.a32); + buf.putFloat(mat.a03); + buf.putFloat(mat.a13); + buf.putFloat(mat.a23); + buf.putFloat(mat.a33); + + + + + } +} diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/gl/attrib/CommonAttributes.java b/src/main/java/com/simibubi/create/foundation/render/backend/gl/attrib/CommonAttributes.java index d3fd9d48e..f6daa58c6 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/gl/attrib/CommonAttributes.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/gl/attrib/CommonAttributes.java @@ -4,7 +4,6 @@ import com.simibubi.create.foundation.render.backend.gl.GlPrimitiveType; public class CommonAttributes { - public static final VertexAttribSpec MAT4 = new VertexAttribSpec(GlPrimitiveType.FLOAT, 16); public static final VertexAttribSpec VEC4 = new VertexAttribSpec(GlPrimitiveType.FLOAT, 4); public static final VertexAttribSpec VEC3 = new VertexAttribSpec(GlPrimitiveType.FLOAT, 3); public static final VertexAttribSpec VEC2 = new VertexAttribSpec(GlPrimitiveType.FLOAT, 2); diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/gl/attrib/IAttribSpec.java b/src/main/java/com/simibubi/create/foundation/render/backend/gl/attrib/IAttribSpec.java new file mode 100644 index 000000000..f16d1deb1 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/render/backend/gl/attrib/IAttribSpec.java @@ -0,0 +1,12 @@ +package com.simibubi.create.foundation.render.backend.gl.attrib; + +import org.lwjgl.opengl.GL20; + +public interface IAttribSpec { + + void vertexAttribPointer(int stride, int index, int pointer); + + int getSize(); + + int getAttributeCount(); +} diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/gl/attrib/IVertexAttrib.java b/src/main/java/com/simibubi/create/foundation/render/backend/gl/attrib/IVertexAttrib.java index 5c77620f9..ee122db00 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/gl/attrib/IVertexAttrib.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/gl/attrib/IVertexAttrib.java @@ -4,7 +4,7 @@ public interface IVertexAttrib { String attribName(); - VertexAttribSpec attribSpec(); + IAttribSpec attribSpec(); int getDivisor(); diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/gl/attrib/InstanceVertexAttributes.java b/src/main/java/com/simibubi/create/foundation/render/backend/gl/attrib/InstanceVertexAttributes.java new file mode 100644 index 000000000..cf1702532 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/render/backend/gl/attrib/InstanceVertexAttributes.java @@ -0,0 +1,36 @@ +package com.simibubi.create.foundation.render.backend.gl.attrib; + +public enum InstanceVertexAttributes implements IVertexAttrib { + TRANSFORM("aTransform", MatrixAttributes.MAT4), + NORMAL_MAT("aNormalMat", MatrixAttributes.MAT3), + LIGHT("aLight", CommonAttributes.LIGHT), + ; + + private final String name; + private final IAttribSpec spec; + + InstanceVertexAttributes(String name, IAttribSpec spec) { + this.name = name; + this.spec = spec; + } + + @Override + public String attribName() { + return name; + } + + @Override + public IAttribSpec attribSpec() { + return spec; + } + + @Override + public int getDivisor() { + return 0; + } + + @Override + public int getBufferIndex() { + return 0; + } +} diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/gl/attrib/MatrixAttributes.java b/src/main/java/com/simibubi/create/foundation/render/backend/gl/attrib/MatrixAttributes.java new file mode 100644 index 000000000..f7eb4d85f --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/render/backend/gl/attrib/MatrixAttributes.java @@ -0,0 +1,36 @@ +package com.simibubi.create.foundation.render.backend.gl.attrib; + +import com.simibubi.create.foundation.render.backend.gl.GlPrimitiveType; +import org.lwjgl.opengl.GL20; + +public enum MatrixAttributes implements IAttribSpec { + MAT3(3, 3), + MAT4(4, 4), + ; + + private final int rows; + private final int cols; + + MatrixAttributes(int rows, int cols) { + this.rows = rows; + this.cols = cols; + } + + @Override + public void vertexAttribPointer(int stride, int index, int pointer) { + for (int i = 0; i < rows; i++) { + long attribPointer = pointer + (long) i * cols * GlPrimitiveType.FLOAT.getSize(); + GL20.glVertexAttribPointer(index + i, cols, GlPrimitiveType.FLOAT.getGlConstant(), false, stride, attribPointer); + } + } + + @Override + public int getSize() { + return GlPrimitiveType.FLOAT.getSize() * rows * cols; + } + + @Override + public int getAttributeCount() { + return rows; + } +} diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/gl/attrib/ModelVertexAttributes.java b/src/main/java/com/simibubi/create/foundation/render/backend/gl/attrib/ModelVertexAttributes.java index 960289fd6..5fec24349 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/gl/attrib/ModelVertexAttributes.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/gl/attrib/ModelVertexAttributes.java @@ -20,7 +20,7 @@ public enum ModelVertexAttributes implements IVertexAttrib { } @Override - public VertexAttribSpec attribSpec() { + public IAttribSpec attribSpec() { return spec; } diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/gl/attrib/VertexAttribSpec.java b/src/main/java/com/simibubi/create/foundation/render/backend/gl/attrib/VertexAttribSpec.java index 1af7dc3a6..82cdac6fc 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/gl/attrib/VertexAttribSpec.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/gl/attrib/VertexAttribSpec.java @@ -4,7 +4,7 @@ import org.lwjgl.opengl.GL20; import com.simibubi.create.foundation.render.backend.gl.GlPrimitiveType; -public class VertexAttribSpec { +public class VertexAttribSpec implements IAttribSpec { private final GlPrimitiveType type; private final int count; @@ -24,14 +24,17 @@ public class VertexAttribSpec { this.normalized = normalized; } + @Override public void vertexAttribPointer(int stride, int index, int pointer) { GL20.glVertexAttribPointer(index, count, type.getGlConstant(), normalized, stride, pointer); } + @Override public int getSize() { return size; } + @Override public int getAttributeCount() { return attributeCount; } diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/gl/attrib/VertexFormat.java b/src/main/java/com/simibubi/create/foundation/render/backend/gl/attrib/VertexFormat.java index 3929e3354..4541a9205 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/gl/attrib/VertexFormat.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/gl/attrib/VertexFormat.java @@ -15,7 +15,7 @@ public class VertexFormat { int numAttributes = 0, stride = 0; for (IVertexAttrib attrib : allAttributes) { - VertexAttribSpec spec = attrib.attribSpec(); + IAttribSpec spec = attrib.attribSpec(); numAttributes += spec.getAttributeCount(); stride += spec.getSize(); } @@ -34,7 +34,7 @@ public class VertexFormat { public void vertexAttribPointers(int index) { int offset = 0; for (IVertexAttrib attrib : this.allAttributes) { - VertexAttribSpec spec = attrib.attribSpec(); + IAttribSpec spec = attrib.attribSpec(); spec.vertexAttribPointer(stride, index, offset); index += spec.getAttributeCount(); offset += spec.getSize(); diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstanceKey.java b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstanceKey.java index 166bf8e56..e25440f75 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstanceKey.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstanceKey.java @@ -25,6 +25,10 @@ public class InstanceKey { model.modifyInstance(this, edit); } + public D getInstance() { + return model.getInstance(this); + } + public void delete() { model.deleteInstance(this); } diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedModel.java b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedModel.java index 2a0255eab..ab1b292a7 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedModel.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedModel.java @@ -6,11 +6,11 @@ import java.util.*; import java.util.function.Consumer; import com.simibubi.create.foundation.render.backend.Backend; +import com.simibubi.create.foundation.render.backend.RenderUtil; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL15; import org.lwjgl.opengl.GL20; -import com.simibubi.create.foundation.render.RenderMath; import com.simibubi.create.foundation.render.backend.BufferedModel; import com.simibubi.create.foundation.render.backend.gl.GlBuffer; import com.simibubi.create.foundation.render.backend.gl.GlVertexArray; @@ -95,7 +95,19 @@ public abstract class InstancedModel extends BufferedMod markIndexChanged(key.index); } - public synchronized InstanceKey setupInstance(Consumer setup) { + public synchronized InstanceKey createInstance() { + D instanceData = newInstance(); + + InstanceKey key = new InstanceKey<>(this, data.size()); + data.add(instanceData); + keys.add(key); + + markIndexChanged(key.index); + + return key; + } + + public synchronized InstanceKey createInstance(Consumer setup) { D instanceData = newInstance(); setup.accept(instanceData); @@ -124,7 +136,7 @@ public abstract class InstancedModel extends BufferedMod int stride = instanceFormat.getStride(); int newInstanceCount = instanceCount(); - int instanceSize = RenderMath.nextPowerOf2((newInstanceCount + 1) * stride); + int instanceSize = RenderUtil.nextPowerOf2((newInstanceCount + 1) * stride); instanceVBO.with(vbo -> { // this probably changes enough that it's not worth reallocating the entire buffer every time. diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/TileEntityInstance.java b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/TileEntityInstance.java index 8683832da..32537476e 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/TileEntityInstance.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/TileEntityInstance.java @@ -53,4 +53,8 @@ public abstract class TileEntityInstance { * Call {@link InstanceKey#delete()} on all acquired keys. */ public abstract void remove(); + + public BlockPos getFloatingPos() { + return pos.subtract(modelManager.getOriginCoordinate()); + } } diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/TransformData.java b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/TransformData.java new file mode 100644 index 000000000..115463df7 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/TransformData.java @@ -0,0 +1,56 @@ +package com.simibubi.create.foundation.render.backend.instancing.impl; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.simibubi.create.foundation.render.backend.RenderUtil; +import com.simibubi.create.foundation.render.backend.instancing.InstanceData; +import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; +import net.minecraft.client.renderer.Matrix3f; +import net.minecraft.client.renderer.Matrix4f; + +import java.nio.ByteBuffer; + +public class TransformData extends InstanceData { + + private Matrix4f modelMat; + private Matrix3f normalMat; + + private byte blockLight; + private byte skyLight; + + public TransformData(InstancedModel owner) { + super(owner); + } + + public TransformData setModelMat(Matrix4f modelMat) { + this.modelMat = modelMat; + return this; + } + + public TransformData setNormalMat(Matrix3f normalMat) { + this.normalMat = normalMat; + return this; + } + + public TransformData setTransform(MatrixStack stack) { + this.modelMat = stack.peek().getModel(); + this.normalMat = stack.peek().getNormal(); + return this; + } + + public TransformData setBlockLight(byte blockLight) { + this.blockLight = blockLight; + return this; + } + + public TransformData setSkyLight(byte skyLight) { + this.skyLight = skyLight; + return this; + } + + @Override + public void write(ByteBuffer buf) { + RenderUtil.writeMat4(buf, modelMat); + RenderUtil.writeMat3(buf, normalMat); + buf.put(new byte[] { blockLight, skyLight }); + } +} diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/TransformedInstancedModel.java b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/TransformedInstancedModel.java new file mode 100644 index 000000000..2335a386f --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/TransformedInstancedModel.java @@ -0,0 +1,25 @@ +package com.simibubi.create.foundation.render.backend.instancing.impl; + +import com.simibubi.create.foundation.render.backend.gl.attrib.InstanceVertexAttributes; +import com.simibubi.create.foundation.render.backend.gl.attrib.VertexFormat; +import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; +import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; +import net.minecraft.client.renderer.BufferBuilder; + +public class TransformedInstancedModel extends InstancedModel { + public static final VertexFormat INSTANCE_FORMAT = VertexFormat.builder().addAttributes(InstanceVertexAttributes.class).build(); + + public TransformedInstancedModel(InstancedTileRenderer renderer, BufferBuilder buf) { + super(renderer, buf); + } + + @Override + protected TransformData newInstance() { + return new TransformData(this); + } + + @Override + protected VertexFormat getInstanceFormat() { + return INSTANCE_FORMAT; + } +} diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/light/GridAlignedBB.java b/src/main/java/com/simibubi/create/foundation/render/backend/light/GridAlignedBB.java index e25fe1924..f711ab41f 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/light/GridAlignedBB.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/light/GridAlignedBB.java @@ -1,8 +1,8 @@ package com.simibubi.create.foundation.render.backend.light; -import static com.simibubi.create.foundation.render.RenderMath.isPowerOf2; +import static com.simibubi.create.foundation.render.backend.RenderUtil.isPowerOf2; -import com.simibubi.create.foundation.render.RenderMath; +import com.simibubi.create.foundation.render.backend.RenderUtil; import net.minecraft.util.Direction; import net.minecraft.util.math.AxisAlignedBB; @@ -142,9 +142,9 @@ public class GridAlignedBB { int sizeY = sizeY(); int sizeZ = sizeZ(); - int newSizeX = RenderMath.nextPowerOf2(sizeX); - int newSizeY = RenderMath.nextPowerOf2(sizeY); - int newSizeZ = RenderMath.nextPowerOf2(sizeZ); + int newSizeX = RenderUtil.nextPowerOf2(sizeX); + int newSizeY = RenderUtil.nextPowerOf2(sizeY); + int newSizeZ = RenderUtil.nextPowerOf2(sizeZ); int diffX = newSizeX - sizeX; int diffY = newSizeY - sizeY; @@ -162,9 +162,9 @@ public class GridAlignedBB { * Grow this bounding box to have power of 2 side lengths, scaling from the minimum coords. */ public void nextPowerOf2() { - int sizeX = RenderMath.nextPowerOf2(sizeX()); - int sizeY = RenderMath.nextPowerOf2(sizeY()); - int sizeZ = RenderMath.nextPowerOf2(sizeZ()); + int sizeX = RenderUtil.nextPowerOf2(sizeX()); + int sizeY = RenderUtil.nextPowerOf2(sizeY()); + int sizeZ = RenderUtil.nextPowerOf2(sizeZ()); this.maxX = this.minX + sizeX; this.maxY = this.minY + sizeY; diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg index 17a263235..80912c491 100644 --- a/src/main/resources/META-INF/accesstransformer.cfg +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -46,4 +46,31 @@ public net.minecraft.client.renderer.GameRenderer func_215311_a(Lnet/minecraft/c # IResizeCallback public net.minecraft.util.palette.IResizeCallback -public net.minecraft.entity.Entity func_205011_p()V # updateAquatics \ No newline at end of file +public net.minecraft.entity.Entity func_205011_p()V # updateAquatics + +public net.minecraft.client.renderer.Matrix3f field_226097_a_ #a00 +public net.minecraft.client.renderer.Matrix3f field_226098_b_ #a01 +public net.minecraft.client.renderer.Matrix3f field_226099_c_ #a02 +public net.minecraft.client.renderer.Matrix3f field_226100_d_ #a10 +public net.minecraft.client.renderer.Matrix3f field_226101_e_ #a11 +public net.minecraft.client.renderer.Matrix3f field_226102_f_ #a12 +public net.minecraft.client.renderer.Matrix3f field_226103_g_ #a20 +public net.minecraft.client.renderer.Matrix3f field_226104_h_ #a21 +public net.minecraft.client.renderer.Matrix3f field_226105_i_ #a22 + +public net.minecraft.client.renderer.Matrix4f field_226575_a_ #a00 +public net.minecraft.client.renderer.Matrix4f field_226576_b_ #a01 +public net.minecraft.client.renderer.Matrix4f field_226577_c_ #a02 +public net.minecraft.client.renderer.Matrix4f field_226578_d_ #a03 +public net.minecraft.client.renderer.Matrix4f field_226579_e_ #a10 +public net.minecraft.client.renderer.Matrix4f field_226580_f_ #a11 +public net.minecraft.client.renderer.Matrix4f field_226581_g_ #a12 +public net.minecraft.client.renderer.Matrix4f field_226582_h_ #a13 +public net.minecraft.client.renderer.Matrix4f field_226583_i_ #a20 +public net.minecraft.client.renderer.Matrix4f field_226584_j_ #a21 +public net.minecraft.client.renderer.Matrix4f field_226585_k_ #a22 +public net.minecraft.client.renderer.Matrix4f field_226586_l_ #a23 +public net.minecraft.client.renderer.Matrix4f field_226587_m_ #a30 +public net.minecraft.client.renderer.Matrix4f field_226588_n_ #a31 +public net.minecraft.client.renderer.Matrix4f field_226589_o_ #a32 +public net.minecraft.client.renderer.Matrix4f field_226590_p_ #a33 \ No newline at end of file diff --git a/src/main/resources/assets/create/shader/instanced.frag b/src/main/resources/assets/create/shader/model.frag similarity index 100% rename from src/main/resources/assets/create/shader/instanced.frag rename to src/main/resources/assets/create/shader/model.frag diff --git a/src/main/resources/assets/create/shader/model.vert b/src/main/resources/assets/create/shader/model.vert new file mode 100644 index 000000000..916cc7bcb --- /dev/null +++ b/src/main/resources/assets/create/shader/model.vert @@ -0,0 +1,76 @@ +#version 110 + +attribute vec3 aPos; +attribute vec3 aNormal; +attribute vec2 aTexCoords; + +attribute mat4 aTransform; +attribute mat3 aNormalMat; +attribute vec2 aLight; + +varying vec2 TexCoords; +varying vec4 Color; +varying float Diffuse; +varying vec2 Light; + +#if defined(CONTRAPTION) +varying vec3 BoxCoord; + +uniform vec3 uLightBoxSize; +uniform vec3 uLightBoxMin; +uniform mat4 uModel; +#endif + +uniform float uTime; +uniform mat4 uViewProjection; +uniform int uDebug; + +uniform vec3 uCameraPos; + +#if defined(USE_FOG) +varying float FragDistance; +#endif + +mat3 modelToNormal(mat4 mat) { + // Discard the edges. This won't be accurate for scaled or skewed matrices, + // but we don't have to work with those often. + mat3 m; + m[0] = mat[0].xyz; + m[1] = mat[1].xyz; + m[2] = mat[2].xyz; + return m; +} + +float diffuse(vec3 normal) { + float x = normal.x; + float y = normal.y; + float z = normal.z; + return min(x * x * .6 + y * y * ((3. + y) / 4.) + z * z * .8, 1.); +} + +void main() { + vec4 worldPos = aTransform * vec4(aPos, 1.); + + mat3 normalMat = aNormalMat; + +#ifdef CONTRAPTION + worldPos = uModel * worldPos; + normalMat *= modelToNormal(uModel); + + BoxCoord = (worldPos.xyz - uLightBoxMin) / uLightBoxSize; + #if defined(USE_FOG) + FragDistance = length(worldPos.xyz); + #endif +#elif defined(USE_FOG) + FragDistance = length(worldPos.xyz - uCameraPos); +#endif + + vec3 norm = normalize(normalMat * aNormal); + + Diffuse = diffuse(norm); + TexCoords = aTexCoords; + Light = aLight; + gl_Position = uViewProjection * worldPos; + + Color = vec4(1.); +} \ No newline at end of file