merge experimental rendering from 1.16 to 1.15
This commit is contained in:
parent
3cdbf47cb9
commit
7d43bb056a
59 changed files with 1079 additions and 268 deletions
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,9 +112,9 @@ 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,
|
||||
transform(te.getWorld(), (SuperByteBuffer) 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,
|
||||
transform(te.getWorld(), (SuperByteBuffer) hand.translate(offset.x, offset.y, offset.z), blockState, pos, false).renderInto(ms,
|
||||
vb);
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
InstancedBuffer shaftHalf =
|
||||
AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthInstanced(te.getBlockState(), direction.getOpposite());
|
||||
InstancedBuffer fanInner =
|
||||
AllBlockPartials.ENCASED_FAN_INNER.renderOnDirectionalSouthInstanced(te.getBlockState(), direction.getOpposite());
|
||||
|
||||
renderRotatingBuffer(te, shaftHalf, lightBehind);
|
||||
fanInner.setupInstance(data -> {
|
||||
final BlockPos pos = te.getPos();
|
||||
Direction.Axis axis = ((IRotate) te.getBlockState()
|
||||
.getBlock()).getRotationAxis(te.getBlockState());
|
||||
|
||||
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;
|
||||
|
||||
standardKineticRotationTransform(shaftHalf, te, lightBehind).renderInto(ms, vb);
|
||||
kineticRotationTransform(fanInner, te, direction.getAxis(), angle, lightInFront).renderInto(ms, vb);
|
||||
data.setPackedLight(lightInFront)
|
||||
.setRotationalSpeed(speed)
|
||||
.setRotationOffset(getRotationOffsetForPosition(te, pos, axis))
|
||||
.setRotationAxis(Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis).getUnitVector())
|
||||
.setPosition(pos);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)));
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
beltBuffer.setupInstance(data -> {
|
||||
float speed = te.getSpeed();
|
||||
if (speed != 0) {
|
||||
float time = renderTick * axisDirection.getOffset();
|
||||
if (diagonal && (downward ^ alongX) || !sideways && !diagonal && alongX
|
||||
|| 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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
InstancedBuffer shaft = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthInstanced(te.getBlockState(), direction);
|
||||
|
||||
shaft.setupInstance(data -> {
|
||||
float speed = te.getSpeed();
|
||||
|
||||
float modifier = 1;
|
||||
|
||||
if (te instanceof SplitShaftTileEntity)
|
||||
modifier = ((SplitShaftTileEntity) te).getRotationSpeedModifier(direction);
|
||||
|
||||
angle *= modifier;
|
||||
angle += offset;
|
||||
angle = angle / 180f * (float) Math.PI;
|
||||
speed *= modifier;
|
||||
|
||||
SuperByteBuffer superByteBuffer =
|
||||
AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouth(te.getBlockState(), direction);
|
||||
kineticRotationTransform(superByteBuffer, te, axis, angle, light);
|
||||
superByteBuffer.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);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
shaft.setupInstance(data -> {
|
||||
float speed = te.getSpeed();
|
||||
|
||||
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;
|
||||
speed *= sourceFacing == direction ? 1 : -1;
|
||||
else if (sourceFacing.getAxisDirection() == direction.getAxisDirection())
|
||||
angle *= -1;
|
||||
speed *= -1;
|
||||
}
|
||||
|
||||
angle += offset;
|
||||
angle = angle / 180f * (float) Math.PI;
|
||||
|
||||
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);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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> {
|
||||
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
|
@ -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;
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -24,3 +24,7 @@ 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
|
||||
|
||||
# Lightmap information for instanced rendering
|
||||
public net.minecraft.client.renderer.LightTexture field_205112_c #resourceLocation
|
||||
public net.minecraft.client.Minecraft field_193996_ah #renderPartialTicksPaused
|
29
src/main/resources/assets/create/shader/instanced.frag
Normal file
29
src/main/resources/assets/create/shader/instanced.frag
Normal 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);
|
||||
}
|
60
src/main/resources/assets/create/shader/instanced.vert
Normal file
60
src/main/resources/assets/create/shader/instanced.vert
Normal 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;
|
||||
}
|
Loading…
Reference in a new issue