merge experimental rendering from 1.16 to 1.15

This commit is contained in:
JozsefA 2021-01-04 14:37:44 -08:00 committed by grimmauld
parent 3cdbf47cb9
commit 7d43bb056a
59 changed files with 1079 additions and 268 deletions

View file

@ -11,12 +11,10 @@ import java.util.Map;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.content.contraptions.fluids.FluidTransportBehaviour.AttachmentTypes;
import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock.HeatLevel;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.foundation.utility.MatrixStacker;
import com.simibubi.create.foundation.utility.SuperByteBuffer;
import com.simibubi.create.foundation.utility.*;
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
import net.minecraft.block.BlockState;
import net.minecraft.client.renderer.model.IBakedModel;
import net.minecraft.util.Direction;
@ -218,4 +216,23 @@ public class AllBlockPartials {
return CreateClient.bufferCache.renderDirectionalPartial(this, referenceState, facing, ms);
}
public InstancedBuffer renderOnInstanced(BlockState referenceState) {
return CreateClient.kineticRenderer.renderPartialInstanced(this, referenceState);
}
public InstancedBuffer renderOnDirectionalSouthInstanced(BlockState referenceState) {
Direction facing = referenceState.get(FACING);
return renderOnDirectionalSouthInstanced(referenceState, facing);
}
public InstancedBuffer renderOnDirectionalSouthInstanced(BlockState referenceState, Direction facing) {
MatrixStack ms = new MatrixStack();
// TODO 1.15 find a way to cache this model matrix computation
MatrixStacker.of(ms)
.centre()
.rotateY(AngleHelper.horizontalAngle(facing))
.rotateX(AngleHelper.verticalAngle(facing))
.unCentre();
return CreateClient.kineticRenderer.renderDirectionalPartialInstanced(this, referenceState, facing, ms);
}
}

View file

@ -16,9 +16,11 @@ import com.simibubi.create.foundation.block.render.CustomBlockModels;
import com.simibubi.create.foundation.block.render.SpriteShifter;
import com.simibubi.create.foundation.item.CustomItemModels;
import com.simibubi.create.foundation.item.CustomRenderedItems;
import com.simibubi.create.foundation.utility.SuperByteBufferCache;
import com.simibubi.create.foundation.utility.render.FastKineticRenderer;
import com.simibubi.create.foundation.utility.render.SuperByteBufferCache;
import com.simibubi.create.foundation.utility.outliner.Outliner;
import com.simibubi.create.foundation.utility.render.shader.ShaderHelper;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BlockModelShapes;
@ -42,6 +44,7 @@ public class CreateClient {
public static SchematicHandler schematicHandler;
public static SchematicAndQuillHandler schematicAndQuillHandler;
public static SuperByteBufferCache bufferCache;
public static FastKineticRenderer kineticRenderer;
public static final Outliner outliner = new Outliner();
private static CustomBlockModels customBlockModels;
@ -56,6 +59,8 @@ public class CreateClient {
modEventBus.addListener(CreateClient::onModelRegistry);
modEventBus.addListener(CreateClient::onTextureStitch);
modEventBus.addListener(AllParticleTypes::registerFactories);
ShaderHelper.initShaders();
}
public static void clientInit(FMLClientSetupEvent event) {
@ -67,6 +72,10 @@ public class CreateClient {
bufferCache.registerCompartment(KineticTileEntityRenderer.KINETIC_TILE);
bufferCache.registerCompartment(ContraptionRenderer.CONTRAPTION, 20);
kineticRenderer = new FastKineticRenderer();
kineticRenderer.registerCompartment(KineticTileEntityRenderer.KINETIC_TILE);
kineticRenderer.registerCompartment(ContraptionRenderer.CONTRAPTION, 20);
AllKeys.register();
AllContainerTypes.registerScreenFactories();
//AllTileEntities.registerRenderers();

View file

@ -1,7 +1,9 @@
package com.simibubi.create.content.contraptions.base;
import com.simibubi.create.CreateClient;
import com.simibubi.create.foundation.item.ItemDescription.Palette;
import com.simibubi.create.foundation.utility.render.SuperByteBufferCache;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.entity.LivingEntity;
@ -14,7 +16,9 @@ import net.minecraft.world.IBlockReader;
import net.minecraft.world.IWorld;
import net.minecraft.world.IWorldReader;
import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.common.ToolType;
import net.minecraftforge.fml.DistExecutor;
public abstract class KineticBlock extends Block implements IRotate {

View file

@ -8,6 +8,7 @@ import java.util.List;
import javax.annotation.Nullable;
import com.simibubi.create.Create;
import com.simibubi.create.CreateClient;
import com.simibubi.create.content.contraptions.KineticNetwork;
import com.simibubi.create.content.contraptions.RotationPropagator;
import com.simibubi.create.content.contraptions.base.IRotate.SpeedLevel;
@ -31,9 +32,13 @@ import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.Direction;
import net.minecraft.util.Direction.AxisDirection;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.common.extensions.IForgeTileEntity;
import net.minecraftforge.fml.DistExecutor;
public abstract class KineticTileEntity extends SmartTileEntity
implements ITickableTileEntity, IHaveGoggleInformation, IHaveHoveringInformation {

View file

@ -1,7 +1,6 @@
package com.simibubi.create.content.contraptions.base;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.vertex.IVertexBuilder;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.CreateClient;
import com.simibubi.create.content.contraptions.KineticDebugger;
@ -9,8 +8,9 @@ import com.simibubi.create.content.contraptions.relays.elementary.CogWheelBlock;
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.utility.SuperByteBuffer;
import com.simibubi.create.foundation.utility.SuperByteBufferCache.Compartment;
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
import com.simibubi.create.foundation.utility.render.SuperByteBufferCache.Compartment;
import net.minecraft.block.BlockState;
import net.minecraft.client.renderer.IRenderTypeBuffer;
@ -35,23 +35,36 @@ public class KineticTileEntityRenderer extends SafeTileEntityRenderer<KineticTil
super(dispatcher);
}
@Override
public boolean isGlobalRenderer(KineticTileEntity te) {
return true;
}
@Override
protected void renderSafe(KineticTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer,
int light, int overlay) {
for (RenderType type : RenderType.getBlockLayers())
if (RenderTypeLookup.canRenderInLayer(te.getBlockState(), type))
renderRotatingBuffer(te, getRotatedModel(te), ms, buffer.getBuffer(type), light);
renderRotatingBuffer(te, getRotatedModel(te), light);
}
public static void renderRotatingKineticBlock(KineticTileEntity te, BlockState renderedState, MatrixStack ms,
IVertexBuilder buffer, int light) {
SuperByteBuffer superByteBuffer = CreateClient.bufferCache.renderBlockIn(KINETIC_TILE, renderedState);
renderRotatingBuffer(te, superByteBuffer, ms, buffer, light);
public static void renderRotatingKineticBlock(KineticTileEntity te, BlockState renderedState, int light) {
InstancedBuffer instancedRenderer = CreateClient.kineticRenderer.renderBlockInstanced(KINETIC_TILE, renderedState);
renderRotatingBuffer(te, instancedRenderer, light);
}
public static void renderRotatingBuffer(KineticTileEntity te, SuperByteBuffer superBuffer, MatrixStack ms,
IVertexBuilder buffer, int light) {
standardKineticRotationTransform(superBuffer, te, light).renderInto(ms, buffer);
public static void renderRotatingBuffer(KineticTileEntity te, InstancedBuffer instancer, int light) {
instancer.setupInstance(data -> {
final BlockPos pos = te.getPos();
Axis axis = ((IRotate) te.getBlockState()
.getBlock()).getRotationAxis(te.getBlockState());
data.setPackedLight(light)
.setRotationalSpeed(te.getSpeed())
.setRotationOffset(getRotationOffsetForPosition(te, pos, axis))
.setRotationAxis(Direction.getFacingFromAxis(AxisDirection.POSITIVE, axis).getUnitVector())
.setPosition(pos);
});
}
public static float getAngleForTe(KineticTileEntity te, final BlockPos pos, Axis axis) {
@ -116,8 +129,8 @@ public class KineticTileEntityRenderer extends SafeTileEntityRenderer<KineticTil
return te.getBlockState();
}
protected SuperByteBuffer getRotatedModel(KineticTileEntity te) {
return CreateClient.bufferCache.renderBlockIn(KINETIC_TILE, getRenderedBlockState(te));
protected InstancedBuffer getRotatedModel(KineticTileEntity te) {
return CreateClient.kineticRenderer.renderBlockInstanced(KINETIC_TILE, getRenderedBlockState(te));
}
}

View file

@ -10,7 +10,8 @@ import com.simibubi.create.content.contraptions.components.structureMovement.Mov
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.MatrixStacker;
import com.simibubi.create.foundation.utility.SuperByteBuffer;
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.block.BlockState;
@ -26,8 +27,8 @@ public class DrillRenderer extends KineticTileEntityRenderer {
}
@Override
protected SuperByteBuffer getRotatedModel(KineticTileEntity te) {
return AllBlockPartials.DRILL_HEAD.renderOnDirectionalSouth(te.getBlockState());
protected InstancedBuffer getRotatedModel(KineticTileEntity te) {
return AllBlockPartials.DRILL_HEAD.renderOnDirectionalSouthInstanced(te.getBlockState());
}
protected static SuperByteBuffer getRotatingModel(BlockState state) {

View file

@ -8,7 +8,7 @@ import com.simibubi.create.content.contraptions.components.structureMovement.Mov
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.SuperByteBuffer;
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.block.BlockState;

View file

@ -10,7 +10,7 @@ import com.simibubi.create.content.contraptions.components.structureMovement.Mov
import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.MatrixStacker;
import com.simibubi.create.foundation.utility.SuperByteBuffer;
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft;

View file

@ -7,7 +7,8 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.content.contraptions.components.clock.CuckooClockTileEntity.Animation;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.SuperByteBuffer;
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
import net.minecraft.block.BlockState;
import net.minecraft.client.renderer.IRenderTypeBuffer;
@ -90,12 +91,12 @@ public class CuckooClockRenderer extends KineticTileEntityRenderer {
}
@Override
protected SuperByteBuffer getRotatedModel(KineticTileEntity te) {
protected InstancedBuffer getRotatedModel(KineticTileEntity te) {
return transform(AllBlockPartials.SHAFT_HALF, te);
}
private SuperByteBuffer transform(AllBlockPartials partial, KineticTileEntity te) {
return partial.renderOnDirectionalSouth(te.getBlockState(), te.getBlockState()
private InstancedBuffer transform(AllBlockPartials partial, KineticTileEntity te) {
return partial.renderOnDirectionalSouthInstanced(te.getBlockState(), te.getBlockState()
.get(CuckooClockBlock.HORIZONTAL_FACING)
.getOpposite());
}

View file

@ -13,7 +13,7 @@ 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.MatrixStacker;
import com.simibubi.create.foundation.utility.SuperByteBuffer;
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft;

View file

@ -6,7 +6,7 @@ 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.SuperByteBuffer;
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;

View file

@ -16,7 +16,7 @@ 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.utility.SuperByteBuffer;
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.block.BlockState;
@ -102,7 +102,7 @@ public class DeployerRenderer extends SafeTileEntityRenderer<DeployerTileEntity>
protected void renderComponents(DeployerTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer,
int light, int overlay) {
IVertexBuilder vb = buffer.getBuffer(RenderType.getSolid());
KineticTileEntityRenderer.renderRotatingKineticBlock(te, getRenderedBlockState(te), ms, vb, light);
KineticTileEntityRenderer.renderRotatingKineticBlock(te, getRenderedBlockState(te), light);
BlockState blockState = te.getBlockState();
BlockPos pos = te.getPos();
@ -112,10 +112,10 @@ public class DeployerRenderer extends SafeTileEntityRenderer<DeployerTileEntity>
SuperByteBuffer hand = te.getHandPose()
.renderOn(blockState);
transform(te.getWorld(), pole.translate(offset.x, offset.y, offset.z), blockState, pos, true).renderInto(ms,
vb);
transform(te.getWorld(), hand.translate(offset.x, offset.y, offset.z), blockState, pos, false).renderInto(ms,
vb);
transform(te.getWorld(), (SuperByteBuffer) pole.translate(offset.x, offset.y, offset.z), blockState, pos, true).renderInto(ms,
vb);
transform(te.getWorld(), (SuperByteBuffer) hand.translate(offset.x, offset.y, offset.z), blockState, pos, false).renderInto(ms,
vb);
}
protected Vec3d getHandOffset(DeployerTileEntity te, float partialTicks, BlockState blockState) {

View file

@ -3,18 +3,17 @@ package com.simibubi.create.content.contraptions.components.fan;
import static net.minecraft.state.properties.BlockStateProperties.FACING;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.vertex.IVertexBuilder;
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.AnimationTickHolder;
import com.simibubi.create.foundation.utility.SuperByteBuffer;
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.WorldRenderer;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
public class EncasedFanRenderer extends KineticTileEntityRenderer {
@ -28,27 +27,33 @@ public class EncasedFanRenderer extends KineticTileEntityRenderer {
int light, int overlay) {
Direction direction = te.getBlockState()
.get(FACING);
IVertexBuilder vb = buffer.getBuffer(RenderType.getCutoutMipped());
int lightBehind = WorldRenderer.getLightmapCoordinates(te.getWorld(), te.getPos().offset(direction.getOpposite()));
int lightInFront = WorldRenderer.getLightmapCoordinates(te.getWorld(), te.getPos().offset(direction));
SuperByteBuffer shaftHalf =
AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouth(te.getBlockState(), direction.getOpposite());
SuperByteBuffer fanInner =
AllBlockPartials.ENCASED_FAN_INNER.renderOnDirectionalSouth(te.getBlockState(), direction.getOpposite());
float time = AnimationTickHolder.getRenderTick();
float speed = te.getSpeed() * 5;
if (speed > 0)
speed = MathHelper.clamp(speed, 80, 64 * 20);
if (speed < 0)
speed = MathHelper.clamp(speed, -64 * 20, -80);
float angle = (time * speed * 3 / 10f) % 360;
angle = angle / 180f * (float) Math.PI;
InstancedBuffer shaftHalf =
AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthInstanced(te.getBlockState(), direction.getOpposite());
InstancedBuffer fanInner =
AllBlockPartials.ENCASED_FAN_INNER.renderOnDirectionalSouthInstanced(te.getBlockState(), direction.getOpposite());
standardKineticRotationTransform(shaftHalf, te, lightBehind).renderInto(ms, vb);
kineticRotationTransform(fanInner, te, direction.getAxis(), angle, lightInFront).renderInto(ms, vb);
renderRotatingBuffer(te, shaftHalf, lightBehind);
fanInner.setupInstance(data -> {
final BlockPos pos = te.getPos();
Direction.Axis axis = ((IRotate) te.getBlockState()
.getBlock()).getRotationAxis(te.getBlockState());
float speed = te.getSpeed() * 5;
if (speed > 0)
speed = MathHelper.clamp(speed, 80, 64 * 20);
if (speed < 0)
speed = MathHelper.clamp(speed, -64 * 20, -80);
data.setPackedLight(lightInFront)
.setRotationalSpeed(speed)
.setRotationOffset(getRotationOffsetForPosition(te, pos, axis))
.setRotationAxis(Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis).getUnitVector())
.setPosition(pos);
});
}
}

View file

@ -9,7 +9,8 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.content.contraptions.components.flywheel.FlywheelBlock.ConnectionState;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.SuperByteBuffer;
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
import net.minecraft.block.BlockState;
import net.minecraft.client.renderer.IRenderTypeBuffer;
@ -74,8 +75,8 @@ public class FlywheelRenderer extends KineticTileEntityRenderer {
}
@Override
protected SuperByteBuffer getRotatedModel(KineticTileEntity te) {
return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouth(te.getBlockState(), te.getBlockState()
protected InstancedBuffer getRotatedModel(KineticTileEntity te) {
return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthInstanced(te.getBlockState(), te.getBlockState()
.get(HORIZONTAL_FACING)
.getOpposite());
}

View file

@ -4,7 +4,7 @@ import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.CreateClient;
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.foundation.utility.SuperByteBuffer;
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
@ -15,8 +15,8 @@ public class MillstoneRenderer extends KineticTileEntityRenderer {
}
@Override
protected SuperByteBuffer getRotatedModel(KineticTileEntity te) {
return CreateClient.bufferCache.renderPartial(AllBlockPartials.MILLSTONE_COG, te.getBlockState());
protected InstancedBuffer getRotatedModel(KineticTileEntity te) {
return CreateClient.kineticRenderer.renderPartialInstanced(AllBlockPartials.MILLSTONE_COG, te.getBlockState());
}
}

View file

@ -6,7 +6,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.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.SuperByteBuffer;
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
import net.minecraft.block.BlockState;
import net.minecraft.client.renderer.IRenderTypeBuffer;

View file

@ -3,7 +3,7 @@ package com.simibubi.create.content.contraptions.components.motor;
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.SuperByteBuffer;
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
@ -14,8 +14,8 @@ public class CreativeMotorRenderer extends KineticTileEntityRenderer {
}
@Override
protected SuperByteBuffer getRotatedModel(KineticTileEntity te) {
return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouth(te.getBlockState());
protected InstancedBuffer getRotatedModel(KineticTileEntity te) {
return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthInstanced(te.getBlockState());
}
}

View file

@ -4,7 +4,7 @@ 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.SuperByteBuffer;
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
import net.minecraft.block.BlockState;
import net.minecraft.client.renderer.IRenderTypeBuffer;

View file

@ -10,11 +10,10 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext;
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.MatrixStacker;
import com.simibubi.create.foundation.utility.SuperByteBuffer;
import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.foundation.utility.*;
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.IRenderTypeBuffer;
@ -79,9 +78,8 @@ public class SawRenderer extends SafeTileEntityRenderer<SawTileEntity> {
ms.pop();
}
protected void renderShaft(SawTileEntity te, MatrixStack ms, IRenderTypeBuffer buffer, int light,
int overlay) {
KineticTileEntityRenderer.renderRotatingBuffer(te, getRotatedModel(te), ms, buffer.getBuffer(RenderType.getSolid()), light);
protected void renderShaft(SawTileEntity te, MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay) {
KineticTileEntityRenderer.renderRotatingBuffer(te, getRotatedModel(te), light);
}
protected void renderItems(SawTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer, int light,
@ -125,11 +123,11 @@ public class SawRenderer extends SafeTileEntityRenderer<SawTileEntity> {
}
}
protected SuperByteBuffer getRotatedModel(KineticTileEntity te) {
protected InstancedBuffer getRotatedModel(KineticTileEntity te) {
BlockState state = te.getBlockState();
if (state.get(FACING).getAxis().isHorizontal())
return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouth(state.rotate(Rotation.CLOCKWISE_180));
return CreateClient.bufferCache.renderBlockIn(KineticTileEntityRenderer.KINETIC_TILE,
return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthInstanced(state.rotate(te.getWorld(), te.getPos(), Rotation.CLOCKWISE_180));
return CreateClient.kineticRenderer.renderBlockInstanced(KineticTileEntityRenderer.KINETIC_TILE,
getRenderedBlockState(te));
}

View file

@ -10,10 +10,10 @@ import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.AllMovementBehaviours;
import com.simibubi.create.CreateClient;
import com.simibubi.create.foundation.utility.MatrixStacker;
import com.simibubi.create.foundation.utility.SuperByteBuffer;
import com.simibubi.create.foundation.utility.SuperByteBufferCache;
import com.simibubi.create.foundation.utility.SuperByteBufferCache.Compartment;
import com.simibubi.create.foundation.utility.TileEntityRenderHelper;
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
import com.simibubi.create.foundation.utility.render.SuperByteBufferCache;
import com.simibubi.create.foundation.utility.render.SuperByteBufferCache.Compartment;
import com.simibubi.create.foundation.utility.render.TileEntityRenderHelper;
import com.simibubi.create.foundation.utility.worldWrappers.PlacementSimulationWorld;
import net.minecraft.block.BlockRenderType;

View file

@ -5,7 +5,8 @@ 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.AngleHelper;
import com.simibubi.create.foundation.utility.SuperByteBuffer;
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.RenderType;
@ -43,8 +44,8 @@ public class BearingRenderer extends KineticTileEntityRenderer {
}
@Override
protected SuperByteBuffer getRotatedModel(KineticTileEntity te) {
return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouth(te.getBlockState(), te.getBlockState()
protected InstancedBuffer getRotatedModel(KineticTileEntity te) {
return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthInstanced(te.getBlockState(), te.getBlockState()
.get(BearingBlock.FACING)
.getOpposite());
}

View file

@ -8,7 +8,7 @@ import com.simibubi.create.content.contraptions.components.structureMovement.Mov
import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext;
import com.simibubi.create.content.contraptions.components.structureMovement.OrientedContraptionEntity;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.SuperByteBuffer;
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.IRenderTypeBuffer;

View file

@ -7,7 +7,7 @@ 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.AngleHelper;
import com.simibubi.create.foundation.utility.SuperByteBuffer;
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
import net.minecraft.block.BlockState;
import net.minecraft.client.renderer.IRenderTypeBuffer;

View file

@ -5,7 +5,7 @@ import com.simibubi.create.AllBlocks;
import com.simibubi.create.CreateClient;
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity;
import com.simibubi.create.foundation.utility.SuperByteBuffer;
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
import net.minecraft.util.Direction.Axis;

View file

@ -11,7 +11,7 @@ import com.simibubi.create.content.contraptions.components.structureMovement.tra
import com.simibubi.create.foundation.utility.ColorHelper;
import com.simibubi.create.foundation.utility.Couple;
import com.simibubi.create.foundation.utility.MatrixStacker;
import com.simibubi.create.foundation.utility.SuperByteBuffer;
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.block.BlockState;

View file

@ -6,7 +6,8 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.MatrixStacker;
import com.simibubi.create.foundation.utility.SuperByteBuffer;
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
import net.minecraft.block.BlockState;
import net.minecraft.client.renderer.IRenderTypeBuffer;
@ -51,8 +52,8 @@ public class PumpRenderer extends KineticTileEntityRenderer {
}
@Override
protected SuperByteBuffer getRotatedModel(KineticTileEntity te) {
return AllBlockPartials.MECHANICAL_PUMP_COG.renderOnDirectionalSouth(te.getBlockState());
protected InstancedBuffer getRotatedModel(KineticTileEntity te) {
return AllBlockPartials.MECHANICAL_PUMP_COG.renderOnDirectionalSouthInstanced(te.getBlockState());
}
}

View file

@ -3,7 +3,7 @@ package com.simibubi.create.content.contraptions.fluids.actors;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.components.structureMovement.pulley.AbstractPulleyRenderer;
import com.simibubi.create.foundation.utility.SuperByteBuffer;
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
import net.minecraft.util.Direction.Axis;

View file

@ -6,7 +6,7 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.MatrixStacker;
import com.simibubi.create.foundation.utility.SuperByteBuffer;
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
import net.minecraft.block.BlockState;
import net.minecraft.client.renderer.IRenderTypeBuffer;

View file

@ -6,7 +6,7 @@ import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlo
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.SuperByteBuffer;
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.RenderType;

View file

@ -4,10 +4,9 @@ import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.CreateClient;
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.foundation.tileEntity.renderer.SmartTileEntityRenderer;
import com.simibubi.create.foundation.utility.SuperByteBuffer;
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
public class SpeedControllerRenderer extends SmartTileEntityRenderer<SpeedControllerTileEntity> {
@ -21,12 +20,11 @@ public class SpeedControllerRenderer extends SmartTileEntityRenderer<SpeedContro
IRenderTypeBuffer buffer, int light, int overlay) {
super.renderSafe(tileEntityIn, partialTicks, ms, buffer, light, overlay);
KineticTileEntityRenderer.renderRotatingBuffer(tileEntityIn, getRotatedModel(tileEntityIn), ms,
buffer.getBuffer(RenderType.getSolid()), light);
KineticTileEntityRenderer.renderRotatingBuffer(tileEntityIn, getRotatedModel(tileEntityIn), light);
}
private SuperByteBuffer getRotatedModel(SpeedControllerTileEntity te) {
return CreateClient.bufferCache.renderBlockIn(KineticTileEntityRenderer.KINETIC_TILE,
private InstancedBuffer getRotatedModel(SpeedControllerTileEntity te) {
return CreateClient.kineticRenderer.renderBlockInstanced(KineticTileEntityRenderer.KINETIC_TILE,
KineticTileEntityRenderer.shaft(KineticTileEntityRenderer.getRotationAxisOf(te)));
}

View file

@ -10,7 +10,7 @@ import java.util.Random;
import com.simibubi.create.AllSpriteShifts;
import com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity.CasingType;
import com.simibubi.create.foundation.block.render.SpriteShiftEntry;
import com.simibubi.create.foundation.utility.SuperByteBuffer;
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
import net.minecraft.block.BlockState;
import net.minecraft.client.renderer.model.BakedQuad;

View file

@ -16,9 +16,10 @@ import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.MatrixStacker;
import com.simibubi.create.foundation.utility.ShadowRenderHelper;
import com.simibubi.create.foundation.utility.SuperByteBuffer;
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
import com.simibubi.create.foundation.utility.render.ShadowRenderHelper;
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.IRenderTypeBuffer;
@ -95,28 +96,25 @@ public class BeltRenderer extends SafeTileEntityRenderer<BeltTileEntity> {
: start ? AllBlockPartials.BELT_START
: end ? AllBlockPartials.BELT_END : AllBlockPartials.BELT_MIDDLE;
SuperByteBuffer beltBuffer = beltPartial.renderOn(blockState)
.light(light);
SpriteShiftEntry spriteShift =
diagonal ? AllSpriteShifts.BELT_DIAGONAL : bottom ? AllSpriteShifts.BELT_OFFSET : AllSpriteShifts.BELT;
InstancedBuffer beltBuffer = beltPartial.renderOnInstanced(blockState);
int cycleLength = diagonal ? 12 : 16;
int cycleOffset = bottom ? 8 : 0;
// UV shift
float speed = te.getSpeed();
if (speed != 0) {
float time = renderTick * axisDirection.getOffset();
beltBuffer.setupInstance(data -> {
float speed = te.getSpeed();
if (diagonal && (downward ^ alongX) || !sideways && !diagonal && alongX
|| sideways && axisDirection == AxisDirection.NEGATIVE)
|| sideways && axisDirection == AxisDirection.NEGATIVE)
speed = -speed;
int textureIndex = (int) (((speed * time / 36) + cycleOffset) % cycleLength);
if (textureIndex < 0)
textureIndex += cycleLength;
beltBuffer.shiftUVtoSheet(spriteShift, (textureIndex % 4) / 4f, (textureIndex / 4) / 4f, 4);
}
beltBuffer.renderInto(ms, vb);
data.setPackedLight(light)
.setPosition(te.getPos())
.setRotationalSpeed(speed)
.setRotationAxis(0, 0, 0)
.setCycleLength(cycleLength)
.setCycleOffset(cycleOffset);
});
// Diagonal belt do not have a separate bottom model
if (diagonal)
@ -140,10 +138,9 @@ public class BeltRenderer extends SafeTileEntityRenderer<BeltTileEntity> {
msr.rotateX(90);
msr.unCentre();
SuperByteBuffer superBuffer = CreateClient.bufferCache
.renderDirectionalPartial(AllBlockPartials.BELT_PULLEY, blockState, dir, modelTransform);
KineticTileEntityRenderer.standardKineticRotationTransform(superBuffer, te, light)
.renderInto(ms, vb);
InstancedBuffer superBuffer = CreateClient.kineticRenderer
.renderDirectionalPartialInstanced(AllBlockPartials.BELT_PULLEY, blockState, dir, modelTransform);
KineticTileEntityRenderer.renderRotatingBuffer(te, superBuffer, light);
}
renderItems(te, partialTicks, ms, buffer, light, overlay);

View file

@ -5,13 +5,11 @@ 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.AnimationTickHolder;
import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.SuperByteBuffer;
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
import net.minecraft.block.Block;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
import net.minecraft.util.Direction;
import net.minecraft.util.Direction.Axis;
@ -29,28 +27,31 @@ public class SplitShaftRenderer extends KineticTileEntityRenderer {
Block block = te.getBlockState().getBlock();
final Axis boxAxis = ((IRotate) block).getRotationAxis(te.getBlockState());
final BlockPos pos = te.getPos();
float time = AnimationTickHolder.getRenderTick();
for (Direction direction : Iterate.directions) {
Axis axis = direction.getAxis();
if (boxAxis != axis)
continue;
float offset = getRotationOffsetForPosition(te, pos, axis);
float angle = (time * te.getSpeed() * 3f / 10) % 360;
float modifier = 1;
if (te instanceof SplitShaftTileEntity)
modifier = ((SplitShaftTileEntity) te).getRotationSpeedModifier(direction);
InstancedBuffer shaft = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthInstanced(te.getBlockState(), direction);
angle *= modifier;
angle += offset;
angle = angle / 180f * (float) Math.PI;
shaft.setupInstance(data -> {
float speed = te.getSpeed();
SuperByteBuffer superByteBuffer =
AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouth(te.getBlockState(), direction);
kineticRotationTransform(superByteBuffer, te, axis, angle, light);
superByteBuffer.renderInto(ms, buffer.getBuffer(RenderType.getSolid()));
float modifier = 1;
if (te instanceof SplitShaftTileEntity)
modifier = ((SplitShaftTileEntity) te).getRotationSpeedModifier(direction);
speed *= modifier;
data.setPackedLight(light)
.setRotationalSpeed(speed)
.setRotationOffset(getRotationOffsetForPosition(te, pos, axis))
.setRotationAxis(Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis).getUnitVector())
.setPosition(pos);
});
}
}

View file

@ -7,7 +7,7 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.content.contraptions.relays.gauge.GaugeBlock.Type;
import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.SuperByteBuffer;
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
import net.minecraft.block.BlockState;
import net.minecraft.client.renderer.IRenderTypeBuffer;

View file

@ -4,12 +4,10 @@ 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.AnimationTickHolder;
import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.SuperByteBuffer;
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.util.Direction;
@ -27,31 +25,32 @@ public class GearboxRenderer extends KineticTileEntityRenderer {
int light, int overlay) {
final Axis boxAxis = te.getBlockState().get(BlockStateProperties.AXIS);
final BlockPos pos = te.getPos();
float time = AnimationTickHolder.getRenderTick();
for (Direction direction : Iterate.directions) {
final Axis axis = direction.getAxis();
if (boxAxis == axis)
continue;
SuperByteBuffer shaft = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouth(te.getBlockState(), direction);
float offset = getRotationOffsetForPosition(te, pos, axis);
float angle = (time * te.getSpeed() * 3f / 10) % 360;
InstancedBuffer shaft = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthInstanced(te.getBlockState(), direction);
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())
angle *= sourceFacing == direction ? 1 : -1;
else if (sourceFacing.getAxisDirection() == direction.getAxisDirection())
angle *= -1;
}
shaft.setupInstance(data -> {
float speed = te.getSpeed();
angle += offset;
angle = angle / 180f * (float) Math.PI;
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())
speed *= sourceFacing == direction ? 1 : -1;
else if (sourceFacing.getAxisDirection() == direction.getAxisDirection())
speed *= -1;
}
kineticRotationTransform(shaft, te, axis, angle, light);
shaft.renderInto(ms, buffer.getBuffer(RenderType.getSolid()));
data.setPackedLight(light)
.setRotationalSpeed(speed)
.setRotationOffset(getRotationOffsetForPosition(te, pos, axis))
.setRotationAxis(Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis).getUnitVector())
.setPosition(pos);
});
}
}

View file

@ -7,7 +7,7 @@ import com.simibubi.create.foundation.tileEntity.renderer.SmartTileEntityRendere
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.MatrixStacker;
import com.simibubi.create.foundation.utility.SuperByteBuffer;
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.client.renderer.IRenderTypeBuffer;

View file

@ -3,7 +3,7 @@ package com.simibubi.create.content.logistics.block.diodes;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.foundation.tileEntity.renderer.ColoredOverlayTileEntityRenderer;
import com.simibubi.create.foundation.utility.ColorHelper;
import com.simibubi.create.foundation.utility.SuperByteBuffer;
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;

View file

@ -6,7 +6,7 @@ import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.foundation.tileEntity.renderer.SmartTileEntityRenderer;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.MatrixStacker;
import com.simibubi.create.foundation.utility.SuperByteBuffer;
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.client.renderer.IRenderTypeBuffer;

View file

@ -6,12 +6,10 @@ 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.logistics.block.mechanicalArm.ArmTileEntity.Phase;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.ColorHelper;
import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.MatrixStacker;
import com.simibubi.create.foundation.utility.SuperByteBuffer;
import com.simibubi.create.foundation.utility.*;
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.IRenderTypeBuffer;
@ -118,8 +116,8 @@ public class ArmRenderer extends KineticTileEntityRenderer {
}
@Override
protected SuperByteBuffer getRotatedModel(KineticTileEntity te) {
return AllBlockPartials.ARM_COG.renderOn(te.getBlockState());
protected InstancedBuffer getRotatedModel(KineticTileEntity te) {
return AllBlockPartials.ARM_COG.renderOnInstanced(te.getBlockState());
}
}

View file

@ -6,7 +6,7 @@ import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.ColorHelper;
import com.simibubi.create.foundation.utility.SuperByteBuffer;
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
import net.minecraft.block.BlockState;
import net.minecraft.client.renderer.IRenderTypeBuffer;

View file

@ -8,7 +8,7 @@ import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.schematics.block.LaunchedItem.ForBlockState;
import com.simibubi.create.content.schematics.block.LaunchedItem.ForEntity;
import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer;
import com.simibubi.create.foundation.utility.SuperByteBuffer;
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft;

View file

@ -13,8 +13,8 @@ import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.content.schematics.SchematicWorld;
import com.simibubi.create.foundation.renderState.SuperRenderTypeBuffer;
import com.simibubi.create.foundation.utility.MatrixStacker;
import com.simibubi.create.foundation.utility.SuperByteBuffer;
import com.simibubi.create.foundation.utility.TileEntityRenderHelper;
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
import com.simibubi.create.foundation.utility.render.TileEntityRenderHelper;
import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft;

View file

@ -32,6 +32,7 @@ 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.utility.render.FastKineticRenderer;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.ActiveRenderInfo;
import net.minecraft.client.renderer.IRenderTypeBuffer;
@ -76,6 +77,8 @@ public class ClientEvents {
if (!isGameActive())
return;
CreateClient.kineticRenderer.tick();
CreateClient.schematicSender.tick();
CreateClient.schematicAndQuillHandler.tick();
CreateClient.schematicHandler.tick();
@ -112,6 +115,8 @@ public class ClientEvents {
@SubscribeEvent
public static void onRenderWorld(RenderWorldLastEvent event) {
CreateClient.kineticRenderer.renderInstances(event);
MatrixStack ms = event.getMatrixStack();
ActiveRenderInfo info = Minecraft.getInstance().gameRenderer.getActiveRenderInfo();
Vec3d view = info.getProjectedView();

View file

@ -3,7 +3,7 @@ package com.simibubi.create.foundation.block.connected;
import com.simibubi.create.foundation.block.connected.CTSpriteShifter.CTType;
import com.simibubi.create.foundation.block.connected.ConnectedTextureBehaviour.CTContext;
import com.simibubi.create.foundation.block.render.SpriteShiftEntry;
import com.simibubi.create.foundation.utility.SuperByteBuffer;
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
public abstract class CTSpriteShiftEntry extends SpriteShiftEntry {

View file

@ -1,7 +1,7 @@
package com.simibubi.create.foundation.tileEntity.renderer;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.foundation.utility.SuperByteBuffer;
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
import net.minecraft.block.BlockState;
import net.minecraft.client.renderer.IRenderTypeBuffer;

View file

@ -7,6 +7,7 @@ import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.client.model.pipeline.LightUtil;
public abstract class SafeTileEntityRenderer<T extends TileEntity> extends TileEntityRenderer<T> {

View file

@ -0,0 +1,185 @@
package com.simibubi.create.foundation.utility.render;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.Create;
import com.simibubi.create.foundation.utility.render.shader.Shader;
import com.simibubi.create.foundation.utility.render.shader.ShaderHelper;
import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.*;
import net.minecraft.client.renderer.model.IBakedModel;
import net.minecraft.client.renderer.texture.Texture;
import net.minecraft.inventory.container.PlayerContainer;
import net.minecraft.util.Direction;
import net.minecraft.util.math.vector.Matrix4f;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.RenderWorldLastEvent;
import net.minecraftforge.fml.common.Mod;
import org.apache.commons.lang3.tuple.Pair;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL40;
import java.util.*;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
import static com.simibubi.create.foundation.utility.render.SuperByteBufferCache.PARTIAL;
@Mod.EventBusSubscriber(modid = Create.ID, value = Dist.CLIENT)
public class FastKineticRenderer {
Map<SuperByteBufferCache.Compartment<?>, Cache<Object, InstancedBuffer>> cache;
Queue<Runnable> runs;
public FastKineticRenderer() {
cache = new HashMap<>();
runs = new ConcurrentLinkedQueue<>();
registerCompartment(SuperByteBufferCache.GENERIC_TILE);
registerCompartment(SuperByteBufferCache.PARTIAL);
registerCompartment(SuperByteBufferCache.DIRECTIONAL_PARTIAL);
}
public void tick() {
for (Cache<Object, InstancedBuffer> cache : cache.values()) {
for (InstancedBuffer renderer : cache.asMap().values()) {
renderer.clearInstanceData();
}
}
}
public void enqueue(Runnable run) {
runs.add(run);
}
public void renderInstances(RenderWorldLastEvent event) {
RenderSystem.enableBlend();
RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA);
RenderSystem.enableCull();
GameRenderer gameRenderer = Minecraft.getInstance().gameRenderer;
LightTexture lightManager = gameRenderer.getLightmapTextureManager();
ShaderHelper.useShader(Shader.ROTATING_INSTANCED, shader -> {
ShaderHelper.MATRIX_BUFFER.position(0);
event.getProjectionMatrix().write(ShaderHelper.MATRIX_BUFFER);
int projection = GlStateManager.getUniformLocation(shader, "projection");
GlStateManager.uniformMatrix4(projection, false, ShaderHelper.MATRIX_BUFFER);
// view matrix
Vector3d pos = gameRenderer.getActiveRenderInfo().getProjectedView();
Matrix4f translate = Matrix4f.translate((float) -pos.x, (float) -pos.y, (float) -pos.z);
translate.multiplyBackward(event.getMatrixStack().peek().getModel());
ShaderHelper.MATRIX_BUFFER.position(0);
translate.write(ShaderHelper.MATRIX_BUFFER);
int view = GlStateManager.getUniformLocation(shader, "view");
GlStateManager.uniformMatrix4(view, false, ShaderHelper.MATRIX_BUFFER);
Texture blockAtlasTexture = Minecraft.getInstance().textureManager.getTexture(PlayerContainer.BLOCK_ATLAS_TEXTURE);
Texture lightTexture = Minecraft.getInstance().textureManager.getTexture(lightManager.resourceLocation);
GL40.glActiveTexture(GL40.GL_TEXTURE0);
GL40.glBindTexture(GL11.GL_TEXTURE_2D, blockAtlasTexture.getGlTextureId());
GL40.glActiveTexture(GL40.GL_TEXTURE0 + 1);
GL40.glBindTexture(GL11.GL_TEXTURE_2D, lightTexture.getGlTextureId());
RenderSystem.texParameter(3553, 10241, 9729);
RenderSystem.texParameter(3553, 10240, 9729);
RenderSystem.texParameter(3553, 10242, 10496);
RenderSystem.texParameter(3553, 10243, 10496);
RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
RenderSystem.enableTexture();
});
cache.values()
.stream()
.flatMap(cache -> {
ConcurrentMap<Object, InstancedBuffer> map = cache.asMap();
return map.values().stream();
})
.filter(type -> !type.isEmpty())
.forEach(InstancedBuffer::render);
ShaderHelper.releaseShader();
GL40.glActiveTexture(GL40.GL_TEXTURE0 + 1);
GL40.glBindTexture(GL11.GL_TEXTURE_2D, 0);
GL40.glActiveTexture(GL40.GL_TEXTURE0);
GL40.glBindTexture(GL11.GL_TEXTURE_2D, 0);
RenderSystem.disableCull();
RenderSystem.disableBlend();
RenderSystem.defaultBlendFunc();
while (!runs.isEmpty()) {
runs.remove().run();
}
}
public void registerCompartment(SuperByteBufferCache.Compartment<?> instance) {
cache.put(instance, CacheBuilder.newBuilder().build());
}
public void registerCompartment(SuperByteBufferCache.Compartment<?> instance, long ticksUntilExpired) {
cache.put(instance, CacheBuilder.newBuilder().expireAfterAccess(ticksUntilExpired * 50, TimeUnit.MILLISECONDS).build());
}
public InstancedBuffer renderPartialInstanced(AllBlockPartials partial, BlockState referenceState) {
return getInstanced(PARTIAL, partial, () -> rotatingInstancedRenderer(partial.get(), referenceState));
}
public InstancedBuffer renderDirectionalPartialInstanced(AllBlockPartials partial, BlockState referenceState, Direction dir,
MatrixStack modelTransform) {
return getInstanced(SuperByteBufferCache.DIRECTIONAL_PARTIAL, Pair.of(dir, partial),
() -> rotatingInstancedRenderer(partial.get(), referenceState, modelTransform));
}
public InstancedBuffer renderBlockInstanced(SuperByteBufferCache.Compartment<BlockState> compartment, BlockState toRender) {
return getInstanced(compartment, toRender, () -> rotatingInstancedRenderer(toRender));
}
public <T> InstancedBuffer getInstanced(SuperByteBufferCache.Compartment<T> compartment, T key, Supplier<InstancedBuffer> supplier) {
Cache<Object, InstancedBuffer> compartmentCache = this.cache.get(compartment);
try {
return compartmentCache.get(key, supplier::get);
} catch (ExecutionException e) {
e.printStackTrace();
return null;
}
}
private InstancedBuffer rotatingInstancedRenderer(BlockState renderedState) {
BlockRendererDispatcher dispatcher = Minecraft.getInstance().getBlockRendererDispatcher();
return rotatingInstancedRenderer(dispatcher.getModelForState(renderedState), renderedState);
}
private InstancedBuffer rotatingInstancedRenderer(IBakedModel model, BlockState renderedState) {
return rotatingInstancedRenderer(model, renderedState, new MatrixStack());
}
private InstancedBuffer rotatingInstancedRenderer(IBakedModel model, BlockState referenceState, MatrixStack ms) {
BufferBuilder builder = SuperByteBufferCache.getBufferBuilder(model, referenceState, ms);
return new InstancedBuffer(builder);
}
public void invalidate() {
cache.values().forEach(cache -> {
cache.asMap().values().forEach(InstancedBuffer::invalidate);
cache.invalidateAll();
});
}
}

View file

@ -0,0 +1,278 @@
package com.simibubi.create.foundation.utility.render;
import com.mojang.blaze3d.platform.GlStateManager;
import com.simibubi.create.CreateClient;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GLAllocation;
import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.Vector3f;
import net.minecraft.client.renderer.vertex.VertexFormatElement;
import net.minecraft.util.math.BlockPos;
import org.lwjgl.opengl.*;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.function.Consumer;
public class InstancedBuffer extends TemplateBuffer {
public int vao, ebo, invariantVBO, instanceVBO, instanceCount;
private final ArrayList<InstanceData> data = new ArrayList<>();
private boolean shouldBuild = true;
public InstancedBuffer(BufferBuilder buf) {
super(buf);
setupMainData();
}
private void setupMainData() {
int floatSize = VertexFormatElement.Type.FLOAT.getSize();
int stride = floatSize * 8;
int invariantSize = count * stride;
ByteBuffer constant = GLAllocation.createDirectByteBuffer(invariantSize);
constant.order(template.order());
((Buffer) constant).limit(invariantSize);
int indicesSize = count * VertexFormatElement.Type.USHORT.getSize();
ByteBuffer indices = GLAllocation.createDirectByteBuffer(indicesSize);
indices.order(template.order());
((Buffer) indices).limit(indicesSize);
int vertexCount = vertexCount(template);
for (int i = 0; i < vertexCount; i++) {
constant.putFloat(getX(template, i));
constant.putFloat(getY(template, i));
constant.putFloat(getZ(template, i));
constant.putFloat(getNX(template, i));
constant.putFloat(getNY(template, i));
constant.putFloat(getNZ(template, i));
constant.putFloat(getU(template, i));
constant.putFloat(getV(template, i));
indices.putShort((short) i);
}
constant.rewind();
indices.rewind();
vao = GL30.glGenVertexArrays();
GL30.glBindVertexArray(vao);
ebo = GlStateManager.genBuffers();
invariantVBO = GlStateManager.genBuffers();
instanceVBO = GlStateManager.genBuffers();
GlStateManager.bindBuffers(GL15.GL_ARRAY_BUFFER, invariantVBO);
GlStateManager.bufferData(GL15.GL_ARRAY_BUFFER, constant, GL15.GL_STATIC_DRAW);
GlStateManager.bindBuffers(GL15.GL_ELEMENT_ARRAY_BUFFER, ebo);
GlStateManager.bufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indices, GL15.GL_STATIC_DRAW);
// vertex positions
GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, stride, 0);
// vertex normals
GL20.glVertexAttribPointer(1, 3, GL11.GL_FLOAT, false, stride, floatSize * 3L);
// uv position
GL20.glVertexAttribPointer(2, 2, GL11.GL_FLOAT, false, stride, floatSize * 6L);
GlStateManager.bindBuffers(GL15.GL_ARRAY_BUFFER, 0);
GlStateManager.bindBuffers(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
// Deselect (bind to 0) the VAO
GL30.glBindVertexArray(0);
}
public int numInstances() {
return instanceCount;
}
public boolean isEmpty() {
return numInstances() == 0;
}
public void clearInstanceData() {
instanceCount = 0;
shouldBuild = true;
}
public void invalidate() {
CreateClient.kineticRenderer.enqueue(() -> {
GL15.glDeleteBuffers(invariantVBO);
GL15.glDeleteBuffers(instanceVBO);
GL15.glDeleteBuffers(ebo);
GL30.glDeleteVertexArrays(vao);
clearInstanceData();
});
}
public void setupInstance(Consumer<InstanceData> setup) {
if (!shouldBuild) return;
InstanceData instanceData = new InstanceData();
setup.accept(instanceData);
data.add(instanceData);
instanceCount++;
}
public void render() {
GL30.glBindVertexArray(vao);
if (finishBuffering()) {
for (int i = 0; i <= 8; i++) {
GL40.glEnableVertexAttribArray(i);
}
GlStateManager.bindBuffers(GL15.GL_ELEMENT_ARRAY_BUFFER, ebo);
GL40.glDrawElementsInstanced(GL11.GL_QUADS, count, GL11.GL_UNSIGNED_SHORT, 0, instanceCount);
for (int i = 0; i <= 8; i++) {
GL40.glDisableVertexAttribArray(i);
}
}
GL30.glBindVertexArray(0);
}
private boolean finishBuffering() {
if (!shouldBuild) return true;
int floatSize = VertexFormatElement.Type.FLOAT.getSize();
int intSize = VertexFormatElement.Type.INT.getSize();
int stride = floatSize * 10 + intSize * 2;
int instanceSize = data.size() * stride;
if (instanceSize == 0) return false;
ByteBuffer buffer = GLAllocation.createDirectByteBuffer(instanceSize);
buffer.order(template.order());
((Buffer) buffer).limit(instanceSize);
data.forEach(instanceData -> instanceData.buffer(buffer));
buffer.rewind();
GlStateManager.bindBuffers(GL15.GL_ARRAY_BUFFER, instanceVBO);
GlStateManager.bufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
// the render position
GL20.glVertexAttribPointer(3, 3, GL11.GL_FLOAT, false, stride, 0);
// vertex lighting
GL20.glVertexAttribPointer(4, 2, GL11.GL_FLOAT, false, stride, floatSize * 3L);
// rotational speed and offset
GL20.glVertexAttribPointer(5, 1, GL11.GL_FLOAT, false, stride, floatSize * 5L);
GL20.glVertexAttribPointer(6, 1, GL11.GL_FLOAT, false, stride, floatSize * 6L);
// rotation axis
GL20.glVertexAttribPointer(7, 3, GL11.GL_FLOAT, false, stride, floatSize * 7L);
// uv scrolling
GL20.glVertexAttribPointer(8, 2, GL11.GL_INT, false, stride, floatSize * 10L);
for (int i = 3; i <= 8; i++) {
GL40.glVertexAttribDivisor(i, 1);
}
// Deselect (bind to 0) the VBO
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
shouldBuild = false;
data.clear();
return true;
}
public static class InstanceData {
private float x;
private float y;
private float z;
private int packedLight = 0;
private float rotationalSpeed;
private float rotationOffset;
private float rotationAxisX;
private float rotationAxisY;
private float rotationAxisZ;
private int cycleLength;
private int cycleOffset;
public InstanceData setPackedLight(int packedLight) {
this.packedLight = packedLight;
return this;
}
public InstanceData setRotationalSpeed(float rotationalSpeed) {
this.rotationalSpeed = rotationalSpeed;
return this;
}
public InstanceData setRotationOffset(float rotationOffset) {
this.rotationOffset = rotationOffset;
return this;
}
public InstanceData setPosition(Vector3f pos) {
this.x = pos.getX();
this.y = pos.getY();
this.z = pos.getZ();
return this;
}
public InstanceData setPosition(BlockPos pos) {
this.x = pos.getX();
this.y = pos.getY();
this.z = pos.getZ();
return this;
}
public InstanceData setRotationAxis(Vector3f axis) {
this.rotationAxisX = axis.getX();
this.rotationAxisY = axis.getY();
this.rotationAxisZ = axis.getZ();
return this;
}
public InstanceData setRotationAxis(float rotationAxisX, float rotationAxisY, float rotationAxisZ) {
this.rotationAxisX = rotationAxisX;
this.rotationAxisY = rotationAxisY;
this.rotationAxisZ = rotationAxisZ;
return this;
}
public InstanceData setCycleLength(int cycleLength) {
this.cycleLength = cycleLength;
return this;
}
public InstanceData setCycleOffset(int cycleOffset) {
this.cycleOffset = cycleOffset;
return this;
}
void buffer(ByteBuffer buf) {
float blockLightCoordinates = LightTexture.getBlockLightCoordinates(packedLight) / (float) 0xF;
float skyLightCoordinates = LightTexture.getSkyLightCoordinates(packedLight) / (float) 0xF;
buf.putFloat(x);
buf.putFloat(y);
buf.putFloat(z);
buf.putFloat(blockLightCoordinates);
buf.putFloat(skyLightCoordinates);
buf.putFloat(rotationalSpeed);
buf.putFloat(rotationOffset);
buf.putFloat(rotationAxisX);
buf.putFloat(rotationAxisY);
buf.putFloat(rotationAxisZ);
buf.putInt(cycleLength);
buf.putInt(cycleOffset);
}
}
}

View file

@ -1,4 +1,4 @@
package com.simibubi.create.foundation.utility;
package com.simibubi.create.foundation.utility.render;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.vertex.IVertexBuilder;

View file

@ -1,19 +1,16 @@
package com.simibubi.create.foundation.utility;
package com.simibubi.create.foundation.utility.render;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.vertex.IVertexBuilder;
import com.mojang.datafixers.util.Pair;
import com.simibubi.create.foundation.block.render.SpriteShiftEntry;
import it.unimi.dsi.fastutil.longs.Long2DoubleMap;
import it.unimi.dsi.fastutil.longs.Long2DoubleOpenHashMap;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.BufferBuilder.DrawState;
import net.minecraft.client.renderer.GLAllocation;
import net.minecraft.client.renderer.Matrix4f;
import net.minecraft.client.renderer.Vector4f;
@ -23,15 +20,12 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.world.LightType;
import net.minecraft.world.World;
public class SuperByteBuffer {
public class SuperByteBuffer extends TemplateBuffer {
public interface IVertexLighter {
public int getPackedLight(float x, float y, float z);
}
protected ByteBuffer template;
protected int formatSize;
// Vertex Position
private MatrixStack transforms;
@ -51,21 +45,7 @@ public class SuperByteBuffer {
private float sheetSize;
public SuperByteBuffer(BufferBuilder buf) {
Pair<DrawState, ByteBuffer> state = buf.popData();
ByteBuffer rendered = state.getSecond();
rendered.order(ByteOrder.nativeOrder()); // Vanilla bug, endianness does not carry over into sliced buffers
formatSize = buf.getVertexFormat()
.getSize();
int size = state.getFirst()
.getCount() * formatSize;
template = GLAllocation.createDirectByteBuffer(size);
template.order(rendered.order());
((Buffer) template).limit(((Buffer) rendered).limit());
template.put(rendered);
((Buffer) template).rewind();
super(buf);
transforms = new MatrixStack();
}
@ -219,66 +199,6 @@ public class SuperByteBuffer {
return this;
}
protected int vertexCount(ByteBuffer buffer) {
return ((Buffer) buffer).limit() / formatSize;
}
protected int getBufferPosition(int vertexIndex) {
return vertexIndex * formatSize;
}
protected float getX(ByteBuffer buffer, int index) {
return buffer.getFloat(getBufferPosition(index));
}
protected float getY(ByteBuffer buffer, int index) {
return buffer.getFloat(getBufferPosition(index) + 4);
}
protected float getZ(ByteBuffer buffer, int index) {
return buffer.getFloat(getBufferPosition(index) + 8);
}
protected byte getR(ByteBuffer buffer, int index) {
return buffer.get(getBufferPosition(index) + 12);
}
protected byte getG(ByteBuffer buffer, int index) {
return buffer.get(getBufferPosition(index) + 13);
}
protected byte getB(ByteBuffer buffer, int index) {
return buffer.get(getBufferPosition(index) + 14);
}
protected byte getA(ByteBuffer buffer, int index) {
return buffer.get(getBufferPosition(index) + 15);
}
protected float getU(ByteBuffer buffer, int index) {
return buffer.getFloat(getBufferPosition(index) + 16);
}
protected float getV(ByteBuffer buffer, int index) {
return buffer.getFloat(getBufferPosition(index) + 20);
}
protected int getLight(ByteBuffer buffer, int index) {
return buffer.getInt(getBufferPosition(index) + 24);
}
protected byte getNX(ByteBuffer buffer, int index) {
return buffer.get(getBufferPosition(index) + 28);
}
protected byte getNY(ByteBuffer buffer, int index) {
return buffer.get(getBufferPosition(index) + 29);
}
protected byte getNZ(ByteBuffer buffer, int index) {
return buffer.get(getBufferPosition(index) + 30);
}
private static int getLight(World world, Vector4f lightPos) {
BlockPos.Mutable pos = new BlockPos.Mutable();
double sky = 0, block = 0;

View file

@ -1,11 +1,15 @@
package com.simibubi.create.foundation.utility;
package com.simibubi.create.foundation.utility.render;
import java.util.HashMap;
import java.util.Map;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
import com.google.common.collect.Collections2;
import com.simibubi.create.CreateClient;
import com.simibubi.create.foundation.utility.VirtualEmptyModelData;
import net.minecraftforge.client.event.EntityViewRenderEvent;
import net.minecraftforge.client.event.RenderWorldLastEvent;
import org.apache.commons.lang3.tuple.Pair;
import org.lwjgl.opengl.GL11;
@ -50,7 +54,6 @@ public class SuperByteBufferCache {
public SuperByteBuffer renderPartial(AllBlockPartials partial, BlockState referenceState) {
return get(PARTIAL, partial, () -> standardModelRender(partial.get(), referenceState));
}
public SuperByteBuffer renderPartial(AllBlockPartials partial, BlockState referenceState,
MatrixStack modelTransform) {
return get(PARTIAL, partial, () -> standardModelRender(partial.get(), referenceState, modelTransform));
@ -108,21 +111,27 @@ public class SuperByteBufferCache {
}
private SuperByteBuffer standardModelRender(IBakedModel model, BlockState referenceState, MatrixStack ms) {
BufferBuilder builder = getBufferBuilder(model, referenceState, ms);
return new SuperByteBuffer(builder);
}
public static BufferBuilder getBufferBuilder(IBakedModel model, BlockState referenceState, MatrixStack ms) {
Minecraft mc = Minecraft.getInstance();
BlockRendererDispatcher dispatcher = mc.getBlockRendererDispatcher();
BlockModelRenderer blockRenderer = dispatcher.getBlockModelRenderer();
BufferBuilder builder = new BufferBuilder(512);
builder.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK);
blockRenderer.renderModel(mc.world, model, referenceState, BlockPos.ZERO.up(255), ms, builder, true,
mc.world.rand, 42, OverlayTexture.DEFAULT_UV, VirtualEmptyModelData.INSTANCE);
blockRenderer.renderModel(mc.world, model, referenceState, BlockPos.ZERO.up(255), ms, builder, true, mc.world.rand, 42, OverlayTexture.DEFAULT_UV, VirtualEmptyModelData.INSTANCE);
builder.finishDrawing();
return new SuperByteBuffer(builder);
return builder;
}
public void invalidate() {
cache.forEach((comp, cache) -> cache.invalidateAll());
CreateClient.kineticRenderer.invalidate();
}
}

View file

@ -0,0 +1,107 @@
package com.simibubi.create.foundation.utility.render;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.datafixers.util.Pair;
import com.simibubi.create.foundation.block.render.SpriteShiftEntry;
import it.unimi.dsi.fastutil.longs.Long2DoubleMap;
import it.unimi.dsi.fastutil.longs.Long2DoubleOpenHashMap;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GLAllocation;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.vector.Matrix4f;
import net.minecraft.util.math.vector.Vector4f;
import net.minecraft.world.LightType;
import net.minecraft.world.World;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.time.temporal.TemporalAccessor;
public class TemplateBuffer {
protected ByteBuffer template;
protected int formatSize;
protected int count;
public TemplateBuffer(BufferBuilder buf) {
Pair<BufferBuilder.DrawState, ByteBuffer> state = buf.popData();
ByteBuffer rendered = state.getSecond();
rendered.order(ByteOrder.nativeOrder()); // Vanilla bug, endianness does not carry over into sliced buffers
formatSize = buf.getVertexFormat()
.getSize();
count = state.getFirst().getCount();
int size = count * formatSize;
template = GLAllocation.createDirectByteBuffer(size);
template.order(rendered.order());
((Buffer)template).limit(((Buffer)rendered).limit());
template.put(rendered);
((Buffer)template).rewind();
}
public boolean isEmpty() {
return ((Buffer) template).limit() == 0;
}
protected int vertexCount(ByteBuffer buffer) {
return ((Buffer)buffer).limit() / formatSize;
}
protected int getBufferPosition(int vertexIndex) {
return vertexIndex * formatSize;
}
protected float getX(ByteBuffer buffer, int index) {
return buffer.getFloat(getBufferPosition(index));
}
protected float getY(ByteBuffer buffer, int index) {
return buffer.getFloat(getBufferPosition(index) + 4);
}
protected float getZ(ByteBuffer buffer, int index) {
return buffer.getFloat(getBufferPosition(index) + 8);
}
protected byte getR(ByteBuffer buffer, int index) {
return buffer.get(getBufferPosition(index) + 12);
}
protected byte getG(ByteBuffer buffer, int index) {
return buffer.get(getBufferPosition(index) + 13);
}
protected byte getB(ByteBuffer buffer, int index) {
return buffer.get(getBufferPosition(index) + 14);
}
protected byte getA(ByteBuffer buffer, int index) {
return buffer.get(getBufferPosition(index) + 15);
}
protected float getU(ByteBuffer buffer, int index) {
return buffer.getFloat(getBufferPosition(index) + 16);
}
protected float getV(ByteBuffer buffer, int index) {
return buffer.getFloat(getBufferPosition(index) + 20);
}
protected int getLight(ByteBuffer buffer, int index) {
return buffer.getInt(getBufferPosition(index) + 24);
}
protected byte getNX(ByteBuffer buffer, int index) {
return buffer.get(getBufferPosition(index) + 28);
}
protected byte getNY(ByteBuffer buffer, int index) {
return buffer.get(getBufferPosition(index) + 29);
}
protected byte getNZ(ByteBuffer buffer, int index) {
return buffer.get(getBufferPosition(index) + 30);
}
}

View file

@ -1,4 +1,4 @@
package com.simibubi.create.foundation.utility;
package com.simibubi.create.foundation.utility.render;
import java.util.Iterator;
@ -6,6 +6,7 @@ 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 net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.Matrix4f;

View file

@ -0,0 +1,13 @@
package com.simibubi.create.foundation.utility.render.shader;
public enum Shader {
ROTATING_INSTANCED("shader/instanced.vert", "shader/instanced.frag");
public final String vert;
public final String frag;
Shader(String vert, String frag) {
this.vert = vert;
this.frag = frag;
}
}

View file

@ -0,0 +1,10 @@
package com.simibubi.create.foundation.utility.render.shader;
/**
* A Callback for when a shader is called. Used to define shader uniforms.
*/
@FunctionalInterface
public interface ShaderCallback {
void call(int shader);
}

View file

@ -0,0 +1,140 @@
package com.simibubi.create.foundation.utility.render.shader;
import com.mojang.blaze3d.platform.GlStateManager;
import com.simibubi.create.Create;
import com.simibubi.create.CreateClient;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import net.minecraft.client.MainWindow;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.ActiveRenderInfo;
import net.minecraft.client.shader.IShaderManager;
import net.minecraft.client.shader.ShaderLinkHelper;
import net.minecraft.client.shader.ShaderLoader;
import net.minecraft.resources.IReloadableResourceManager;
import net.minecraft.resources.IResourceManager;
import net.minecraft.resources.IResourceManagerReloadListener;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.event.EntityViewRenderEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.lwjgl.system.MemoryUtil;
import javax.annotation.Nullable;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.FloatBuffer;
import java.util.EnumMap;
import java.util.Locale;
import java.util.Map;
public class ShaderHelper {
public static final Logger log = LogManager.getLogger("shader");
public static final FloatBuffer FLOAT_BUFFER = MemoryUtil.memAllocFloat(1);
public static final FloatBuffer MATRIX_BUFFER = MemoryUtil.memAllocFloat(16);
private static final Map<Shader, ShaderProgram> PROGRAMS = new EnumMap<>(Shader.class);
@SuppressWarnings("deprecation")
public static void initShaders() {
// Can be null when running datagenerators due to the unfortunate time we call this
if (Minecraft.getInstance() != null
&& Minecraft.getInstance().getResourceManager() instanceof IReloadableResourceManager) {
((IReloadableResourceManager) Minecraft.getInstance().getResourceManager()).addReloadListener(
(IResourceManagerReloadListener) manager -> {
PROGRAMS.values().forEach(ShaderLinkHelper::deleteShader);
PROGRAMS.clear();
for (Shader shader : Shader.values()) {
createProgram(manager, shader);
}
});
}
}
public static void useShader(Shader shader) {
useShader(shader, null);
}
public static void useShader(Shader shader, @Nullable ShaderCallback cb) {
ShaderProgram prog = PROGRAMS.get(shader);
if (prog == null) {
return;
}
int program = prog.getProgram();
ShaderLinkHelper.useProgram(program);
int time = GlStateManager.getUniformLocation(program, "time");
FLOAT_BUFFER.position(0);
FLOAT_BUFFER.put(0, AnimationTickHolder.getRenderTick());
GlStateManager.uniform1(time, FLOAT_BUFFER);
int ticks = GlStateManager.getUniformLocation(program, "ticks");
GlStateManager.uniform1(ticks, AnimationTickHolder.ticks);
if (cb != null) {
cb.call(program);
}
}
public static void releaseShader() {
ShaderLinkHelper.useProgram(0);
}
private static void createProgram(IResourceManager manager, Shader shader) {
try {
ShaderLoader vert = createShader(manager, shader.vert, ShaderLoader.ShaderType.VERTEX);
ShaderLoader frag = createShader(manager, shader.frag, ShaderLoader.ShaderType.FRAGMENT);
int progId = ShaderLinkHelper.createProgram();
ShaderProgram prog = new ShaderProgram(progId, vert, frag);
ShaderLinkHelper.linkProgram(prog);
PROGRAMS.put(shader, prog);
log.info("Loaded program {}", shader.name());
} catch (IOException ex) {
log.error("Failed to load program {}", shader.name(), ex);
}
}
private static ShaderLoader createShader(IResourceManager manager, String filename, ShaderLoader.ShaderType shaderType) throws IOException {
ResourceLocation loc = new ResourceLocation(Create.ID, filename);
try (InputStream is = new BufferedInputStream(manager.getResource(loc).getInputStream())) {
return ShaderLoader.func_216534_a(shaderType, loc.toString(), is, shaderType.name().toLowerCase(Locale.ROOT));
}
}
private static class ShaderProgram implements IShaderManager {
private final int program;
private final ShaderLoader vert;
private final ShaderLoader frag;
private ShaderProgram(int program, ShaderLoader vert, ShaderLoader frag) {
this.program = program;
this.vert = vert;
this.frag = frag;
}
@Override
public int getProgram() {
return program;
}
@Override
public void markDirty() {
}
@Override
public ShaderLoader getVertexShaderLoader() {
return vert;
}
@Override
public ShaderLoader getFragmentShaderLoader() {
return frag;
}
}
}

View file

@ -23,4 +23,8 @@ public net.minecraft.tileentity.BeaconTileEntity field_174909_f # beamSegments
# Server Tick List (For stopping placed fluids from spilling)
public net.minecraft.world.server.ServerTickList field_205374_d # pendingTickListEntriesHashSet
public net.minecraft.world.server.ServerTickList field_205375_e # pendingTickListEntriesTreeSet
public net.minecraft.world.server.ServerTickList field_205375_e # pendingTickListEntriesTreeSet
# Lightmap information for instanced rendering
public net.minecraft.client.renderer.LightTexture field_205112_c #resourceLocation
public net.minecraft.client.Minecraft field_193996_ah #renderPartialTicksPaused

View file

@ -0,0 +1,29 @@
#version 440 core
in vec2 TexCoords;
in vec2 Light;
out vec4 fragColor;
layout(binding=0) uniform sampler2D BlockAtlas;
layout(binding=1) uniform sampler2D LightMap;
float blendDarken(float base, float blend) {
return min(blend,base);
}
vec3 blendDarken(vec3 base, vec3 blend) {
return vec3(blendDarken(base.r,blend.r),blendDarken(base.g,blend.g),blendDarken(base.b,blend.b));
}
vec3 blendDarken(vec3 base, vec3 blend, float opacity) {
return (blendDarken(base, blend) * opacity + base * (1.0 - opacity));
}
void main()
{
vec4 tex = texture2D(BlockAtlas, TexCoords);
vec4 light = texture2D(LightMap, Light);
fragColor = vec4(blendDarken(tex.rgb, light.rgb, light.a), tex.a);
}

View file

@ -0,0 +1,60 @@
#version 330 core
#define PI 3.1415926538
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
layout (location = 2) in vec2 aTexCoords;
layout (location = 3) in vec3 instancePos;
layout (location = 4) in vec2 light;
layout (location = 5) in float speed;
layout (location = 6) in float rotationOffset;
layout (location = 7) in vec3 rotationAxis;
layout (location = 8) in int[2] uvScroll; // uvScroll[0] <- cycleLength, uvScroll[1] <- cycleOffset
out vec2 TexCoords;
out vec2 Light;
uniform float time;
uniform int ticks;
uniform mat4 projection;
uniform mat4 view;
mat4 rotationMatrix(vec3 axis, float angle)
{
axis = normalize(axis);
float s = sin(angle);
float c = cos(angle);
float oc = 1.0 - c;
return mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.,
oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.,
oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.,
0., 0., 0., 1.);
}
void main()
{
vec4 renderPos;
int textureIndex = 0;
if (abs(rotationAxis.x) + abs(rotationAxis.y) + abs(rotationAxis.z) < 0.2) {
renderPos = vec4(aPos + instancePos, 1f);
textureIndex = int((speed * time / 36) + uvScroll[1]) % uvScroll[0];
if (textureIndex < 0) {
textureIndex += uvScroll[0];
}
} else {
float degrees = rotationOffset + time * speed * 3./10.;
float angle = fract(-degrees / 360.) * PI * 2.;
renderPos = rotationMatrix(rotationAxis, angle) * vec4(aPos - vec3(0.5), 1f);
renderPos += vec4(instancePos + vec3(0.5), 0);
}
TexCoords = aTexCoords + vec2(float(textureIndex % 4) / 4f, float(textureIndex / 4) / 4f);
gl_Position = projection * view * renderPos;
Light = light;
}