a bunch of refactoring to make things easier later
it's not any more stable but belts render on contraptions rotating things almost do actually fix a bunch of memory leaks
This commit is contained in:
parent
092a92f095
commit
a56d08b78e
43 changed files with 916 additions and 396 deletions
|
@ -9,12 +9,13 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||||
|
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
||||||
import com.simibubi.create.content.contraptions.fluids.FluidTransportBehaviour.AttachmentTypes;
|
import com.simibubi.create.content.contraptions.fluids.FluidTransportBehaviour.AttachmentTypes;
|
||||||
import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock.HeatLevel;
|
import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock.HeatLevel;
|
||||||
|
import com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity;
|
||||||
import com.simibubi.create.foundation.utility.*;
|
import com.simibubi.create.foundation.utility.*;
|
||||||
|
|
||||||
import com.simibubi.create.foundation.utility.render.instancing.BeltBuffer;
|
import com.simibubi.create.foundation.utility.render.instancing.*;
|
||||||
import com.simibubi.create.foundation.utility.render.instancing.RotatingBuffer;
|
|
||||||
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
|
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.client.renderer.model.IBakedModel;
|
import net.minecraft.client.renderer.model.IBakedModel;
|
||||||
|
@ -217,19 +218,20 @@ public class AllBlockPartials {
|
||||||
return CreateClient.bufferCache.renderDirectionalPartial(this, referenceState, facing, ms);
|
return CreateClient.bufferCache.renderDirectionalPartial(this, referenceState, facing, ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RotatingBuffer renderOnRotating(BlockState referenceState) {
|
public <T extends KineticTileEntity> InstanceBuffer<RotatingData> renderOnRotating(InstanceContext<T> ctx, BlockState referenceState) {
|
||||||
return CreateClient.kineticRenderer.renderPartialRotating(this, referenceState);
|
return ctx.getKinetics().renderPartialRotating(this, referenceState);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BeltBuffer renderOnBelt(BlockState referenceState) {
|
public <T extends BeltTileEntity> InstanceBuffer<BeltData> renderOnBelt(InstanceContext<T> ctx, BlockState referenceState) {
|
||||||
return CreateClient.kineticRenderer.renderPartialBelt(this, referenceState);
|
return ctx.getKinetics().renderPartialBelt(this, referenceState);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RotatingBuffer renderOnDirectionalSouthRotating(BlockState referenceState) {
|
public <T extends KineticTileEntity> InstanceBuffer<RotatingData> renderOnDirectionalSouthRotating(InstanceContext<T> ctx, BlockState referenceState) {
|
||||||
Direction facing = referenceState.get(FACING);
|
Direction facing = referenceState.get(FACING);
|
||||||
return renderOnDirectionalSouthRotating(referenceState, facing);
|
return renderOnDirectionalSouthRotating(ctx, referenceState, facing);
|
||||||
}
|
}
|
||||||
public RotatingBuffer renderOnDirectionalSouthRotating(BlockState referenceState, Direction facing) {
|
|
||||||
|
public <T extends KineticTileEntity> InstanceBuffer<RotatingData> renderOnDirectionalSouthRotating(InstanceContext<T> ctx, BlockState referenceState, Direction facing) {
|
||||||
MatrixStack ms = new MatrixStack();
|
MatrixStack ms = new MatrixStack();
|
||||||
// TODO 1.15 find a way to cache this model matrix computation
|
// TODO 1.15 find a way to cache this model matrix computation
|
||||||
MatrixStacker.of(ms)
|
MatrixStacker.of(ms)
|
||||||
|
@ -237,7 +239,7 @@ public class AllBlockPartials {
|
||||||
.rotateY(AngleHelper.horizontalAngle(facing))
|
.rotateY(AngleHelper.horizontalAngle(facing))
|
||||||
.rotateX(AngleHelper.verticalAngle(facing))
|
.rotateX(AngleHelper.verticalAngle(facing))
|
||||||
.unCentre();
|
.unCentre();
|
||||||
return CreateClient.kineticRenderer.renderDirectionalPartialInstanced(this, referenceState, facing, ms);
|
return ctx.getKinetics().renderDirectionalPartialInstanced(this, referenceState, facing, ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ import com.simibubi.create.foundation.block.render.CustomBlockModels;
|
||||||
import com.simibubi.create.foundation.block.render.SpriteShifter;
|
import com.simibubi.create.foundation.block.render.SpriteShifter;
|
||||||
import com.simibubi.create.foundation.item.CustomItemModels;
|
import com.simibubi.create.foundation.item.CustomItemModels;
|
||||||
import com.simibubi.create.foundation.item.CustomRenderedItems;
|
import com.simibubi.create.foundation.item.CustomRenderedItems;
|
||||||
|
import com.simibubi.create.foundation.utility.render.FastContraptionRenderer;
|
||||||
import com.simibubi.create.foundation.utility.render.FastKineticRenderer;
|
import com.simibubi.create.foundation.utility.render.FastKineticRenderer;
|
||||||
import com.simibubi.create.foundation.utility.render.SuperByteBufferCache;
|
import com.simibubi.create.foundation.utility.render.SuperByteBufferCache;
|
||||||
import com.simibubi.create.foundation.utility.outliner.Outliner;
|
import com.simibubi.create.foundation.utility.outliner.Outliner;
|
||||||
|
@ -73,8 +74,6 @@ public class CreateClient {
|
||||||
bufferCache.registerCompartment(ContraptionRenderer.CONTRAPTION, 20);
|
bufferCache.registerCompartment(ContraptionRenderer.CONTRAPTION, 20);
|
||||||
|
|
||||||
kineticRenderer = new FastKineticRenderer();
|
kineticRenderer = new FastKineticRenderer();
|
||||||
kineticRenderer.registerCompartment(KineticTileEntityRenderer.KINETIC_TILE);
|
|
||||||
kineticRenderer.registerCompartment(ContraptionRenderer.CONTRAPTION, 20);
|
|
||||||
|
|
||||||
AllKeys.register();
|
AllKeys.register();
|
||||||
AllContainerTypes.registerScreenFactories();
|
AllContainerTypes.registerScreenFactories();
|
||||||
|
@ -180,4 +179,9 @@ public class CreateClient {
|
||||||
return casingConnectivity;
|
return casingConnectivity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void invalidateRenderers() {
|
||||||
|
CreateClient.bufferCache.invalidate();
|
||||||
|
CreateClient.kineticRenderer.invalidate();
|
||||||
|
FastContraptionRenderer.invalidateAll();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -457,8 +457,14 @@ public abstract class KineticTileEntity extends SmartTileEntity
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AxisAlignedBB NOWHERE_AABB = new AxisAlignedBB(Double.NaN, Double.NaN, Double.NaN, Double.NaN, Double.NaN, Double.NaN);
|
public static AxisAlignedBB NOWHERE_AABB = new AxisAlignedBB(Double.NaN, Double.NaN, Double.NaN, Double.NaN, Double.NaN, Double.NaN);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AxisAlignedBB getRenderBoundingBox() {
|
public AxisAlignedBB getRenderBoundingBox() {
|
||||||
return super.getRenderBoundingBox();
|
return super.getRenderBoundingBox();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getMaxRenderDistanceSquared() {
|
||||||
|
return 16384.0D; // TODO: make this a config option
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,21 +2,17 @@ package com.simibubi.create.content.contraptions.base;
|
||||||
|
|
||||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
import com.simibubi.create.CreateClient;
|
|
||||||
import com.simibubi.create.content.contraptions.KineticDebugger;
|
import com.simibubi.create.content.contraptions.KineticDebugger;
|
||||||
import com.simibubi.create.content.contraptions.relays.elementary.CogWheelBlock;
|
import com.simibubi.create.content.contraptions.relays.elementary.CogWheelBlock;
|
||||||
import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer;
|
import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer;
|
||||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||||
import com.simibubi.create.foundation.utility.ColorHelper;
|
import com.simibubi.create.foundation.utility.ColorHelper;
|
||||||
import com.simibubi.create.foundation.utility.render.instancing.IInstancedTileEntityRenderer;
|
import com.simibubi.create.foundation.utility.render.instancing.*;
|
||||||
import com.simibubi.create.foundation.utility.render.instancing.RotatingBuffer;
|
|
||||||
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
|
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
|
||||||
import com.simibubi.create.foundation.utility.render.SuperByteBufferCache.Compartment;
|
import com.simibubi.create.foundation.utility.render.SuperByteBufferCache.Compartment;
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||||
import net.minecraft.client.renderer.RenderType;
|
|
||||||
import net.minecraft.client.renderer.RenderTypeLookup;
|
|
||||||
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
||||||
import net.minecraft.state.properties.BlockStateProperties;
|
import net.minecraft.state.properties.BlockStateProperties;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
|
@ -48,32 +44,36 @@ public class KineticTileEntityRenderer extends SafeTileEntityRenderer<KineticTil
|
||||||
// for (RenderType type : RenderType.getBlockLayers())
|
// for (RenderType type : RenderType.getBlockLayers())
|
||||||
// if (RenderTypeLookup.canRenderInLayer(te.getBlockState(), type))
|
// if (RenderTypeLookup.canRenderInLayer(te.getBlockState(), type))
|
||||||
// renderRotatingBuffer(te, getRotatedModel(te));
|
// renderRotatingBuffer(te, getRotatedModel(te));
|
||||||
addInstanceData(te);
|
|
||||||
|
addInstanceData(new InstanceContext.World<>(te));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addInstanceData(KineticTileEntity te) {
|
public void addInstanceData(InstanceContext<KineticTileEntity> ctx) {
|
||||||
renderRotatingBuffer(te, getRotatedModel(te));
|
renderRotatingBuffer(ctx, getRotatedModel(ctx));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void renderRotatingKineticBlock(KineticTileEntity te, BlockState renderedState) {
|
public static <T extends KineticTileEntity> void renderRotatingKineticBlock(InstanceContext<T> ctx, BlockState renderedState) {
|
||||||
RotatingBuffer instancedRenderer = CreateClient.kineticRenderer.renderBlockInstanced(KINETIC_TILE, renderedState);
|
InstanceBuffer<RotatingData> instancedRenderer = ctx.getKinetics().renderBlockInstanced(KINETIC_TILE, renderedState);
|
||||||
renderRotatingBuffer(te, instancedRenderer);
|
renderRotatingBuffer(ctx, instancedRenderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void renderRotatingBuffer(KineticTileEntity te, RotatingBuffer instancer) {
|
public static <T extends KineticTileEntity> void renderRotatingBuffer(InstanceContext<T> ctx, InstanceBuffer<RotatingData> instancer) {
|
||||||
instancer.setupInstance(data -> {
|
instancer.setupInstance(data -> {
|
||||||
|
T te = ctx.te;
|
||||||
final BlockPos pos = te.getPos();
|
final BlockPos pos = te.getPos();
|
||||||
Axis axis = ((IRotate) te.getBlockState()
|
Axis axis = ((IRotate) te.getBlockState()
|
||||||
.getBlock()).getRotationAxis(te.getBlockState());
|
.getBlock()).getRotationAxis(te.getBlockState());
|
||||||
|
|
||||||
data
|
data.setRotationalSpeed(te.getSpeed())
|
||||||
.setBlockLight(te.getWorld().getLightLevel(LightType.BLOCK, te.getPos()))
|
|
||||||
.setSkyLight(te.getWorld().getLightLevel(LightType.SKY, te.getPos()))
|
|
||||||
.setRotationalSpeed(te.getSpeed())
|
|
||||||
.setRotationOffset(getRotationOffsetForPosition(te, pos, axis))
|
.setRotationOffset(getRotationOffsetForPosition(te, pos, axis))
|
||||||
.setRotationAxis(Direction.getFacingFromAxis(AxisDirection.POSITIVE, axis).getUnitVector())
|
.setRotationAxis(Direction.getFacingFromAxis(AxisDirection.POSITIVE, axis).getUnitVector())
|
||||||
.setPosition(pos);
|
.setPosition(pos);
|
||||||
|
|
||||||
|
if (ctx.checkWorldLight()) {
|
||||||
|
data.setBlockLight(te.getWorld().getLightLevel(LightType.BLOCK, te.getPos()))
|
||||||
|
.setSkyLight(te.getWorld().getLightLevel(LightType.SKY, te.getPos()));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,8 +139,8 @@ public class KineticTileEntityRenderer extends SafeTileEntityRenderer<KineticTil
|
||||||
return te.getBlockState();
|
return te.getBlockState();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected RotatingBuffer getRotatedModel(KineticTileEntity te) {
|
protected InstanceBuffer<RotatingData> getRotatedModel(InstanceContext<? extends KineticTileEntity> ctx) {
|
||||||
return CreateClient.kineticRenderer.renderBlockInstanced(KINETIC_TILE, getRenderedBlockState(te));
|
return ctx.getKinetics().renderBlockInstanced(KINETIC_TILE, getRenderedBlockState(ctx.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.AngleHelper;
|
||||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||||
import com.simibubi.create.foundation.utility.MatrixStacker;
|
import com.simibubi.create.foundation.utility.MatrixStacker;
|
||||||
import com.simibubi.create.foundation.utility.render.instancing.RotatingBuffer;
|
import com.simibubi.create.foundation.utility.render.instancing.InstanceBuffer;
|
||||||
|
import com.simibubi.create.foundation.utility.render.instancing.InstanceContext;
|
||||||
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
|
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
|
||||||
import com.simibubi.create.foundation.utility.VecHelper;
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
|
|
||||||
|
@ -28,8 +29,8 @@ public class DrillRenderer extends KineticTileEntityRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected RotatingBuffer getRotatedModel(KineticTileEntity te) {
|
protected InstanceBuffer<RotatingData> getRotatedModel(InstanceContext<? extends KineticTileEntity> ctx) {
|
||||||
return AllBlockPartials.DRILL_HEAD.renderOnDirectionalSouthRotating(te.getBlockState());
|
return AllBlockPartials.DRILL_HEAD.renderOnDirectionalSouthRotating(ctx, ctx.te.getBlockState());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static SuperByteBuffer getRotatingModel(BlockState state) {
|
protected static SuperByteBuffer getRotatingModel(BlockState state) {
|
||||||
|
|
|
@ -8,7 +8,7 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
|
||||||
import com.simibubi.create.content.contraptions.components.clock.CuckooClockTileEntity.Animation;
|
import com.simibubi.create.content.contraptions.components.clock.CuckooClockTileEntity.Animation;
|
||||||
import com.simibubi.create.foundation.utility.AngleHelper;
|
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||||
import com.simibubi.create.foundation.utility.render.instancing.InstanceBuffer;
|
import com.simibubi.create.foundation.utility.render.instancing.InstanceBuffer;
|
||||||
import com.simibubi.create.foundation.utility.render.instancing.RotatingBuffer;
|
import com.simibubi.create.foundation.utility.render.instancing.InstanceContext;
|
||||||
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
|
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
|
||||||
|
|
||||||
import com.simibubi.create.foundation.utility.render.instancing.RotatingData;
|
import com.simibubi.create.foundation.utility.render.instancing.RotatingData;
|
||||||
|
@ -93,14 +93,9 @@ public class CuckooClockRenderer extends KineticTileEntityRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected RotatingBuffer getRotatedModel(KineticTileEntity te) {
|
protected InstanceBuffer<RotatingData> getRotatedModel(InstanceContext<? extends KineticTileEntity> ctx) {
|
||||||
return transform(AllBlockPartials.SHAFT_HALF, te);
|
BlockState blockState = ctx.te.getBlockState();
|
||||||
}
|
return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(ctx, blockState, blockState.get(CuckooClockBlock.HORIZONTAL_FACING).getOpposite());
|
||||||
|
|
||||||
private RotatingBuffer transform(AllBlockPartials partial, KineticTileEntity te) {
|
|
||||||
return partial.renderOnDirectionalSouthRotating(te.getBlockState(), te.getBlockState()
|
|
||||||
.get(CuckooClockBlock.HORIZONTAL_FACING)
|
|
||||||
.getOpposite());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private SuperByteBuffer rotateHand(SuperByteBuffer buffer, float angle, Direction facing) {
|
private SuperByteBuffer rotateHand(SuperByteBuffer buffer, float angle, Direction facing) {
|
||||||
|
|
|
@ -20,6 +20,7 @@ import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
|
||||||
import com.simibubi.create.foundation.utility.VecHelper;
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
|
|
||||||
import com.simibubi.create.foundation.utility.render.instancing.IInstancedTileEntityRenderer;
|
import com.simibubi.create.foundation.utility.render.instancing.IInstancedTileEntityRenderer;
|
||||||
|
import com.simibubi.create.foundation.utility.render.instancing.InstanceContext;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||||
|
@ -51,12 +52,11 @@ public class DeployerRenderer extends SafeTileEntityRenderer<DeployerTileEntity>
|
||||||
FilteringRenderer.renderOnTileEntity(te, partialTicks, ms, buffer, light, overlay);
|
FilteringRenderer.renderOnTileEntity(te, partialTicks, ms, buffer, light, overlay);
|
||||||
renderComponents(te, partialTicks, ms, buffer, light, overlay);
|
renderComponents(te, partialTicks, ms, buffer, light, overlay);
|
||||||
|
|
||||||
addInstanceData(te);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addInstanceData(DeployerTileEntity te) {
|
public void addInstanceData(InstanceContext<DeployerTileEntity> ctx) {
|
||||||
KineticTileEntityRenderer.renderRotatingKineticBlock(te, getRenderedBlockState(te));
|
KineticTileEntityRenderer.renderRotatingKineticBlock(ctx, getRenderedBlockState(ctx.te));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void renderItem(DeployerTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer,
|
protected void renderItem(DeployerTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer,
|
||||||
|
@ -110,7 +110,7 @@ public class DeployerRenderer extends SafeTileEntityRenderer<DeployerTileEntity>
|
||||||
protected void renderComponents(DeployerTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer,
|
protected void renderComponents(DeployerTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer,
|
||||||
int light, int overlay) {
|
int light, int overlay) {
|
||||||
IVertexBuilder vb = buffer.getBuffer(RenderType.getSolid());
|
IVertexBuilder vb = buffer.getBuffer(RenderType.getSolid());
|
||||||
KineticTileEntityRenderer.renderRotatingKineticBlock(te, getRenderedBlockState(te));
|
KineticTileEntityRenderer.renderRotatingKineticBlock(new InstanceContext.World<>(te), getRenderedBlockState(te));
|
||||||
|
|
||||||
BlockState blockState = te.getBlockState();
|
BlockState blockState = te.getBlockState();
|
||||||
BlockPos pos = te.getPos();
|
BlockPos pos = te.getPos();
|
||||||
|
|
|
@ -8,7 +8,10 @@ import com.simibubi.create.content.contraptions.base.IRotate;
|
||||||
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
||||||
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
|
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.utility.render.instancing.InstanceBuffer;
|
||||||
|
import com.simibubi.create.foundation.utility.render.instancing.InstanceContext;
|
||||||
import com.simibubi.create.foundation.utility.render.instancing.RotatingBuffer;
|
import com.simibubi.create.foundation.utility.render.instancing.RotatingBuffer;
|
||||||
|
import com.simibubi.create.foundation.utility.render.instancing.RotatingData;
|
||||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||||
import net.minecraft.client.renderer.WorldRenderer;
|
import net.minecraft.client.renderer.WorldRenderer;
|
||||||
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
||||||
|
@ -26,24 +29,21 @@ public class EncasedFanRenderer extends KineticTileEntityRenderer {
|
||||||
@Override
|
@Override
|
||||||
protected void renderSafe(KineticTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer,
|
protected void renderSafe(KineticTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer,
|
||||||
int light, int overlay) {
|
int light, int overlay) {
|
||||||
addInstanceData(te);
|
super.renderSafe(te, partialTicks, ms, buffer, light, overlay);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addInstanceData(KineticTileEntity te) {
|
public void addInstanceData(InstanceContext<KineticTileEntity> ctx) {
|
||||||
|
KineticTileEntity te = ctx.te;
|
||||||
Direction direction = te.getBlockState()
|
Direction direction = te.getBlockState()
|
||||||
.get(FACING);
|
.get(FACING);
|
||||||
|
|
||||||
BlockPos inFront = te.getPos().offset(direction);
|
InstanceBuffer<RotatingData> shaftHalf =
|
||||||
int blockLight = te.getWorld().getLightLevel(LightType.BLOCK, inFront);
|
AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(ctx, te.getBlockState(), direction.getOpposite());
|
||||||
int skyLight = te.getWorld().getLightLevel(LightType.SKY, inFront);
|
InstanceBuffer<RotatingData> fanInner =
|
||||||
|
AllBlockPartials.ENCASED_FAN_INNER.renderOnDirectionalSouthRotating(ctx, te.getBlockState(), direction.getOpposite());
|
||||||
|
|
||||||
RotatingBuffer shaftHalf =
|
renderRotatingBuffer(ctx, shaftHalf);
|
||||||
AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(te.getBlockState(), direction.getOpposite());
|
|
||||||
RotatingBuffer fanInner =
|
|
||||||
AllBlockPartials.ENCASED_FAN_INNER.renderOnDirectionalSouthRotating(te.getBlockState(), direction.getOpposite());
|
|
||||||
|
|
||||||
renderRotatingBuffer(te, shaftHalf);
|
|
||||||
fanInner.setupInstance(data -> {
|
fanInner.setupInstance(data -> {
|
||||||
final BlockPos pos = te.getPos();
|
final BlockPos pos = te.getPos();
|
||||||
Direction.Axis axis = ((IRotate) te.getBlockState()
|
Direction.Axis axis = ((IRotate) te.getBlockState()
|
||||||
|
@ -55,12 +55,19 @@ public class EncasedFanRenderer extends KineticTileEntityRenderer {
|
||||||
if (speed < 0)
|
if (speed < 0)
|
||||||
speed = MathHelper.clamp(speed, -64 * 20, -80);
|
speed = MathHelper.clamp(speed, -64 * 20, -80);
|
||||||
|
|
||||||
data.setBlockLight(blockLight)
|
data.setRotationalSpeed(speed)
|
||||||
.setSkyLight(skyLight)
|
|
||||||
.setRotationalSpeed(speed)
|
|
||||||
.setRotationOffset(getRotationOffsetForPosition(te, pos, axis))
|
.setRotationOffset(getRotationOffsetForPosition(te, pos, axis))
|
||||||
.setRotationAxis(Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis).getUnitVector())
|
.setRotationAxis(Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis).getUnitVector())
|
||||||
.setPosition(pos);
|
.setPosition(pos);
|
||||||
|
|
||||||
|
if (ctx.checkWorldLight()) {
|
||||||
|
BlockPos inFront = te.getPos().offset(direction);
|
||||||
|
int blockLight = te.getWorld().getLightLevel(LightType.BLOCK, inFront);
|
||||||
|
int skyLight = te.getWorld().getLightLevel(LightType.SKY, inFront);
|
||||||
|
|
||||||
|
data.setBlockLight(blockLight)
|
||||||
|
.setSkyLight(skyLight);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,10 +9,10 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
||||||
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
|
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
|
||||||
import com.simibubi.create.content.contraptions.components.flywheel.FlywheelBlock.ConnectionState;
|
import com.simibubi.create.content.contraptions.components.flywheel.FlywheelBlock.ConnectionState;
|
||||||
import com.simibubi.create.foundation.utility.AngleHelper;
|
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||||
import com.simibubi.create.foundation.utility.render.instancing.InstanceBuffer;
|
|
||||||
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
|
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
|
||||||
|
|
||||||
import com.simibubi.create.foundation.utility.render.instancing.RotatingBuffer;
|
import com.simibubi.create.foundation.utility.render.instancing.InstanceBuffer;
|
||||||
|
import com.simibubi.create.foundation.utility.render.instancing.InstanceContext;
|
||||||
import com.simibubi.create.foundation.utility.render.instancing.RotatingData;
|
import com.simibubi.create.foundation.utility.render.instancing.RotatingData;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||||
|
@ -77,8 +77,8 @@ public class FlywheelRenderer extends KineticTileEntityRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected RotatingBuffer getRotatedModel(KineticTileEntity te) {
|
protected InstanceBuffer<RotatingData> getRotatedModel(InstanceContext<? extends KineticTileEntity> ctx) {
|
||||||
return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(te.getBlockState(), te.getBlockState()
|
return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(ctx, ctx.te.getBlockState(), ctx.te.getBlockState()
|
||||||
.get(HORIZONTAL_FACING)
|
.get(HORIZONTAL_FACING)
|
||||||
.getOpposite());
|
.getOpposite());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
package com.simibubi.create.content.contraptions.components.millstone;
|
package com.simibubi.create.content.contraptions.components.millstone;
|
||||||
|
|
||||||
import com.simibubi.create.AllBlockPartials;
|
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.KineticTileEntity;
|
||||||
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
|
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
|
||||||
|
|
||||||
import com.simibubi.create.foundation.utility.render.instancing.InstanceBuffer;
|
import com.simibubi.create.foundation.utility.render.instancing.InstanceBuffer;
|
||||||
import com.simibubi.create.foundation.utility.render.instancing.RotatingBuffer;
|
import com.simibubi.create.foundation.utility.render.instancing.InstanceContext;
|
||||||
import com.simibubi.create.foundation.utility.render.instancing.RotatingData;
|
import com.simibubi.create.foundation.utility.render.instancing.RotatingData;
|
||||||
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
||||||
|
|
||||||
|
@ -17,8 +16,8 @@ public class MillstoneRenderer extends KineticTileEntityRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected RotatingBuffer getRotatedModel(KineticTileEntity te) {
|
protected InstanceBuffer<RotatingData> getRotatedModel(InstanceContext<? extends KineticTileEntity> ctx) {
|
||||||
return CreateClient.kineticRenderer.renderPartialRotating(AllBlockPartials.MILLSTONE_COG, te.getBlockState());
|
return AllBlockPartials.MILLSTONE_COG.renderOnRotating(ctx, ctx.te.getBlockState());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
||||||
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
|
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
|
||||||
|
|
||||||
import com.simibubi.create.foundation.utility.render.instancing.InstanceBuffer;
|
import com.simibubi.create.foundation.utility.render.instancing.InstanceBuffer;
|
||||||
import com.simibubi.create.foundation.utility.render.instancing.RotatingBuffer;
|
import com.simibubi.create.foundation.utility.render.instancing.InstanceContext;
|
||||||
import com.simibubi.create.foundation.utility.render.instancing.RotatingData;
|
import com.simibubi.create.foundation.utility.render.instancing.RotatingData;
|
||||||
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
||||||
|
|
||||||
|
@ -16,8 +16,8 @@ public class CreativeMotorRenderer extends KineticTileEntityRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected RotatingBuffer getRotatedModel(KineticTileEntity te) {
|
protected InstanceBuffer<RotatingData> getRotatedModel(InstanceContext<? extends KineticTileEntity> ctx) {
|
||||||
return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(te.getBlockState());
|
return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(ctx, ctx.te.getBlockState());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,8 +12,7 @@ import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringRe
|
||||||
import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer;
|
import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer;
|
||||||
import com.simibubi.create.foundation.utility.*;
|
import com.simibubi.create.foundation.utility.*;
|
||||||
|
|
||||||
import com.simibubi.create.foundation.utility.render.instancing.IInstancedTileEntityRenderer;
|
import com.simibubi.create.foundation.utility.render.instancing.*;
|
||||||
import com.simibubi.create.foundation.utility.render.instancing.RotatingBuffer;
|
|
||||||
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
|
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
@ -43,12 +42,11 @@ public class SawRenderer extends SafeTileEntityRenderer<SawTileEntity> implement
|
||||||
renderItems(te, partialTicks, ms, buffer, light, overlay);
|
renderItems(te, partialTicks, ms, buffer, light, overlay);
|
||||||
FilteringRenderer.renderOnTileEntity(te, partialTicks, ms, buffer, light, overlay);
|
FilteringRenderer.renderOnTileEntity(te, partialTicks, ms, buffer, light, overlay);
|
||||||
|
|
||||||
addInstanceData(te);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addInstanceData(SawTileEntity te) {
|
public void addInstanceData(InstanceContext<SawTileEntity> ctx) {
|
||||||
KineticTileEntityRenderer.renderRotatingBuffer(te, getRotatedModel(te));
|
KineticTileEntityRenderer.renderRotatingBuffer(ctx, getRotatedModel(ctx));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void renderBlade(SawTileEntity te, MatrixStack ms, IRenderTypeBuffer buffer, int light){
|
protected void renderBlade(SawTileEntity te, MatrixStack ms, IRenderTypeBuffer buffer, int light){
|
||||||
|
@ -86,7 +84,7 @@ public class SawRenderer extends SafeTileEntityRenderer<SawTileEntity> implement
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void renderShaft(SawTileEntity te, MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay) {
|
protected void renderShaft(SawTileEntity te, MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay) {
|
||||||
KineticTileEntityRenderer.renderRotatingBuffer(te, getRotatedModel(te));
|
//KineticTileEntityRenderer.renderRotatingBuffer(te, getRotatedModel(te));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void renderItems(SawTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer, int light,
|
protected void renderItems(SawTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer, int light,
|
||||||
|
@ -130,11 +128,12 @@ public class SawRenderer extends SafeTileEntityRenderer<SawTileEntity> implement
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected RotatingBuffer getRotatedModel(KineticTileEntity te) {
|
protected InstanceBuffer<RotatingData> getRotatedModel(InstanceContext<SawTileEntity> ctx) {
|
||||||
|
KineticTileEntity te = ctx.te;
|
||||||
BlockState state = te.getBlockState();
|
BlockState state = te.getBlockState();
|
||||||
if (state.get(FACING).getAxis().isHorizontal())
|
if (state.get(FACING).getAxis().isHorizontal())
|
||||||
return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(state.rotate(te.getWorld(), te.getPos(), Rotation.CLOCKWISE_180));
|
return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(ctx, state.rotate(te.getWorld(), te.getPos(), Rotation.CLOCKWISE_180));
|
||||||
return CreateClient.kineticRenderer.renderBlockInstanced(KineticTileEntityRenderer.KINETIC_TILE,
|
return ctx.getKinetics().renderBlockInstanced(KineticTileEntityRenderer.KINETIC_TILE,
|
||||||
getRenderedBlockState(te));
|
getRenderedBlockState(te));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,11 +5,12 @@ import com.simibubi.create.AllBlockPartials;
|
||||||
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
||||||
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
|
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
|
||||||
import com.simibubi.create.foundation.utility.AngleHelper;
|
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||||
import com.simibubi.create.foundation.utility.render.instancing.InstanceBuffer;
|
|
||||||
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
|
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
|
||||||
|
|
||||||
import com.simibubi.create.foundation.utility.render.instancing.RotatingBuffer;
|
import com.simibubi.create.foundation.utility.render.instancing.InstanceBuffer;
|
||||||
|
import com.simibubi.create.foundation.utility.render.instancing.InstanceContext;
|
||||||
import com.simibubi.create.foundation.utility.render.instancing.RotatingData;
|
import com.simibubi.create.foundation.utility.render.instancing.RotatingData;
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||||
import net.minecraft.client.renderer.RenderType;
|
import net.minecraft.client.renderer.RenderType;
|
||||||
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
||||||
|
@ -46,10 +47,9 @@ public class BearingRenderer extends KineticTileEntityRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected RotatingBuffer getRotatedModel(KineticTileEntity te) {
|
protected InstanceBuffer<RotatingData> getRotatedModel(InstanceContext<? extends KineticTileEntity> ctx) {
|
||||||
return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(te.getBlockState(), te.getBlockState()
|
BlockState blockState = ctx.te.getBlockState();
|
||||||
.get(BearingBlock.FACING)
|
return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(ctx, blockState, blockState.get(BearingBlock.FACING).getOpposite());
|
||||||
.getOpposite());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,10 +6,10 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
||||||
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
|
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
|
||||||
import com.simibubi.create.foundation.utility.AngleHelper;
|
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||||
import com.simibubi.create.foundation.utility.MatrixStacker;
|
import com.simibubi.create.foundation.utility.MatrixStacker;
|
||||||
import com.simibubi.create.foundation.utility.render.instancing.InstanceBuffer;
|
|
||||||
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
|
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
|
||||||
|
|
||||||
import com.simibubi.create.foundation.utility.render.instancing.RotatingBuffer;
|
import com.simibubi.create.foundation.utility.render.instancing.InstanceBuffer;
|
||||||
|
import com.simibubi.create.foundation.utility.render.instancing.InstanceContext;
|
||||||
import com.simibubi.create.foundation.utility.render.instancing.RotatingData;
|
import com.simibubi.create.foundation.utility.render.instancing.RotatingData;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||||
|
@ -54,8 +54,8 @@ public class PumpRenderer extends KineticTileEntityRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected RotatingBuffer getRotatedModel(KineticTileEntity te) {
|
protected InstanceBuffer<RotatingData> getRotatedModel(InstanceContext<? extends KineticTileEntity> ctx) {
|
||||||
return AllBlockPartials.MECHANICAL_PUMP_COG.renderOnDirectionalSouthRotating(te.getBlockState());
|
return AllBlockPartials.MECHANICAL_PUMP_COG.renderOnDirectionalSouthRotating(ctx, ctx.te.getBlockState());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,7 @@ import com.simibubi.create.CreateClient;
|
||||||
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
|
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
|
||||||
import com.simibubi.create.foundation.tileEntity.renderer.SmartTileEntityRenderer;
|
import com.simibubi.create.foundation.tileEntity.renderer.SmartTileEntityRenderer;
|
||||||
|
|
||||||
import com.simibubi.create.foundation.utility.render.instancing.IInstancedTileEntityRenderer;
|
import com.simibubi.create.foundation.utility.render.instancing.*;
|
||||||
import com.simibubi.create.foundation.utility.render.instancing.RotatingBuffer;
|
|
||||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||||
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
||||||
|
|
||||||
|
@ -21,15 +20,14 @@ public class SpeedControllerRenderer extends SmartTileEntityRenderer<SpeedContro
|
||||||
IRenderTypeBuffer buffer, int light, int overlay) {
|
IRenderTypeBuffer buffer, int light, int overlay) {
|
||||||
super.renderSafe(tileEntityIn, partialTicks, ms, buffer, light, overlay);
|
super.renderSafe(tileEntityIn, partialTicks, ms, buffer, light, overlay);
|
||||||
|
|
||||||
addInstanceData(tileEntityIn);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addInstanceData(SpeedControllerTileEntity te) {
|
public void addInstanceData(InstanceContext<SpeedControllerTileEntity> ctx) {
|
||||||
KineticTileEntityRenderer.renderRotatingBuffer(te, getRotatedModel(te));
|
KineticTileEntityRenderer.renderRotatingBuffer(ctx, getRotatedModel(ctx.te));
|
||||||
}
|
}
|
||||||
|
|
||||||
private RotatingBuffer getRotatedModel(SpeedControllerTileEntity te) {
|
private InstanceBuffer<RotatingData> getRotatedModel(SpeedControllerTileEntity te) {
|
||||||
return CreateClient.kineticRenderer.renderBlockInstanced(KineticTileEntityRenderer.KINETIC_TILE,
|
return CreateClient.kineticRenderer.renderBlockInstanced(KineticTileEntityRenderer.KINETIC_TILE,
|
||||||
KineticTileEntityRenderer.shaft(KineticTileEntityRenderer.getRotationAxisOf(te)));
|
KineticTileEntityRenderer.shaft(KineticTileEntityRenderer.getRotationAxisOf(te)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package com.simibubi.create.content.contraptions.relays.belt;
|
package com.simibubi.create.content.contraptions.relays.belt;
|
||||||
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||||
import com.simibubi.create.AllBlockPartials;
|
import com.simibubi.create.AllBlockPartials;
|
||||||
|
@ -13,9 +15,9 @@ import com.simibubi.create.foundation.block.render.SpriteShiftEntry;
|
||||||
import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer;
|
import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer;
|
||||||
import com.simibubi.create.foundation.utility.Iterate;
|
import com.simibubi.create.foundation.utility.Iterate;
|
||||||
import com.simibubi.create.foundation.utility.MatrixStacker;
|
import com.simibubi.create.foundation.utility.MatrixStacker;
|
||||||
import com.simibubi.create.foundation.utility.render.instancing.BeltBuffer;
|
import com.simibubi.create.foundation.utility.render.FastContraptionRenderer;
|
||||||
import com.simibubi.create.foundation.utility.render.instancing.IInstancedTileEntityRenderer;
|
import com.simibubi.create.foundation.utility.render.FastKineticRenderer;
|
||||||
import com.simibubi.create.foundation.utility.render.instancing.RotatingBuffer;
|
import com.simibubi.create.foundation.utility.render.instancing.*;
|
||||||
import com.simibubi.create.foundation.utility.render.ShadowRenderHelper;
|
import com.simibubi.create.foundation.utility.render.ShadowRenderHelper;
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
|
@ -51,13 +53,13 @@ public class BeltRenderer extends SafeTileEntityRenderer<BeltTileEntity> impleme
|
||||||
if (!AllBlocks.BELT.has(blockState))
|
if (!AllBlocks.BELT.has(blockState))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
addInstanceData(te);
|
addInstanceData(new InstanceContext.World<>(te));
|
||||||
|
|
||||||
renderItems(te, partialTicks, ms, buffer, light, overlay);
|
renderItems(te, partialTicks, ms, buffer, light, overlay);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addInstanceData(BeltTileEntity te) {
|
public void addInstanceData(InstanceContext<BeltTileEntity> ctx) {
|
||||||
|
BeltTileEntity te = ctx.te;
|
||||||
BlockState blockState = te.getBlockState();
|
BlockState blockState = te.getBlockState();
|
||||||
if (!AllBlocks.BELT.has(blockState))
|
if (!AllBlocks.BELT.has(blockState))
|
||||||
return;
|
return;
|
||||||
|
@ -83,6 +85,8 @@ public class BeltRenderer extends SafeTileEntityRenderer<BeltTileEntity> impleme
|
||||||
end = b;
|
end = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FastKineticRenderer fastKineticRenderer = ctx.getKinetics();
|
||||||
|
|
||||||
for (boolean bottom : Iterate.trueAndFalse) {
|
for (boolean bottom : Iterate.trueAndFalse) {
|
||||||
|
|
||||||
AllBlockPartials beltPartial = diagonal
|
AllBlockPartials beltPartial = diagonal
|
||||||
|
@ -94,7 +98,7 @@ public class BeltRenderer extends SafeTileEntityRenderer<BeltTileEntity> impleme
|
||||||
: start ? AllBlockPartials.BELT_START
|
: start ? AllBlockPartials.BELT_START
|
||||||
: end ? AllBlockPartials.BELT_END : AllBlockPartials.BELT_MIDDLE;
|
: end ? AllBlockPartials.BELT_END : AllBlockPartials.BELT_MIDDLE;
|
||||||
|
|
||||||
BeltBuffer beltBuffer = beltPartial.renderOnBelt(blockState);
|
InstanceBuffer<BeltData> beltBuffer = beltPartial.renderOnBelt(ctx, blockState);
|
||||||
SpriteShiftEntry spriteShift =
|
SpriteShiftEntry spriteShift =
|
||||||
diagonal ? AllSpriteShifts.BELT_DIAGONAL : bottom ? AllSpriteShifts.BELT_OFFSET : AllSpriteShifts.BELT;
|
diagonal ? AllSpriteShifts.BELT_DIAGONAL : bottom ? AllSpriteShifts.BELT_OFFSET : AllSpriteShifts.BELT;
|
||||||
|
|
||||||
|
@ -139,9 +143,9 @@ public class BeltRenderer extends SafeTileEntityRenderer<BeltTileEntity> impleme
|
||||||
msr.rotateX(90);
|
msr.rotateX(90);
|
||||||
msr.unCentre();
|
msr.unCentre();
|
||||||
|
|
||||||
RotatingBuffer rotatingBuffer = CreateClient.kineticRenderer
|
InstanceBuffer<RotatingData> rotatingBuffer = fastKineticRenderer
|
||||||
.renderDirectionalPartialInstanced(AllBlockPartials.BELT_PULLEY, blockState, dir, modelTransform);
|
.renderDirectionalPartialInstanced(AllBlockPartials.BELT_PULLEY, blockState, dir, modelTransform);
|
||||||
KineticTileEntityRenderer.renderRotatingBuffer(te, rotatingBuffer);
|
KineticTileEntityRenderer.renderRotatingBuffer(ctx, rotatingBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,10 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
||||||
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
|
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
|
||||||
import com.simibubi.create.foundation.utility.Iterate;
|
import com.simibubi.create.foundation.utility.Iterate;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.utility.render.instancing.InstanceBuffer;
|
||||||
|
import com.simibubi.create.foundation.utility.render.instancing.InstanceContext;
|
||||||
import com.simibubi.create.foundation.utility.render.instancing.RotatingBuffer;
|
import com.simibubi.create.foundation.utility.render.instancing.RotatingBuffer;
|
||||||
|
import com.simibubi.create.foundation.utility.render.instancing.RotatingData;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||||
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
||||||
|
@ -25,18 +28,26 @@ public class SplitShaftRenderer extends KineticTileEntityRenderer {
|
||||||
@Override
|
@Override
|
||||||
protected void renderSafe(KineticTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer,
|
protected void renderSafe(KineticTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer,
|
||||||
int light, int overlay) {
|
int light, int overlay) {
|
||||||
|
super.renderSafe(te, partialTicks, ms, buffer, light, overlay);
|
||||||
addInstanceData(te);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addInstanceData(KineticTileEntity te) {
|
public void addInstanceData(InstanceContext<KineticTileEntity> ctx) {
|
||||||
|
KineticTileEntity te = ctx.te;
|
||||||
Block block = te.getBlockState().getBlock();
|
Block block = te.getBlockState().getBlock();
|
||||||
final Axis boxAxis = ((IRotate) block).getRotationAxis(te.getBlockState());
|
final Axis boxAxis = ((IRotate) block).getRotationAxis(te.getBlockState());
|
||||||
final BlockPos pos = te.getPos();
|
final BlockPos pos = te.getPos();
|
||||||
|
|
||||||
int blockLight = te.getWorld().getLightLevel(LightType.BLOCK, te.getPos());
|
int blockLight;
|
||||||
int skyLight = te.getWorld().getLightLevel(LightType.SKY, te.getPos());
|
int skyLight;
|
||||||
|
|
||||||
|
if (ctx.checkWorldLight()) {
|
||||||
|
blockLight = te.getWorld().getLightLevel(LightType.BLOCK, te.getPos());
|
||||||
|
skyLight = te.getWorld().getLightLevel(LightType.SKY, te.getPos());
|
||||||
|
} else {
|
||||||
|
blockLight = 0;
|
||||||
|
skyLight = 0;
|
||||||
|
}
|
||||||
|
|
||||||
for (Direction direction : Iterate.directions) {
|
for (Direction direction : Iterate.directions) {
|
||||||
Axis axis = direction.getAxis();
|
Axis axis = direction.getAxis();
|
||||||
|
@ -44,7 +55,7 @@ public class SplitShaftRenderer extends KineticTileEntityRenderer {
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
||||||
RotatingBuffer shaft = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(te.getBlockState(), direction);
|
InstanceBuffer<RotatingData> shaft = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(ctx, te.getBlockState(), direction);
|
||||||
|
|
||||||
shaft.setupInstance(data -> {
|
shaft.setupInstance(data -> {
|
||||||
float speed = te.getSpeed();
|
float speed = te.getSpeed();
|
||||||
|
|
|
@ -6,7 +6,10 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
||||||
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
|
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
|
||||||
import com.simibubi.create.foundation.utility.Iterate;
|
import com.simibubi.create.foundation.utility.Iterate;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.utility.render.instancing.InstanceBuffer;
|
||||||
|
import com.simibubi.create.foundation.utility.render.instancing.InstanceContext;
|
||||||
import com.simibubi.create.foundation.utility.render.instancing.RotatingBuffer;
|
import com.simibubi.create.foundation.utility.render.instancing.RotatingBuffer;
|
||||||
|
import com.simibubi.create.foundation.utility.render.instancing.RotatingData;
|
||||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||||
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
||||||
import net.minecraft.state.properties.BlockStateProperties;
|
import net.minecraft.state.properties.BlockStateProperties;
|
||||||
|
@ -24,18 +27,32 @@ public class GearboxRenderer extends KineticTileEntityRenderer {
|
||||||
@Override
|
@Override
|
||||||
protected void renderSafe(KineticTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer,
|
protected void renderSafe(KineticTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer,
|
||||||
int light, int overlay) {
|
int light, int overlay) {
|
||||||
|
super.renderSafe(te, partialTicks, ms, buffer, light, overlay);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addInstanceData(InstanceContext<KineticTileEntity> ctx) {
|
||||||
|
KineticTileEntity te = ctx.te;
|
||||||
final Axis boxAxis = te.getBlockState().get(BlockStateProperties.AXIS);
|
final Axis boxAxis = te.getBlockState().get(BlockStateProperties.AXIS);
|
||||||
final BlockPos pos = te.getPos();
|
final BlockPos pos = te.getPos();
|
||||||
|
|
||||||
int blockLight = te.getWorld().getLightLevel(LightType.BLOCK, te.getPos());
|
int blockLight;
|
||||||
int skyLight = te.getWorld().getLightLevel(LightType.SKY, te.getPos());
|
int skyLight;
|
||||||
|
|
||||||
|
if (ctx.checkWorldLight()) {
|
||||||
|
blockLight = te.getWorld().getLightLevel(LightType.BLOCK, te.getPos());
|
||||||
|
skyLight = te.getWorld().getLightLevel(LightType.SKY, te.getPos());
|
||||||
|
} else {
|
||||||
|
blockLight = 0;
|
||||||
|
skyLight = 0;
|
||||||
|
}
|
||||||
|
|
||||||
for (Direction direction : Iterate.directions) {
|
for (Direction direction : Iterate.directions) {
|
||||||
final Axis axis = direction.getAxis();
|
final Axis axis = direction.getAxis();
|
||||||
if (boxAxis == axis)
|
if (boxAxis == axis)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
RotatingBuffer shaft = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(te.getBlockState(), direction);
|
InstanceBuffer<RotatingData> shaft = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(ctx, te.getBlockState(), direction);
|
||||||
|
|
||||||
shaft.setupInstance(data -> {
|
shaft.setupInstance(data -> {
|
||||||
float speed = te.getSpeed();
|
float speed = te.getSpeed();
|
||||||
|
@ -58,5 +75,4 @@ public class GearboxRenderer extends KineticTileEntityRenderer {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,9 +8,9 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
|
||||||
import com.simibubi.create.content.logistics.block.mechanicalArm.ArmTileEntity.Phase;
|
import com.simibubi.create.content.logistics.block.mechanicalArm.ArmTileEntity.Phase;
|
||||||
import com.simibubi.create.foundation.utility.*;
|
import com.simibubi.create.foundation.utility.*;
|
||||||
|
|
||||||
import com.simibubi.create.foundation.utility.render.instancing.InstanceBuffer;
|
|
||||||
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
|
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
|
||||||
import com.simibubi.create.foundation.utility.render.instancing.RotatingBuffer;
|
import com.simibubi.create.foundation.utility.render.instancing.InstanceBuffer;
|
||||||
|
import com.simibubi.create.foundation.utility.render.instancing.InstanceContext;
|
||||||
import com.simibubi.create.foundation.utility.render.instancing.RotatingData;
|
import com.simibubi.create.foundation.utility.render.instancing.RotatingData;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
@ -118,8 +118,8 @@ public class ArmRenderer extends KineticTileEntityRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected RotatingBuffer getRotatedModel(KineticTileEntity te) {
|
protected InstanceBuffer<RotatingData> getRotatedModel(InstanceContext<? extends KineticTileEntity> ctx) {
|
||||||
return AllBlockPartials.ARM_COG.renderOnRotating(te.getBlockState());
|
return AllBlockPartials.ARM_COG.renderOnRotating(ctx, ctx.te.getBlockState());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ import com.simibubi.create.foundation.utility.render.RenderWork;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.renderer.ActiveRenderInfo;
|
import net.minecraft.client.renderer.ActiveRenderInfo;
|
||||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||||
|
import net.minecraft.client.renderer.Matrix4f;
|
||||||
import net.minecraft.client.renderer.texture.OverlayTexture;
|
import net.minecraft.client.renderer.texture.OverlayTexture;
|
||||||
import net.minecraft.fluid.Fluid;
|
import net.minecraft.fluid.Fluid;
|
||||||
import net.minecraft.fluid.IFluidState;
|
import net.minecraft.fluid.IFluidState;
|
||||||
|
@ -112,21 +113,25 @@ public class ClientEvents {
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void onLoadWorld(WorldEvent.Load event) {
|
public static void onLoadWorld(WorldEvent.Load event) {
|
||||||
CreateClient.bufferCache.invalidate();
|
CreateClient.invalidateRenderers();
|
||||||
CreateClient.kineticRenderer.invalidate();
|
|
||||||
FastContraptionRenderer.invalidateAll();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void onRenderWorld(RenderWorldLastEvent event) {
|
public static void onRenderWorld(RenderWorldLastEvent event) {
|
||||||
CreateClient.kineticRenderer.renderInstances(event);
|
Matrix4f projection = event.getProjectionMatrix();
|
||||||
FastContraptionRenderer.renderAll(event);
|
// view matrix
|
||||||
|
Vec3d cameraPos = Minecraft.getInstance().gameRenderer.getActiveRenderInfo().getProjectedView();
|
||||||
|
|
||||||
|
Matrix4f view = Matrix4f.translate((float) -cameraPos.x, (float) -cameraPos.y, (float) -cameraPos.z);
|
||||||
|
view.multiplyBackward(event.getMatrixStack().peek().getModel());
|
||||||
|
|
||||||
|
CreateClient.kineticRenderer.renderInstancesAsWorld(projection, view);
|
||||||
|
FastContraptionRenderer.renderAll(projection, view);
|
||||||
|
|
||||||
MatrixStack ms = event.getMatrixStack();
|
MatrixStack ms = event.getMatrixStack();
|
||||||
ActiveRenderInfo info = Minecraft.getInstance().gameRenderer.getActiveRenderInfo();
|
ActiveRenderInfo info = Minecraft.getInstance().gameRenderer.getActiveRenderInfo();
|
||||||
Vec3d view = info.getProjectedView();
|
|
||||||
ms.push();
|
ms.push();
|
||||||
ms.translate(-view.getX(), -view.getY(), -view.getZ());
|
ms.translate(-cameraPos.getX(), -cameraPos.getY(), -cameraPos.getZ());
|
||||||
SuperRenderTypeBuffer buffer = SuperRenderTypeBuffer.getInstance();
|
SuperRenderTypeBuffer buffer = SuperRenderTypeBuffer.getInstance();
|
||||||
|
|
||||||
CouplingRenderer.renderAll(ms, buffer);
|
CouplingRenderer.renderAll(ms, buffer);
|
||||||
|
|
|
@ -18,9 +18,7 @@ public class ResourceReloadHandler extends ReloadListener<Object> {
|
||||||
@Override
|
@Override
|
||||||
protected void apply(Object $, IResourceManager resourceManagerIn, IProfiler profilerIn) {
|
protected void apply(Object $, IResourceManager resourceManagerIn, IProfiler profilerIn) {
|
||||||
SpriteShifter.reloadUVs();
|
SpriteShifter.reloadUVs();
|
||||||
CreateClient.bufferCache.invalidate();
|
CreateClient.invalidateRenderers();
|
||||||
CreateClient.kineticRenderer.invalidate();
|
|
||||||
FastContraptionRenderer.invalidateAll();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,8 +23,6 @@ public class ClearBufferCacheCommand {
|
||||||
|
|
||||||
@OnlyIn(Dist.CLIENT)
|
@OnlyIn(Dist.CLIENT)
|
||||||
private static void execute() {
|
private static void execute() {
|
||||||
CreateClient.bufferCache.invalidate();
|
CreateClient.invalidateRenderers();
|
||||||
CreateClient.kineticRenderer.invalidate();
|
|
||||||
FastContraptionRenderer.invalidateAll();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
package com.simibubi.create.foundation.utility.render;
|
package com.simibubi.create.foundation.utility.render;
|
||||||
|
|
||||||
import com.mojang.blaze3d.platform.GlStateManager;
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
import com.simibubi.create.CreateClient;
|
|
||||||
import com.simibubi.create.foundation.utility.render.instancing.VertexFormat;
|
import com.simibubi.create.foundation.utility.render.instancing.VertexFormat;
|
||||||
import net.minecraft.client.renderer.BufferBuilder;
|
import net.minecraft.client.renderer.BufferBuilder;
|
||||||
import net.minecraft.client.renderer.GLAllocation;
|
import net.minecraft.client.renderer.GLAllocation;
|
||||||
import net.minecraft.client.renderer.WorldRenderer;
|
|
||||||
import net.minecraft.client.renderer.vertex.VertexFormatElement;
|
import net.minecraft.client.renderer.vertex.VertexFormatElement;
|
||||||
import org.lwjgl.opengl.*;
|
import org.lwjgl.opengl.*;
|
||||||
import org.lwjgl.system.MemoryUtil;
|
import org.lwjgl.system.MemoryUtil;
|
||||||
|
@ -43,7 +41,7 @@ public class ContraptionBuffer extends TemplateBuffer {
|
||||||
|
|
||||||
GlStateManager.bindBuffers(GL15.GL_ELEMENT_ARRAY_BUFFER, ebo);
|
GlStateManager.bindBuffers(GL15.GL_ELEMENT_ARRAY_BUFFER, ebo);
|
||||||
|
|
||||||
GL40.glDrawElements(GL11.GL_QUADS, count, GL11.GL_UNSIGNED_SHORT, 0);
|
GL40.glDrawElements(GL11.GL_QUADS, vertexCount, GL11.GL_UNSIGNED_SHORT, 0);
|
||||||
|
|
||||||
for (int i = 0; i <= FORMAT.getNumAttributes(); i++) {
|
for (int i = 0; i <= FORMAT.getNumAttributes(); i++) {
|
||||||
GL40.glDisableVertexAttribArray(i);
|
GL40.glDisableVertexAttribArray(i);
|
||||||
|
@ -55,39 +53,35 @@ public class ContraptionBuffer extends TemplateBuffer {
|
||||||
|
|
||||||
private void setup() {
|
private void setup() {
|
||||||
int stride = FORMAT.getStride();
|
int stride = FORMAT.getStride();
|
||||||
int invariantSize = count * stride;
|
int invariantSize = vertexCount * stride;
|
||||||
|
|
||||||
ByteBuffer constant = GLAllocation.createDirectByteBuffer(invariantSize);
|
GlStateManager.bindBuffers(GL15.GL_ARRAY_BUFFER, 0);
|
||||||
|
GlStateManager.bindBuffers(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
|
// Deselect (bind to 0) the VAO
|
||||||
|
GL30.glBindVertexArray(0);
|
||||||
|
|
||||||
|
try (SafeDirectBuffer constant = new SafeDirectBuffer(invariantSize)) {
|
||||||
constant.order(template.order());
|
constant.order(template.order());
|
||||||
((Buffer) constant).limit(invariantSize);
|
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++) {
|
for (int i = 0; i < vertexCount; i++) {
|
||||||
constant.putFloat(getX(template, i));
|
constant.putFloat(getX(template, i));
|
||||||
constant.putFloat(getY(template, i));
|
constant.putFloat(getY(template, i));
|
||||||
constant.putFloat(getZ(template, i));
|
constant.putFloat(getZ(template, i));
|
||||||
|
|
||||||
constant.putFloat(getNX(template, i));
|
constant.put(getNX(template, i));
|
||||||
constant.putFloat(getNY(template, i));
|
constant.put(getNY(template, i));
|
||||||
constant.putFloat(getNZ(template, i));
|
constant.put(getNZ(template, i));
|
||||||
|
|
||||||
constant.putFloat(getU(template, i));
|
constant.putFloat(getU(template, i));
|
||||||
constant.putFloat(getV(template, i));
|
constant.putFloat(getV(template, i));
|
||||||
|
|
||||||
constant.putFloat(getR(template, i) / 255f);
|
constant.put(getR(template, i));
|
||||||
constant.putFloat(getG(template, i) / 255f);
|
constant.put(getG(template, i));
|
||||||
constant.putFloat(getB(template, i) / 255f);
|
constant.put(getB(template, i));
|
||||||
constant.putFloat(getA(template, i) / 255f);
|
constant.put(getA(template, i));
|
||||||
|
|
||||||
indices.putShort((short) i);
|
|
||||||
}
|
}
|
||||||
constant.rewind();
|
constant.rewind();
|
||||||
indices.rewind();
|
|
||||||
|
|
||||||
vao = GL30.glGenVertexArrays();
|
vao = GL30.glGenVertexArrays();
|
||||||
GL30.glBindVertexArray(vao);
|
GL30.glBindVertexArray(vao);
|
||||||
|
@ -96,14 +90,13 @@ public class ContraptionBuffer extends TemplateBuffer {
|
||||||
vbo = GlStateManager.genBuffers();
|
vbo = GlStateManager.genBuffers();
|
||||||
|
|
||||||
GlStateManager.bindBuffers(GL15.GL_ARRAY_BUFFER, vbo);
|
GlStateManager.bindBuffers(GL15.GL_ARRAY_BUFFER, vbo);
|
||||||
GlStateManager.bufferData(GL15.GL_ARRAY_BUFFER, constant, GL15.GL_STATIC_DRAW);
|
GlStateManager.bufferData(GL15.GL_ARRAY_BUFFER, constant.getBacking(), GL15.GL_STATIC_DRAW);
|
||||||
MemoryUtil.memFree(constant);
|
buildEBO(ebo);
|
||||||
|
|
||||||
GlStateManager.bindBuffers(GL15.GL_ELEMENT_ARRAY_BUFFER, ebo);
|
|
||||||
GlStateManager.bufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indices, GL15.GL_STATIC_DRAW);
|
|
||||||
MemoryUtil.memFree(indices);
|
|
||||||
|
|
||||||
FORMAT.informAttributes(0);
|
FORMAT.informAttributes(0);
|
||||||
|
} catch (Exception e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
GlStateManager.bindBuffers(GL15.GL_ARRAY_BUFFER, 0);
|
GlStateManager.bindBuffers(GL15.GL_ARRAY_BUFFER, 0);
|
||||||
GlStateManager.bindBuffers(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
|
GlStateManager.bindBuffers(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
|
|
|
@ -2,6 +2,7 @@ package com.simibubi.create.foundation.utility.render;
|
||||||
|
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.Contraption;
|
import com.simibubi.create.content.contraptions.components.structureMovement.Contraption;
|
||||||
import net.minecraft.client.renderer.GLAllocation;
|
import net.minecraft.client.renderer.GLAllocation;
|
||||||
|
import net.minecraft.client.renderer.RenderType;
|
||||||
import net.minecraft.util.math.AxisAlignedBB;
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
@ -132,22 +133,19 @@ public class ContraptionLighter {
|
||||||
public void use() {
|
public void use() {
|
||||||
if (texture == 0 || lightVolume == null) return;
|
if (texture == 0 || lightVolume == null) return;
|
||||||
|
|
||||||
GL13.glEnable(GL31.GL_TEXTURE_3D);
|
|
||||||
GL13.glActiveTexture(GL40.GL_TEXTURE0 + 4);
|
|
||||||
GL12.glBindTexture(GL12.GL_TEXTURE_3D, texture);
|
GL12.glBindTexture(GL12.GL_TEXTURE_3D, texture);
|
||||||
|
GL11.glTexParameteri(GL13.GL_TEXTURE_3D, GL13.GL_TEXTURE_MIN_FILTER, GL13.GL_LINEAR);
|
||||||
|
GL11.glTexParameteri(GL13.GL_TEXTURE_3D, GL13.GL_TEXTURE_MAG_FILTER, GL13.GL_LINEAR);
|
||||||
|
GL11.glTexParameteri(GL13.GL_TEXTURE_3D, GL13.GL_TEXTURE_WRAP_S, GL13.GL_CLAMP);
|
||||||
|
GL11.glTexParameteri(GL13.GL_TEXTURE_3D, GL13.GL_TEXTURE_WRAP_R, GL13.GL_CLAMP);
|
||||||
|
GL11.glTexParameteri(GL13.GL_TEXTURE_3D, GL13.GL_TEXTURE_WRAP_T, GL13.GL_CLAMP);
|
||||||
if (dirty) {
|
if (dirty) {
|
||||||
GL12.glTexImage3D(GL12.GL_TEXTURE_3D, 0, GL40.GL_RG8, sizeX, sizeY, sizeZ, 0, GL40.GL_RG, GL40.GL_UNSIGNED_BYTE, lightVolume);
|
GL12.glTexImage3D(GL12.GL_TEXTURE_3D, 0, GL40.GL_RG8, sizeX, sizeY, sizeZ, 0, GL40.GL_RG, GL40.GL_UNSIGNED_BYTE, lightVolume);
|
||||||
dirty = false;
|
dirty = false;
|
||||||
}
|
}
|
||||||
GL40.glTexParameteri(GL13.GL_TEXTURE_3D, GL13.GL_TEXTURE_MIN_FILTER, GL13.GL_LINEAR);
|
|
||||||
GL40.glTexParameteri(GL13.GL_TEXTURE_3D, GL13.GL_TEXTURE_MAG_FILTER, GL13.GL_LINEAR);
|
|
||||||
GL40.glTexParameteri(GL13.GL_TEXTURE_3D, GL13.GL_TEXTURE_WRAP_S, GL13.GL_CLAMP);
|
|
||||||
GL40.glTexParameteri(GL13.GL_TEXTURE_3D, GL13.GL_TEXTURE_WRAP_R, GL13.GL_CLAMP);
|
|
||||||
GL40.glTexParameteri(GL13.GL_TEXTURE_3D, GL13.GL_TEXTURE_WRAP_T, GL13.GL_CLAMP);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void release() {
|
public void release() {
|
||||||
GL13.glActiveTexture(GL40.GL_TEXTURE0 + 4);
|
|
||||||
GL12.glBindTexture(GL12.GL_TEXTURE_3D, 0);
|
GL12.glBindTexture(GL12.GL_TEXTURE_3D, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,23 @@
|
||||||
package com.simibubi.create.foundation.utility.render;
|
package com.simibubi.create.foundation.utility.render;
|
||||||
|
|
||||||
import com.mojang.blaze3d.platform.GlStateManager;
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
import com.simibubi.create.CreateClient;
|
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.Contraption;
|
import com.simibubi.create.content.contraptions.components.structureMovement.Contraption;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionRenderer;
|
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionRenderer;
|
||||||
|
import com.simibubi.create.foundation.utility.render.instancing.IInstanceRendered;
|
||||||
|
import com.simibubi.create.foundation.utility.render.instancing.IInstancedTileEntityRenderer;
|
||||||
import com.simibubi.create.foundation.utility.render.shader.Shader;
|
import com.simibubi.create.foundation.utility.render.shader.Shader;
|
||||||
|
import com.simibubi.create.foundation.utility.render.shader.ShaderCallback;
|
||||||
import com.simibubi.create.foundation.utility.render.shader.ShaderHelper;
|
import com.simibubi.create.foundation.utility.render.shader.ShaderHelper;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.renderer.*;
|
import net.minecraft.client.renderer.*;
|
||||||
|
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
|
||||||
|
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
||||||
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraftforge.client.event.RenderWorldLastEvent;
|
import org.lwjgl.opengl.GL11;
|
||||||
|
import org.lwjgl.opengl.GL13;
|
||||||
|
import org.lwjgl.opengl.GL40;
|
||||||
|
|
||||||
import java.nio.FloatBuffer;
|
import java.nio.FloatBuffer;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -25,6 +32,8 @@ public class FastContraptionRenderer extends ContraptionRenderer {
|
||||||
|
|
||||||
private ContraptionLighter lighter;
|
private ContraptionLighter lighter;
|
||||||
|
|
||||||
|
public final FastKineticRenderer kinetics;
|
||||||
|
|
||||||
private Contraption c;
|
private Contraption c;
|
||||||
|
|
||||||
private Vec3d renderPos;
|
private Vec3d renderPos;
|
||||||
|
@ -33,18 +42,49 @@ public class FastContraptionRenderer extends ContraptionRenderer {
|
||||||
public FastContraptionRenderer(World world, Contraption c) {
|
public FastContraptionRenderer(World world, Contraption c) {
|
||||||
this.c = c;
|
this.c = c;
|
||||||
this.lighter = new ContraptionLighter(c);
|
this.lighter = new ContraptionLighter(c);
|
||||||
|
this.kinetics = new FastKineticRenderer();
|
||||||
|
|
||||||
buildLayers();
|
buildLayers(c);
|
||||||
|
buildInstancedTiles(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buildLayers(Contraption c) {
|
||||||
|
for (ContraptionBuffer buffer : renderLayers) {
|
||||||
|
buffer.delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
renderLayers.clear();
|
||||||
|
|
||||||
|
List<RenderType> blockLayers = RenderType.getBlockLayers();
|
||||||
|
|
||||||
|
for (RenderType layer : blockLayers) {
|
||||||
|
renderLayers.add(buildStructureBuffer(c, layer));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buildInstancedTiles(Contraption c) {
|
||||||
|
List<TileEntity> tileEntities = c.renderedTileEntities;
|
||||||
|
if (!tileEntities.isEmpty()) {
|
||||||
|
for (TileEntity te : tileEntities) {
|
||||||
|
if (te instanceof IInstanceRendered) {
|
||||||
|
TileEntityRenderer<TileEntity> renderer = TileEntityRendererDispatcher.instance.getRenderer(te);
|
||||||
|
|
||||||
|
if (renderer instanceof IInstancedTileEntityRenderer) {
|
||||||
|
kinetics.addInstancedData(this, te, (IInstancedTileEntityRenderer<? super TileEntity>) renderer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
kinetics.markAllDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void tick() {
|
public static void tick() {
|
||||||
if (Minecraft.getInstance().isGamePaused()) return;
|
if (Minecraft.getInstance().isGamePaused()) return;
|
||||||
|
|
||||||
RenderWork.enqueue(() -> {
|
|
||||||
for (FastContraptionRenderer renderer : renderers.values()) {
|
for (FastContraptionRenderer renderer : renderers.values()) {
|
||||||
renderer.lighter.update(renderer.c);
|
renderer.lighter.update(renderer.c);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setRenderSettings(Vec3d position, Vec3d rotation) {
|
private void setRenderSettings(Vec3d position, Vec3d rotation) {
|
||||||
|
@ -52,9 +92,16 @@ public class FastContraptionRenderer extends ContraptionRenderer {
|
||||||
renderRot = rotation;
|
renderRot = rotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void render(int shader) {
|
private void setup(int shader) {
|
||||||
|
setupShaderUniforms(shader);
|
||||||
lighter.use();
|
lighter.use();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void teardown() {
|
||||||
|
lighter.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupShaderUniforms(int shader) {
|
||||||
FloatBuffer buf = ShaderHelper.VEC3_BUFFER;
|
FloatBuffer buf = ShaderHelper.VEC3_BUFFER;
|
||||||
|
|
||||||
int lightBoxSize = GlStateManager.getUniformLocation(shader, "lightBoxSize");
|
int lightBoxSize = GlStateManager.getUniformLocation(shader, "lightBoxSize");
|
||||||
|
@ -84,26 +131,6 @@ public class FastContraptionRenderer extends ContraptionRenderer {
|
||||||
buf.put(2, (float) renderRot.z);
|
buf.put(2, (float) renderRot.z);
|
||||||
buf.rewind();
|
buf.rewind();
|
||||||
GlStateManager.uniform3(cRot, buf);
|
GlStateManager.uniform3(cRot, buf);
|
||||||
|
|
||||||
for (ContraptionBuffer layer : renderLayers) {
|
|
||||||
layer.render();
|
|
||||||
}
|
|
||||||
|
|
||||||
lighter.release();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void buildLayers() {
|
|
||||||
for (ContraptionBuffer buffer : renderLayers) {
|
|
||||||
buffer.delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
renderLayers.clear();
|
|
||||||
|
|
||||||
List<RenderType> blockLayers = RenderType.getBlockLayers();
|
|
||||||
|
|
||||||
for (RenderType layer : blockLayers) {
|
|
||||||
renderLayers.add(buildStructureBuffer(c, layer));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void invalidate() {
|
private void invalidate() {
|
||||||
|
@ -113,6 +140,8 @@ public class FastContraptionRenderer extends ContraptionRenderer {
|
||||||
|
|
||||||
lighter.delete();
|
lighter.delete();
|
||||||
|
|
||||||
|
kinetics.invalidate();
|
||||||
|
|
||||||
renderLayers.clear();
|
renderLayers.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,26 +162,56 @@ public class FastContraptionRenderer extends ContraptionRenderer {
|
||||||
return renderer;
|
return renderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void renderAll(RenderWorldLastEvent event) {
|
public static void renderAll(Matrix4f projectionMat, Matrix4f viewMat) {
|
||||||
|
removeDeadContraptions();
|
||||||
|
|
||||||
|
if (renderers.isEmpty()) return;
|
||||||
|
|
||||||
GameRenderer gameRenderer = Minecraft.getInstance().gameRenderer;
|
GameRenderer gameRenderer = Minecraft.getInstance().gameRenderer;
|
||||||
CreateClient.kineticRenderer.setup(gameRenderer);
|
FastKineticRenderer.setup(gameRenderer);
|
||||||
GlStateManager.enableCull();
|
GL11.glEnable(GL13.GL_TEXTURE_3D);
|
||||||
|
GL13.glActiveTexture(GL40.GL_TEXTURE4);
|
||||||
|
|
||||||
ShaderHelper.useShader(Shader.CONTRAPTION_STRUCTURE, ShaderHelper.getViewProjectionCallback(event));
|
ShaderCallback callback = ShaderHelper.getViewProjectionCallback(projectionMat, viewMat);
|
||||||
int shader = ShaderHelper.getShaderHandle(Shader.CONTRAPTION_STRUCTURE);
|
|
||||||
|
|
||||||
ArrayList<Integer> toRemove = new ArrayList<>();
|
|
||||||
|
|
||||||
|
int structureShader = ShaderHelper.useShader(Shader.CONTRAPTION_STRUCTURE, callback);
|
||||||
for (FastContraptionRenderer renderer : renderers.values()) {
|
for (FastContraptionRenderer renderer : renderers.values()) {
|
||||||
if (renderer.c.entity.isAlive())
|
renderer.setup(structureShader);
|
||||||
renderer.render(shader);
|
for (ContraptionBuffer layer : renderer.renderLayers) {
|
||||||
else
|
layer.render();
|
||||||
toRemove.add(renderer.c.entity.getEntityId());
|
}
|
||||||
|
renderer.teardown();
|
||||||
|
}
|
||||||
|
|
||||||
|
int rotatingShader = ShaderHelper.useShader(Shader.CONTRAPTION_ROTATING, callback);
|
||||||
|
for (FastContraptionRenderer renderer : renderers.values()) {
|
||||||
|
renderer.setup(rotatingShader);
|
||||||
|
renderer.kinetics.renderRotating();
|
||||||
|
renderer.teardown();
|
||||||
|
}
|
||||||
|
|
||||||
|
int beltShader = ShaderHelper.useShader(Shader.CONTRAPTION_BELT, callback);
|
||||||
|
for (FastContraptionRenderer renderer : renderers.values()) {
|
||||||
|
renderer.setup(beltShader);
|
||||||
|
renderer.kinetics.renderBelts();
|
||||||
|
renderer.teardown();
|
||||||
}
|
}
|
||||||
|
|
||||||
ShaderHelper.releaseShader();
|
ShaderHelper.releaseShader();
|
||||||
|
|
||||||
CreateClient.kineticRenderer.teardown();
|
GL11.glDisable(GL13.GL_TEXTURE_3D);
|
||||||
|
FastKineticRenderer.teardown();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void removeDeadContraptions() {
|
||||||
|
ArrayList<Integer> toRemove = new ArrayList<>();
|
||||||
|
|
||||||
|
for (FastContraptionRenderer renderer : renderers.values()) {
|
||||||
|
if (!renderer.c.entity.isAlive()) {
|
||||||
|
toRemove.add(renderer.c.entity.getEntityId());
|
||||||
|
renderer.invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (Integer id : toRemove) {
|
for (Integer id : toRemove) {
|
||||||
renderers.remove(id);
|
renderers.remove(id);
|
||||||
|
|
|
@ -3,9 +3,9 @@ package com.simibubi.create.foundation.utility.render;
|
||||||
import com.google.common.cache.Cache;
|
import com.google.common.cache.Cache;
|
||||||
import com.google.common.cache.CacheBuilder;
|
import com.google.common.cache.CacheBuilder;
|
||||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||||
import com.mojang.blaze3d.platform.GlStateManager;
|
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
import com.simibubi.create.AllBlockPartials;
|
import com.simibubi.create.AllBlockPartials;
|
||||||
|
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
|
||||||
import com.simibubi.create.foundation.utility.render.instancing.*;
|
import com.simibubi.create.foundation.utility.render.instancing.*;
|
||||||
import com.simibubi.create.foundation.utility.render.shader.Shader;
|
import com.simibubi.create.foundation.utility.render.shader.Shader;
|
||||||
import com.simibubi.create.foundation.utility.render.shader.ShaderCallback;
|
import com.simibubi.create.foundation.utility.render.shader.ShaderCallback;
|
||||||
|
@ -21,7 +21,6 @@ import net.minecraft.inventory.container.PlayerContainer;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraftforge.client.event.RenderWorldLastEvent;
|
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
import org.lwjgl.opengl.GL11;
|
import org.lwjgl.opengl.GL11;
|
||||||
import org.lwjgl.opengl.GL13;
|
import org.lwjgl.opengl.GL13;
|
||||||
|
@ -35,8 +34,8 @@ import java.util.function.Supplier;
|
||||||
import static com.simibubi.create.foundation.utility.render.SuperByteBufferCache.PARTIAL;
|
import static com.simibubi.create.foundation.utility.render.SuperByteBufferCache.PARTIAL;
|
||||||
|
|
||||||
public class FastKineticRenderer {
|
public class FastKineticRenderer {
|
||||||
Map<SuperByteBufferCache.Compartment<?>, Cache<Object, RotatingBuffer>> rotating;
|
Map<SuperByteBufferCache.Compartment<?>, Cache<Object, InstanceBuffer<RotatingData>>> rotating;
|
||||||
Map<SuperByteBufferCache.Compartment<?>, Cache<Object, BeltBuffer>> belts;
|
Map<SuperByteBufferCache.Compartment<?>, Cache<Object, InstanceBuffer<BeltData>>> belts;
|
||||||
|
|
||||||
boolean rebuild;
|
boolean rebuild;
|
||||||
|
|
||||||
|
@ -46,6 +45,7 @@ public class FastKineticRenderer {
|
||||||
registerCompartment(SuperByteBufferCache.GENERIC_TILE);
|
registerCompartment(SuperByteBufferCache.GENERIC_TILE);
|
||||||
registerCompartment(SuperByteBufferCache.PARTIAL);
|
registerCompartment(SuperByteBufferCache.PARTIAL);
|
||||||
registerCompartment(SuperByteBufferCache.DIRECTIONAL_PARTIAL);
|
registerCompartment(SuperByteBufferCache.DIRECTIONAL_PARTIAL);
|
||||||
|
registerCompartment(KineticTileEntityRenderer.KINETIC_TILE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void buildTileEntityBuffers(World world) {
|
public void buildTileEntityBuffers(World world) {
|
||||||
|
@ -65,66 +65,102 @@ public class FastKineticRenderer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T extends TileEntity> void addInstancedData(T te, IInstancedTileEntityRenderer<T> renderer) {
|
<T extends TileEntity> void addInstancedData(T te, IInstancedTileEntityRenderer<T> renderer) {
|
||||||
renderer.addInstanceData(te);
|
renderer.addInstanceData(new InstanceContext.World<>(te));
|
||||||
|
}
|
||||||
|
|
||||||
|
<T extends TileEntity> void addInstancedData(FastContraptionRenderer c, T te, IInstancedTileEntityRenderer<T> renderer) {
|
||||||
|
renderer.addInstanceData(new InstanceContext.Contraption<>(te, c));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function should be called after building instances.
|
||||||
|
* It must be called either on the render thread before committing to rendering, or in a place where there are
|
||||||
|
* guaranteed to be no race conditions with the render thread, i.e. when constructing a FastContraptionRenderer.
|
||||||
|
*/
|
||||||
|
public void markAllDirty() {
|
||||||
|
for (Cache<Object, InstanceBuffer<RotatingData>> cache : rotating.values()) {
|
||||||
|
for (InstanceBuffer<RotatingData> renderer : cache.asMap().values()) {
|
||||||
|
renderer.markDirty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Cache<Object, InstanceBuffer<BeltData>> cache : belts.values()) {
|
||||||
|
for (InstanceBuffer<BeltData> renderer : cache.asMap().values()) {
|
||||||
|
renderer.markDirty();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void tick() {
|
public void tick() {
|
||||||
// TODO: (later) detect changes in lighting with a mixin (or forge hook) to ClientChunkProvider.markLightChanged()
|
// TODO: (later) detect changes in lighting with a mixin (or forge hook) to ClientChunkProvider.markLightChanged()
|
||||||
for (Cache<Object, RotatingBuffer> cache : rotating.values()) {
|
for (Cache<Object, InstanceBuffer<RotatingData>> cache : rotating.values()) {
|
||||||
for (RotatingBuffer renderer : cache.asMap().values()) {
|
for (InstanceBuffer<RotatingData> renderer : cache.asMap().values()) {
|
||||||
renderer.clearInstanceData();
|
renderer.clearInstanceData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Cache<Object, BeltBuffer> cache : belts.values()) {
|
for (Cache<Object, InstanceBuffer<BeltData>> cache : belts.values()) {
|
||||||
for (BeltBuffer renderer : cache.asMap().values()) {
|
for (InstanceBuffer<BeltData> renderer : cache.asMap().values()) {
|
||||||
renderer.clearInstanceData();
|
renderer.clearInstanceData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// rebuild = true;
|
//buildTileEntityBuffers(Minecraft.getInstance().world);
|
||||||
|
|
||||||
|
rebuild = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void renderInstances(RenderWorldLastEvent event) {
|
void renderBelts() {
|
||||||
|
for (Cache<Object, InstanceBuffer<BeltData>> cache : belts.values()) {
|
||||||
|
for (InstanceBuffer<BeltData> type : cache.asMap().values()) {
|
||||||
|
if (!type.isEmpty()) {
|
||||||
|
type.render();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void renderRotating() {
|
||||||
|
for (Cache<Object, InstanceBuffer<RotatingData>> cache : rotating.values()) {
|
||||||
|
for (InstanceBuffer<RotatingData> rotatingDataInstanceBuffer : cache.asMap().values()) {
|
||||||
|
if (!rotatingDataInstanceBuffer.isEmpty()) {
|
||||||
|
rotatingDataInstanceBuffer.render();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void renderInstancesAsWorld(Matrix4f projection, Matrix4f view) {
|
||||||
GameRenderer gameRenderer = Minecraft.getInstance().gameRenderer;
|
GameRenderer gameRenderer = Minecraft.getInstance().gameRenderer;
|
||||||
//
|
|
||||||
// if (rebuild) {
|
if (rebuild) {
|
||||||
// buildTileEntityBuffers(Minecraft.getInstance().world);
|
markAllDirty();
|
||||||
// rebuild = false;
|
rebuild = false;
|
||||||
// }
|
}
|
||||||
|
|
||||||
setup(gameRenderer);
|
setup(gameRenderer);
|
||||||
|
|
||||||
ShaderCallback callback = ShaderHelper.getViewProjectionCallback(event);
|
ShaderCallback callback = ShaderHelper.getViewProjectionCallback(projection, view);
|
||||||
|
|
||||||
ShaderHelper.useShader(Shader.ROTATING_INSTANCED, callback);
|
ShaderHelper.useShader(Shader.ROTATING, callback);
|
||||||
|
renderRotating();
|
||||||
|
|
||||||
rotating.values()
|
ShaderHelper.useShader(Shader.BELT, callback);
|
||||||
.stream()
|
renderBelts();
|
||||||
.flatMap(cache -> cache.asMap().values().stream())
|
|
||||||
.filter(type -> !type.isEmpty())
|
|
||||||
.forEach(InstanceBuffer::render);
|
|
||||||
|
|
||||||
ShaderHelper.useShader(Shader.BELT_INSTANCED, callback);
|
|
||||||
|
|
||||||
belts.values()
|
|
||||||
.stream()
|
|
||||||
.flatMap(cache -> cache.asMap().values().stream())
|
|
||||||
.filter(type -> !type.isEmpty())
|
|
||||||
.forEach(InstanceBuffer::render);
|
|
||||||
|
|
||||||
ShaderHelper.releaseShader();
|
ShaderHelper.releaseShader();
|
||||||
|
|
||||||
teardown();
|
teardown();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setup(GameRenderer gameRenderer) {
|
public static void setup(GameRenderer gameRenderer) {
|
||||||
RenderSystem.enableBlend();
|
RenderSystem.enableBlend();
|
||||||
RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA);
|
RenderSystem.defaultBlendFunc();
|
||||||
|
|
||||||
RenderSystem.enableLighting();
|
RenderSystem.enableLighting();
|
||||||
RenderSystem.enableDepthTest();
|
RenderSystem.enableDepthTest();
|
||||||
|
RenderSystem.enableCull();
|
||||||
GL11.glCullFace(GL11.GL_BACK);
|
GL11.glCullFace(GL11.GL_BACK);
|
||||||
|
|
||||||
LightTexture lightManager = gameRenderer.getLightmapTextureManager();
|
LightTexture lightManager = gameRenderer.getLightmapTextureManager();
|
||||||
|
@ -149,9 +185,9 @@ public class FastKineticRenderer {
|
||||||
RenderSystem.enableTexture();
|
RenderSystem.enableTexture();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void teardown() {
|
public static void teardown() {
|
||||||
|
|
||||||
GL13.glActiveTexture(GL40.GL_TEXTURE0 + 1);
|
GL13.glActiveTexture(GL40.GL_TEXTURE1);
|
||||||
GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
|
GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
GL13.glActiveTexture(GL40.GL_TEXTURE0);
|
GL13.glActiveTexture(GL40.GL_TEXTURE0);
|
||||||
|
@ -175,26 +211,26 @@ public class FastKineticRenderer {
|
||||||
belts.put(instance, CacheBuilder.newBuilder().expireAfterAccess(ticksUntilExpired * 50, TimeUnit.MILLISECONDS).build());
|
belts.put(instance, CacheBuilder.newBuilder().expireAfterAccess(ticksUntilExpired * 50, TimeUnit.MILLISECONDS).build());
|
||||||
}
|
}
|
||||||
|
|
||||||
public RotatingBuffer renderPartialRotating(AllBlockPartials partial, BlockState referenceState) {
|
public InstanceBuffer<RotatingData> renderPartialRotating(AllBlockPartials partial, BlockState referenceState) {
|
||||||
return getRotating(PARTIAL, partial, () -> rotatingInstancedRenderer(partial.get(), referenceState));
|
return getRotating(PARTIAL, partial, () -> rotatingInstancedRenderer(partial.get(), referenceState));
|
||||||
}
|
}
|
||||||
|
|
||||||
public BeltBuffer renderPartialBelt(AllBlockPartials partial, BlockState referenceState) {
|
public InstanceBuffer<BeltData> renderPartialBelt(AllBlockPartials partial, BlockState referenceState) {
|
||||||
return getBelt(PARTIAL, partial, () -> beltInstancedRenderer(partial.get(), referenceState));
|
return getBelt(PARTIAL, partial, () -> beltInstancedRenderer(partial.get(), referenceState));
|
||||||
}
|
}
|
||||||
|
|
||||||
public RotatingBuffer renderDirectionalPartialInstanced(AllBlockPartials partial, BlockState referenceState, Direction dir,
|
public InstanceBuffer<RotatingData> renderDirectionalPartialInstanced(AllBlockPartials partial, BlockState referenceState, Direction dir,
|
||||||
MatrixStack modelTransform) {
|
MatrixStack modelTransform) {
|
||||||
return getRotating(SuperByteBufferCache.DIRECTIONAL_PARTIAL, Pair.of(dir, partial),
|
return getRotating(SuperByteBufferCache.DIRECTIONAL_PARTIAL, Pair.of(dir, partial),
|
||||||
() -> rotatingInstancedRenderer(partial.get(), referenceState, modelTransform));
|
() -> rotatingInstancedRenderer(partial.get(), referenceState, modelTransform));
|
||||||
}
|
}
|
||||||
|
|
||||||
public RotatingBuffer renderBlockInstanced(SuperByteBufferCache.Compartment<BlockState> compartment, BlockState toRender) {
|
public InstanceBuffer<RotatingData> renderBlockInstanced(SuperByteBufferCache.Compartment<BlockState> compartment, BlockState toRender) {
|
||||||
return getRotating(compartment, toRender, () -> rotatingInstancedRenderer(toRender));
|
return getRotating(compartment, toRender, () -> rotatingInstancedRenderer(toRender));
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> RotatingBuffer getRotating(SuperByteBufferCache.Compartment<T> compartment, T key, Supplier<RotatingBuffer> supplier) {
|
public <T> InstanceBuffer<RotatingData> getRotating(SuperByteBufferCache.Compartment<T> compartment, T key, Supplier<InstanceBuffer<RotatingData>> supplier) {
|
||||||
Cache<Object, RotatingBuffer> compartmentCache = this.rotating.get(compartment);
|
Cache<Object, InstanceBuffer<RotatingData>> compartmentCache = this.rotating.get(compartment);
|
||||||
try {
|
try {
|
||||||
return compartmentCache.get(key, supplier::get);
|
return compartmentCache.get(key, supplier::get);
|
||||||
} catch (ExecutionException e) {
|
} catch (ExecutionException e) {
|
||||||
|
@ -203,8 +239,8 @@ public class FastKineticRenderer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> BeltBuffer getBelt(SuperByteBufferCache.Compartment<T> compartment, T key, Supplier<BeltBuffer> supplier) {
|
public <T> InstanceBuffer<BeltData> getBelt(SuperByteBufferCache.Compartment<T> compartment, T key, Supplier<InstanceBuffer<BeltData>> supplier) {
|
||||||
Cache<Object, BeltBuffer> compartmentCache = this.belts.get(compartment);
|
Cache<Object, InstanceBuffer<BeltData>> compartmentCache = this.belts.get(compartment);
|
||||||
try {
|
try {
|
||||||
return compartmentCache.get(key, supplier::get);
|
return compartmentCache.get(key, supplier::get);
|
||||||
} catch (ExecutionException e) {
|
} catch (ExecutionException e) {
|
||||||
|
@ -214,40 +250,40 @@ public class FastKineticRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private RotatingBuffer rotatingInstancedRenderer(BlockState renderedState) {
|
private InstanceBuffer<RotatingData> rotatingInstancedRenderer(BlockState renderedState) {
|
||||||
BlockRendererDispatcher dispatcher = Minecraft.getInstance().getBlockRendererDispatcher();
|
BlockRendererDispatcher dispatcher = Minecraft.getInstance().getBlockRendererDispatcher();
|
||||||
return rotatingInstancedRenderer(dispatcher.getModelForState(renderedState), renderedState);
|
return rotatingInstancedRenderer(dispatcher.getModelForState(renderedState), renderedState);
|
||||||
}
|
}
|
||||||
|
|
||||||
private RotatingBuffer rotatingInstancedRenderer(IBakedModel model, BlockState renderedState) {
|
private InstanceBuffer<RotatingData> rotatingInstancedRenderer(IBakedModel model, BlockState renderedState) {
|
||||||
return rotatingInstancedRenderer(model, renderedState, new MatrixStack());
|
return rotatingInstancedRenderer(model, renderedState, new MatrixStack());
|
||||||
}
|
}
|
||||||
|
|
||||||
private BeltBuffer beltInstancedRenderer(IBakedModel model, BlockState renderedState) {
|
private InstanceBuffer<BeltData> beltInstancedRenderer(IBakedModel model, BlockState renderedState) {
|
||||||
return beltInstancedRenderer(model, renderedState, new MatrixStack());
|
return beltInstancedRenderer(model, renderedState, new MatrixStack());
|
||||||
}
|
}
|
||||||
|
|
||||||
private RotatingBuffer rotatingInstancedRenderer(IBakedModel model, BlockState referenceState, MatrixStack ms) {
|
private InstanceBuffer<RotatingData> rotatingInstancedRenderer(IBakedModel model, BlockState referenceState, MatrixStack ms) {
|
||||||
BufferBuilder builder = SuperByteBufferCache.getBufferBuilder(model, referenceState, ms);
|
BufferBuilder builder = SuperByteBufferCache.getBufferBuilder(model, referenceState, ms);
|
||||||
|
|
||||||
return new RotatingBuffer(builder);
|
return new RotatingBuffer(builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
private BeltBuffer beltInstancedRenderer(IBakedModel model, BlockState referenceState, MatrixStack ms) {
|
private InstanceBuffer<BeltData> beltInstancedRenderer(IBakedModel model, BlockState referenceState, MatrixStack ms) {
|
||||||
BufferBuilder builder = SuperByteBufferCache.getBufferBuilder(model, referenceState, ms);
|
BufferBuilder builder = SuperByteBufferCache.getBufferBuilder(model, referenceState, ms);
|
||||||
|
|
||||||
return new BeltBuffer(builder);
|
return new BeltBuffer(builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void invalidate() {
|
public void invalidate() {
|
||||||
rotating.values().forEach(cache -> {
|
for (Cache<Object, InstanceBuffer<RotatingData>> objectInstanceBufferCache : rotating.values()) {
|
||||||
cache.asMap().values().forEach(InstanceBuffer::delete);
|
objectInstanceBufferCache.asMap().values().forEach(InstanceBuffer::delete);
|
||||||
cache.invalidateAll();
|
objectInstanceBufferCache.invalidateAll();
|
||||||
});
|
}
|
||||||
|
|
||||||
belts.values().forEach(cache -> {
|
for (Cache<Object, InstanceBuffer<BeltData>> cache : belts.values()) {
|
||||||
cache.asMap().values().forEach(InstanceBuffer::delete);
|
cache.asMap().values().forEach(InstanceBuffer::delete);
|
||||||
cache.invalidateAll();
|
cache.invalidateAll();
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,172 @@
|
||||||
|
package com.simibubi.create.foundation.utility.render;
|
||||||
|
|
||||||
|
import net.minecraft.client.renderer.GLAllocation;
|
||||||
|
import org.lwjgl.system.MemoryStack;
|
||||||
|
import org.lwjgl.system.MemoryUtil;
|
||||||
|
import sun.misc.Cleaner;
|
||||||
|
import sun.nio.ch.DirectBuffer;
|
||||||
|
|
||||||
|
import java.nio.*;
|
||||||
|
|
||||||
|
public class SafeDirectBuffer implements AutoCloseable {
|
||||||
|
|
||||||
|
private ByteBuffer wrapped;
|
||||||
|
|
||||||
|
public SafeDirectBuffer(int capacity) {
|
||||||
|
this.wrapped = GLAllocation.createDirectByteBuffer(capacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() throws Exception {
|
||||||
|
if (wrapped instanceof DirectBuffer) {
|
||||||
|
Cleaner cleaner = ((DirectBuffer) wrapped).cleaner();
|
||||||
|
if (!cleaner.isEnqueued()) {
|
||||||
|
cleaner.clean();
|
||||||
|
cleaner.enqueue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Only use this function to pass information to OpenGL.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public ByteBuffer getBacking() {
|
||||||
|
return wrapped;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void order(ByteOrder bo) {
|
||||||
|
wrapped.order(bo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void limit(int limit) {
|
||||||
|
wrapped.limit(limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void rewind() {
|
||||||
|
wrapped.rewind();
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte get() {
|
||||||
|
return wrapped.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteBuffer put(byte b) {
|
||||||
|
return wrapped.put(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte get(int index) {
|
||||||
|
return wrapped.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteBuffer put(int index, byte b) {
|
||||||
|
return wrapped.put(index, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteBuffer compact() {
|
||||||
|
return wrapped.compact();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isReadOnly() {
|
||||||
|
return wrapped.isReadOnly();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDirect() {
|
||||||
|
return wrapped.isDirect();
|
||||||
|
}
|
||||||
|
|
||||||
|
public char getChar() {
|
||||||
|
return wrapped.getChar();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteBuffer putChar(char value) {
|
||||||
|
return wrapped.putChar(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public char getChar(int index) {
|
||||||
|
return wrapped.getChar(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteBuffer putChar(int index, char value) {
|
||||||
|
return wrapped.putChar(index, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public short getShort() {
|
||||||
|
return wrapped.getShort();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteBuffer putShort(short value) {
|
||||||
|
return wrapped.putShort(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public short getShort(int index) {
|
||||||
|
return wrapped.getShort(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteBuffer putShort(int index, short value) {
|
||||||
|
return wrapped.putShort(index, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getInt() {
|
||||||
|
return wrapped.getInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteBuffer putInt(int value) {
|
||||||
|
return wrapped.putInt(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getInt(int index) {
|
||||||
|
return wrapped.getInt(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteBuffer putInt(int index, int value) {
|
||||||
|
return wrapped.putInt(index, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getLong() {
|
||||||
|
return wrapped.getLong();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteBuffer putLong(long value) {
|
||||||
|
return wrapped.putLong(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getLong(int index) {
|
||||||
|
return wrapped.getLong(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteBuffer putLong(int index, long value) {
|
||||||
|
return wrapped.putLong(index, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getFloat() {
|
||||||
|
return wrapped.getFloat();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteBuffer putFloat(float value) {
|
||||||
|
return wrapped.putFloat(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getFloat(int index) {
|
||||||
|
return wrapped.getFloat(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteBuffer putFloat(int index, float value) {
|
||||||
|
return wrapped.putFloat(index, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getDouble() {
|
||||||
|
return wrapped.getDouble();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteBuffer putDouble(double value) {
|
||||||
|
return wrapped.putDouble(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getDouble(int index) {
|
||||||
|
return wrapped.getDouble(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteBuffer putDouble(int index, double value) {
|
||||||
|
return wrapped.putDouble(index, value);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,8 +1,10 @@
|
||||||
package com.simibubi.create.foundation.utility.render;
|
package com.simibubi.create.foundation.utility.render;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
import com.mojang.datafixers.util.Pair;
|
import com.mojang.datafixers.util.Pair;
|
||||||
import net.minecraft.client.renderer.BufferBuilder;
|
import net.minecraft.client.renderer.BufferBuilder;
|
||||||
import net.minecraft.client.renderer.GLAllocation;
|
import net.minecraft.client.renderer.vertex.VertexFormatElement;
|
||||||
|
import org.lwjgl.opengl.GL15;
|
||||||
|
|
||||||
import java.nio.Buffer;
|
import java.nio.Buffer;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
@ -11,7 +13,7 @@ import java.nio.ByteOrder;
|
||||||
public class TemplateBuffer {
|
public class TemplateBuffer {
|
||||||
protected ByteBuffer template;
|
protected ByteBuffer template;
|
||||||
protected int formatSize;
|
protected int formatSize;
|
||||||
protected int count;
|
protected int vertexCount;
|
||||||
|
|
||||||
public TemplateBuffer(BufferBuilder buf) {
|
public TemplateBuffer(BufferBuilder buf) {
|
||||||
Pair<BufferBuilder.DrawState, ByteBuffer> state = buf.popData();
|
Pair<BufferBuilder.DrawState, ByteBuffer> state = buf.popData();
|
||||||
|
@ -20,8 +22,8 @@ public class TemplateBuffer {
|
||||||
|
|
||||||
formatSize = buf.getVertexFormat()
|
formatSize = buf.getVertexFormat()
|
||||||
.getSize();
|
.getSize();
|
||||||
count = state.getFirst().getCount();
|
vertexCount = state.getFirst().getCount();
|
||||||
int size = count * formatSize;
|
int size = vertexCount * formatSize;
|
||||||
|
|
||||||
template = ByteBuffer.allocate(size);
|
template = ByteBuffer.allocate(size);
|
||||||
template.order(rendered.order());
|
template.order(rendered.order());
|
||||||
|
@ -30,6 +32,22 @@ public class TemplateBuffer {
|
||||||
((Buffer)template).rewind();
|
((Buffer)template).rewind();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void buildEBO(int ebo) throws Exception {
|
||||||
|
int indicesSize = vertexCount * VertexFormatElement.Type.USHORT.getSize();
|
||||||
|
try (SafeDirectBuffer indices = new SafeDirectBuffer(indicesSize)) {
|
||||||
|
indices.order(template.order());
|
||||||
|
indices.limit(indicesSize);
|
||||||
|
|
||||||
|
for (int i = 0; i < vertexCount; i++) {
|
||||||
|
indices.putShort((short) i);
|
||||||
|
}
|
||||||
|
indices.rewind();
|
||||||
|
|
||||||
|
GlStateManager.bindBuffers(GL15.GL_ELEMENT_ARRAY_BUFFER, ebo);
|
||||||
|
GlStateManager.bufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indices.getBacking(), GL15.GL_STATIC_DRAW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
return ((Buffer) template).limit() == 0;
|
return ((Buffer) template).limit() == 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import com.simibubi.create.Create;
|
||||||
import com.simibubi.create.foundation.config.AllConfigs;
|
import com.simibubi.create.foundation.config.AllConfigs;
|
||||||
|
|
||||||
import com.simibubi.create.foundation.utility.MatrixStacker;
|
import com.simibubi.create.foundation.utility.MatrixStacker;
|
||||||
|
import com.simibubi.create.foundation.utility.render.instancing.IInstanceRendered;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||||
import net.minecraft.client.renderer.Matrix4f;
|
import net.minecraft.client.renderer.Matrix4f;
|
||||||
|
@ -30,6 +31,8 @@ public class TileEntityRenderHelper {
|
||||||
|
|
||||||
for (Iterator<TileEntity> iterator = customRenderTEs.iterator(); iterator.hasNext();) {
|
for (Iterator<TileEntity> iterator = customRenderTEs.iterator(); iterator.hasNext();) {
|
||||||
TileEntity tileEntity = iterator.next();
|
TileEntity tileEntity = iterator.next();
|
||||||
|
if (tileEntity instanceof IInstanceRendered) continue; // TODO: some things still need to render
|
||||||
|
|
||||||
TileEntityRenderer<TileEntity> renderer = TileEntityRendererDispatcher.instance.getRenderer(tileEntity);
|
TileEntityRenderer<TileEntity> renderer = TileEntityRendererDispatcher.instance.getRenderer(tileEntity);
|
||||||
if (renderer == null) {
|
if (renderer == null) {
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
package com.simibubi.create.foundation.utility.render.instancing;
|
package com.simibubi.create.foundation.utility.render.instancing;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.utility.render.SafeDirectBuffer;
|
||||||
import net.minecraft.client.renderer.Vector3f;
|
import net.minecraft.client.renderer.Vector3f;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
|
|
||||||
public class BasicData<D extends BasicData<D>> extends InstanceData {
|
public class BasicData<D extends BasicData<D>> extends InstanceData {
|
||||||
|
|
||||||
private float x;
|
private float x;
|
||||||
|
@ -38,7 +37,7 @@ public class BasicData<D extends BasicData<D>> extends InstanceData {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(ByteBuffer buf) {
|
public void write(SafeDirectBuffer buf) {
|
||||||
putVec3(buf, x, y, z);
|
putVec3(buf, x, y, z);
|
||||||
|
|
||||||
putVec2(buf, blockLight, skyLight);
|
putVec2(buf, blockLight, skyLight);
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
package com.simibubi.create.foundation.utility.render.instancing;
|
package com.simibubi.create.foundation.utility.render.instancing;
|
||||||
|
|
||||||
import com.simibubi.create.foundation.block.render.SpriteShiftEntry;
|
import com.simibubi.create.foundation.block.render.SpriteShiftEntry;
|
||||||
|
import com.simibubi.create.foundation.utility.render.SafeDirectBuffer;
|
||||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
|
|
||||||
import static com.simibubi.create.foundation.utility.render.instancing.VertexAttribute.*;
|
import static com.simibubi.create.foundation.utility.render.instancing.VertexAttribute.*;
|
||||||
|
|
||||||
|
@ -55,7 +53,7 @@ public class BeltData extends BasicData<BeltData> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(ByteBuffer buf) {
|
public void write(SafeDirectBuffer buf) {
|
||||||
super.write(buf);
|
super.write(buf);
|
||||||
|
|
||||||
putVec3(buf, rotX, rotY, rotZ);
|
putVec3(buf, rotX, rotY, rotZ);
|
||||||
|
|
|
@ -1,13 +1,19 @@
|
||||||
package com.simibubi.create.foundation.utility.render.instancing;
|
package com.simibubi.create.foundation.utility.render.instancing;
|
||||||
|
|
||||||
|
import com.simibubi.create.AllBlockPartials;
|
||||||
|
import com.simibubi.create.content.contraptions.components.structureMovement.Contraption;
|
||||||
import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer;
|
import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer;
|
||||||
|
import com.simibubi.create.foundation.utility.render.FastContraptionRenderer;
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
|
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
|
||||||
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
import java.util.function.Function;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public interface IInstancedTileEntityRenderer<T extends TileEntity> {
|
public interface IInstancedTileEntityRenderer<T extends TileEntity> {
|
||||||
|
|
||||||
void addInstanceData(T te);
|
void addInstanceData(InstanceContext<T> te);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,17 +2,12 @@ package com.simibubi.create.foundation.utility.render.instancing;
|
||||||
|
|
||||||
|
|
||||||
import com.mojang.blaze3d.platform.GlStateManager;
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
import com.simibubi.create.CreateClient;
|
|
||||||
import com.simibubi.create.foundation.utility.render.RenderWork;
|
import com.simibubi.create.foundation.utility.render.RenderWork;
|
||||||
|
import com.simibubi.create.foundation.utility.render.SafeDirectBuffer;
|
||||||
import com.simibubi.create.foundation.utility.render.TemplateBuffer;
|
import com.simibubi.create.foundation.utility.render.TemplateBuffer;
|
||||||
import net.minecraft.client.renderer.BufferBuilder;
|
import net.minecraft.client.renderer.BufferBuilder;
|
||||||
import net.minecraft.client.renderer.GLAllocation;
|
|
||||||
import net.minecraft.client.renderer.vertex.VertexFormatElement;
|
|
||||||
import org.lwjgl.opengl.*;
|
import org.lwjgl.opengl.*;
|
||||||
import org.lwjgl.system.MemoryUtil;
|
|
||||||
|
|
||||||
import java.nio.Buffer;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
@ -24,60 +19,53 @@ public abstract class InstanceBuffer<D extends InstanceData> extends TemplateBuf
|
||||||
protected int vao, ebo, invariantVBO, instanceVBO, instanceCount;
|
protected int vao, ebo, invariantVBO, instanceVBO, instanceCount;
|
||||||
|
|
||||||
protected final ArrayList<D> data = new ArrayList<>();
|
protected final ArrayList<D> data = new ArrayList<>();
|
||||||
|
protected boolean rebuffer = false;
|
||||||
protected boolean shouldBuild = true;
|
protected boolean shouldBuild = true;
|
||||||
|
|
||||||
public InstanceBuffer(BufferBuilder buf) {
|
public InstanceBuffer(BufferBuilder buf) {
|
||||||
super(buf);
|
super(buf);
|
||||||
setupMainData();
|
setup();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupMainData() {
|
private void setup() {
|
||||||
int stride = FORMAT.getStride();
|
int stride = FORMAT.getStride();
|
||||||
int invariantSize = count * stride;
|
|
||||||
|
|
||||||
ByteBuffer constant = GLAllocation.createDirectByteBuffer(invariantSize);
|
int invariantSize = vertexCount * stride;
|
||||||
|
|
||||||
|
vao = GL30.glGenVertexArrays();
|
||||||
|
ebo = GlStateManager.genBuffers();
|
||||||
|
invariantVBO = GlStateManager.genBuffers();
|
||||||
|
instanceVBO = GlStateManager.genBuffers();
|
||||||
|
|
||||||
|
try (SafeDirectBuffer constant = new SafeDirectBuffer(invariantSize)) {
|
||||||
constant.order(template.order());
|
constant.order(template.order());
|
||||||
((Buffer) constant).limit(invariantSize);
|
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++) {
|
for (int i = 0; i < vertexCount; i++) {
|
||||||
constant.putFloat(getX(template, i));
|
constant.putFloat(getX(template, i));
|
||||||
constant.putFloat(getY(template, i));
|
constant.putFloat(getY(template, i));
|
||||||
constant.putFloat(getZ(template, i));
|
constant.putFloat(getZ(template, i));
|
||||||
|
|
||||||
constant.putFloat(getNX(template, i));
|
constant.put(getNX(template, i));
|
||||||
constant.putFloat(getNY(template, i));
|
constant.put(getNY(template, i));
|
||||||
constant.putFloat(getNZ(template, i));
|
constant.put(getNZ(template, i));
|
||||||
|
|
||||||
constant.putFloat(getU(template, i));
|
constant.putFloat(getU(template, i));
|
||||||
constant.putFloat(getV(template, i));
|
constant.putFloat(getV(template, i));
|
||||||
|
|
||||||
indices.putShort((short) i);
|
|
||||||
}
|
}
|
||||||
constant.rewind();
|
constant.rewind();
|
||||||
indices.rewind();
|
|
||||||
|
|
||||||
vao = GL30.glGenVertexArrays();
|
|
||||||
GL30.glBindVertexArray(vao);
|
GL30.glBindVertexArray(vao);
|
||||||
|
|
||||||
ebo = GlStateManager.genBuffers();
|
|
||||||
invariantVBO = GlStateManager.genBuffers();
|
|
||||||
instanceVBO = GlStateManager.genBuffers();
|
|
||||||
|
|
||||||
GlStateManager.bindBuffers(GL15.GL_ARRAY_BUFFER, invariantVBO);
|
GlStateManager.bindBuffers(GL15.GL_ARRAY_BUFFER, invariantVBO);
|
||||||
GlStateManager.bufferData(GL15.GL_ARRAY_BUFFER, constant, GL15.GL_STATIC_DRAW);
|
GlStateManager.bufferData(GL15.GL_ARRAY_BUFFER, constant.getBacking(), GL15.GL_STATIC_DRAW);
|
||||||
MemoryUtil.memFree(constant);
|
|
||||||
|
|
||||||
GlStateManager.bindBuffers(GL15.GL_ELEMENT_ARRAY_BUFFER, ebo);
|
buildEBO(ebo);
|
||||||
GlStateManager.bufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indices, GL15.GL_STATIC_DRAW);
|
|
||||||
MemoryUtil.memFree(indices);
|
|
||||||
|
|
||||||
FORMAT.informAttributes(0);
|
FORMAT.informAttributes(0);
|
||||||
|
} catch (Exception e) {
|
||||||
|
delete();
|
||||||
|
}
|
||||||
|
|
||||||
GlStateManager.bindBuffers(GL15.GL_ARRAY_BUFFER, 0);
|
GlStateManager.bindBuffers(GL15.GL_ARRAY_BUFFER, 0);
|
||||||
GlStateManager.bindBuffers(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
|
GlStateManager.bindBuffers(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
|
@ -88,7 +76,7 @@ public abstract class InstanceBuffer<D extends InstanceData> extends TemplateBuf
|
||||||
protected abstract VertexFormat getInstanceFormat();
|
protected abstract VertexFormat getInstanceFormat();
|
||||||
|
|
||||||
public int numInstances() {
|
public int numInstances() {
|
||||||
return instanceCount;
|
return instanceCount + data.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
|
@ -100,14 +88,20 @@ public abstract class InstanceBuffer<D extends InstanceData> extends TemplateBuf
|
||||||
shouldBuild = true;
|
shouldBuild = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void markDirty() {
|
||||||
|
rebuffer = true;
|
||||||
|
}
|
||||||
|
|
||||||
public void delete() {
|
public void delete() {
|
||||||
RenderWork.enqueue(() -> {
|
RenderWork.enqueue(() -> {
|
||||||
GL15.glDeleteBuffers(invariantVBO);
|
GL15.glDeleteBuffers(invariantVBO);
|
||||||
GL15.glDeleteBuffers(instanceVBO);
|
GL15.glDeleteBuffers(instanceVBO);
|
||||||
GL15.glDeleteBuffers(ebo);
|
GL15.glDeleteBuffers(ebo);
|
||||||
GL30.glDeleteVertexArrays(vao);
|
GL30.glDeleteVertexArrays(vao);
|
||||||
|
vao = 0;
|
||||||
clearInstanceData();
|
ebo = 0;
|
||||||
|
invariantVBO = 0;
|
||||||
|
instanceVBO = 0;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,10 +114,10 @@ public abstract class InstanceBuffer<D extends InstanceData> extends TemplateBuf
|
||||||
setup.accept(instanceData);
|
setup.accept(instanceData);
|
||||||
|
|
||||||
data.add(instanceData);
|
data.add(instanceData);
|
||||||
instanceCount++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void render() {
|
public void render() {
|
||||||
|
if (vao == 0) return;
|
||||||
|
|
||||||
GL30.glBindVertexArray(vao);
|
GL30.glBindVertexArray(vao);
|
||||||
finishBuffering();
|
finishBuffering();
|
||||||
|
@ -135,7 +129,7 @@ public abstract class InstanceBuffer<D extends InstanceData> extends TemplateBuf
|
||||||
|
|
||||||
GlStateManager.bindBuffers(GL15.GL_ELEMENT_ARRAY_BUFFER, ebo);
|
GlStateManager.bindBuffers(GL15.GL_ELEMENT_ARRAY_BUFFER, ebo);
|
||||||
|
|
||||||
GL40.glDrawElementsInstanced(GL11.GL_QUADS, count, GL11.GL_UNSIGNED_SHORT, 0, instanceCount);
|
GL40.glDrawElementsInstanced(GL11.GL_QUADS, vertexCount, GL11.GL_UNSIGNED_SHORT, 0, instanceCount);
|
||||||
|
|
||||||
for (int i = 0; i <= numAttributes; i++) {
|
for (int i = 0; i <= numAttributes; i++) {
|
||||||
GL40.glDisableVertexAttribArray(i);
|
GL40.glDisableVertexAttribArray(i);
|
||||||
|
@ -146,21 +140,23 @@ public abstract class InstanceBuffer<D extends InstanceData> extends TemplateBuf
|
||||||
}
|
}
|
||||||
|
|
||||||
private void finishBuffering() {
|
private void finishBuffering() {
|
||||||
if (!shouldBuild) return;
|
if (!rebuffer || isEmpty()) return;
|
||||||
|
|
||||||
|
instanceCount = data.size();
|
||||||
|
|
||||||
VertexFormat instanceFormat = getInstanceFormat();
|
VertexFormat instanceFormat = getInstanceFormat();
|
||||||
|
|
||||||
int instanceSize = instanceCount * instanceFormat.getStride();
|
int instanceSize = instanceCount * instanceFormat.getStride();
|
||||||
|
|
||||||
ByteBuffer buffer = GLAllocation.createDirectByteBuffer(instanceSize);
|
try (SafeDirectBuffer buffer = new SafeDirectBuffer(instanceSize)) {
|
||||||
buffer.order(template.order());
|
buffer.order(template.order());
|
||||||
((Buffer) buffer).limit(instanceSize);
|
buffer.limit(instanceSize);
|
||||||
|
|
||||||
data.forEach(instanceData -> instanceData.write(buffer));
|
data.forEach(instanceData -> instanceData.write(buffer));
|
||||||
buffer.rewind();
|
buffer.rewind();
|
||||||
|
|
||||||
GlStateManager.bindBuffers(GL15.GL_ARRAY_BUFFER, instanceVBO);
|
GlStateManager.bindBuffers(GL15.GL_ARRAY_BUFFER, instanceVBO);
|
||||||
GlStateManager.bufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
|
GlStateManager.bufferData(GL15.GL_ARRAY_BUFFER, buffer.getBacking(), GL15.GL_STATIC_DRAW);
|
||||||
|
|
||||||
int staticAttributes = FORMAT.getNumAttributes();
|
int staticAttributes = FORMAT.getNumAttributes();
|
||||||
instanceFormat.informAttributes(staticAttributes);
|
instanceFormat.informAttributes(staticAttributes);
|
||||||
|
@ -168,11 +164,15 @@ public abstract class InstanceBuffer<D extends InstanceData> extends TemplateBuf
|
||||||
for (int i = 0; i < instanceFormat.getNumAttributes(); i++) {
|
for (int i = 0; i < instanceFormat.getNumAttributes(); i++) {
|
||||||
GL40.glVertexAttribDivisor(i + staticAttributes, 1);
|
GL40.glVertexAttribDivisor(i + staticAttributes, 1);
|
||||||
}
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// Deselect (bind to 0) the VBO
|
// Deselect (bind to 0) the VBO
|
||||||
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
|
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
shouldBuild = false;
|
shouldBuild = false;
|
||||||
|
rebuffer = false;
|
||||||
data.clear();
|
data.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
package com.simibubi.create.foundation.utility.render.instancing;
|
||||||
|
|
||||||
|
import com.simibubi.create.CreateClient;
|
||||||
|
import com.simibubi.create.foundation.utility.render.FastContraptionRenderer;
|
||||||
|
import com.simibubi.create.foundation.utility.render.FastKineticRenderer;
|
||||||
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
|
||||||
|
public abstract class InstanceContext<T extends TileEntity> {
|
||||||
|
|
||||||
|
public final T te;
|
||||||
|
|
||||||
|
public InstanceContext(T te) {
|
||||||
|
this.te = te;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract FastKineticRenderer getKinetics();
|
||||||
|
|
||||||
|
public abstract boolean checkWorldLight();
|
||||||
|
|
||||||
|
public static class Contraption<T extends TileEntity> extends InstanceContext<T> {
|
||||||
|
|
||||||
|
public final FastContraptionRenderer c;
|
||||||
|
|
||||||
|
public Contraption(T te, FastContraptionRenderer c) {
|
||||||
|
super(te);
|
||||||
|
this.c = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FastKineticRenderer getKinetics() {
|
||||||
|
return c.kinetics;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean checkWorldLight() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class World<T extends TileEntity> extends InstanceContext<T> {
|
||||||
|
|
||||||
|
public World(T te) {
|
||||||
|
super(te);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FastKineticRenderer getKinetics() {
|
||||||
|
return CreateClient.kineticRenderer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean checkWorldLight() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,30 +1,32 @@
|
||||||
package com.simibubi.create.foundation.utility.render.instancing;
|
package com.simibubi.create.foundation.utility.render.instancing;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.utility.render.SafeDirectBuffer;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
public abstract class InstanceData {
|
public abstract class InstanceData {
|
||||||
|
|
||||||
public abstract void write(ByteBuffer buf);
|
public abstract void write(SafeDirectBuffer buf);
|
||||||
|
|
||||||
public void putVec4(ByteBuffer buf, float x, float y, float z, float w) {
|
public void putVec4(SafeDirectBuffer buf, float x, float y, float z, float w) {
|
||||||
putFloat(buf, x);
|
putFloat(buf, x);
|
||||||
putFloat(buf, y);
|
putFloat(buf, y);
|
||||||
putFloat(buf, z);
|
putFloat(buf, z);
|
||||||
putFloat(buf, w);
|
putFloat(buf, w);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void putVec3(ByteBuffer buf, float x, float y, float z) {
|
public void putVec3(SafeDirectBuffer buf, float x, float y, float z) {
|
||||||
putFloat(buf, x);
|
putFloat(buf, x);
|
||||||
putFloat(buf, y);
|
putFloat(buf, y);
|
||||||
putFloat(buf, z);
|
putFloat(buf, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void putVec2(ByteBuffer buf, float x, float y) {
|
public void putVec2(SafeDirectBuffer buf, float x, float y) {
|
||||||
putFloat(buf, x);
|
putFloat(buf, x);
|
||||||
putFloat(buf, y);
|
putFloat(buf, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void putFloat(ByteBuffer buf, float f) {
|
public void putFloat(SafeDirectBuffer buf, float f) {
|
||||||
buf.putFloat(f);
|
buf.putFloat(f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
package com.simibubi.create.foundation.utility.render.instancing;
|
package com.simibubi.create.foundation.utility.render.instancing;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.utility.render.SafeDirectBuffer;
|
||||||
import net.minecraft.client.renderer.Vector3f;
|
import net.minecraft.client.renderer.Vector3f;
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
|
|
||||||
import static com.simibubi.create.foundation.utility.render.instancing.VertexAttribute.*;
|
import static com.simibubi.create.foundation.utility.render.instancing.VertexAttribute.*;
|
||||||
|
|
||||||
|
@ -41,7 +39,7 @@ public class RotatingData extends BasicData<RotatingData> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(ByteBuffer buf) {
|
public void write(SafeDirectBuffer buf) {
|
||||||
super.write(buf);
|
super.write(buf);
|
||||||
putFloat(buf, rotationalSpeed);
|
putFloat(buf, rotationalSpeed);
|
||||||
putFloat(buf, rotationOffset);
|
putFloat(buf, rotationOffset);
|
||||||
|
|
|
@ -11,8 +11,8 @@ public class VertexAttribute {
|
||||||
public static final VertexAttribute FLOAT = new VertexAttribute(VertexFormatElement.Type.FLOAT, 1);
|
public static final VertexAttribute FLOAT = new VertexAttribute(VertexFormatElement.Type.FLOAT, 1);
|
||||||
|
|
||||||
public static final VertexAttribute POSITION = VEC3;
|
public static final VertexAttribute POSITION = VEC3;
|
||||||
public static final VertexAttribute NORMAL = VEC3;
|
public static final VertexAttribute NORMAL = new VertexAttribute(VertexFormatElement.Type.BYTE, 3);
|
||||||
public static final VertexAttribute COLOR = VEC4;
|
public static final VertexAttribute COLOR = new VertexAttribute(VertexFormatElement.Type.BYTE, 4);
|
||||||
public static final VertexAttribute UV = VEC2;
|
public static final VertexAttribute UV = VEC2;
|
||||||
public static final VertexAttribute LIGHT= VEC2;
|
public static final VertexAttribute LIGHT= VEC2;
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
package com.simibubi.create.foundation.utility.render.shader;
|
package com.simibubi.create.foundation.utility.render.shader;
|
||||||
|
|
||||||
public enum Shader {
|
public enum Shader {
|
||||||
ROTATING_INSTANCED("shader/rotating.vert", "shader/instanced.frag"),
|
ROTATING("shader/rotating.vert", "shader/instanced.frag"),
|
||||||
BELT_INSTANCED("shader/belt.vert", "shader/instanced.frag"),
|
BELT("shader/belt.vert", "shader/instanced.frag"),
|
||||||
CONTRAPTION_STRUCTURE("shader/contraption.vert", "shader/contraption.frag"),
|
CONTRAPTION_STRUCTURE("shader/contraption.vert", "shader/contraption.frag"),
|
||||||
|
CONTRAPTION_ROTATING("shader/contraption_rotating.vert", "shader/contraption.frag"),
|
||||||
|
CONTRAPTION_BELT("shader/contraption_belt.vert", "shader/contraption.frag"),
|
||||||
;
|
;
|
||||||
|
|
||||||
public final String vert;
|
public final String vert;
|
||||||
|
|
|
@ -58,34 +58,28 @@ public class ShaderHelper {
|
||||||
return shaderProgram.getProgram();
|
return shaderProgram.getProgram();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ShaderCallback getViewProjectionCallback(RenderWorldLastEvent event) {
|
public static ShaderCallback getViewProjectionCallback(Matrix4f projectionMat, Matrix4f viewMat) {
|
||||||
return shader -> {
|
return shader -> {
|
||||||
ShaderHelper.MATRIX_BUFFER.position(0);
|
ShaderHelper.MATRIX_BUFFER.position(0);
|
||||||
event.getProjectionMatrix().write(ShaderHelper.MATRIX_BUFFER);
|
projectionMat.write(ShaderHelper.MATRIX_BUFFER);
|
||||||
|
|
||||||
int projection = GlStateManager.getUniformLocation(shader, "projection");
|
int projection = GlStateManager.getUniformLocation(shader, "projection");
|
||||||
GlStateManager.uniformMatrix4(projection, false, ShaderHelper.MATRIX_BUFFER);
|
GlStateManager.uniformMatrix4(projection, false, ShaderHelper.MATRIX_BUFFER);
|
||||||
|
|
||||||
// view matrix
|
|
||||||
Vec3d pos = Minecraft.getInstance().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);
|
ShaderHelper.MATRIX_BUFFER.position(0);
|
||||||
translate.write(ShaderHelper.MATRIX_BUFFER);
|
viewMat.write(ShaderHelper.MATRIX_BUFFER);
|
||||||
int view = GlStateManager.getUniformLocation(shader, "view");
|
int view = GlStateManager.getUniformLocation(shader, "view");
|
||||||
GlStateManager.uniformMatrix4(view, false, ShaderHelper.MATRIX_BUFFER);
|
GlStateManager.uniformMatrix4(view, false, ShaderHelper.MATRIX_BUFFER);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void useShader(Shader shader) {
|
public static int useShader(Shader shader) {
|
||||||
useShader(shader, null);
|
return useShader(shader, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void useShader(Shader shader, @Nullable ShaderCallback cb) {
|
public static int useShader(Shader shader, @Nullable ShaderCallback cb) {
|
||||||
ShaderProgram prog = PROGRAMS.get(shader);
|
ShaderProgram prog = PROGRAMS.get(shader);
|
||||||
if (prog == null) {
|
if (prog == null) {
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int program = prog.getProgram();
|
int program = prog.getProgram();
|
||||||
|
@ -102,6 +96,8 @@ public class ShaderHelper {
|
||||||
if (cb != null) {
|
if (cb != null) {
|
||||||
cb.call(program);
|
cb.call(program);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return program;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void releaseShader() {
|
public static void releaseShader() {
|
||||||
|
|
|
@ -16,7 +16,6 @@ vec4 light() {
|
||||||
return texture2D(LightMap, lm);
|
return texture2D(LightMap, lm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec4 tex = texture2D(BlockAtlas, TexCoords);
|
vec4 tex = texture2D(BlockAtlas, TexCoords);
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,7 @@ uniform int ticks;
|
||||||
uniform mat4 projection;
|
uniform mat4 projection;
|
||||||
uniform mat4 view;
|
uniform mat4 view;
|
||||||
|
|
||||||
mat4 rotate(vec3 axis, float angle)
|
mat4 rotate(vec3 axis, float angle) {
|
||||||
{
|
|
||||||
float s = sin(angle);
|
float s = sin(angle);
|
||||||
float c = cos(angle);
|
float c = cos(angle);
|
||||||
float oc = 1.0 - c;
|
float oc = 1.0 - c;
|
||||||
|
@ -47,18 +46,11 @@ float diffuse(vec3 normal) {
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
mat4 rotation = contraptionRotation();
|
mat4 rotation = contraptionRotation();
|
||||||
|
vec4 worldPos = (rotation * vec4(aPos - vec3(0.5), 1)) + vec4(cPos + vec3(0.5), 0);
|
||||||
|
|
||||||
vec4 rotatedPos = rotation * vec4(aPos - vec3(0.5), 1);
|
BoxCoord = (worldPos.xyz - lightBoxMin) / lightBoxSize;
|
||||||
|
Diffuse = diffuse(normalize(rotation * vec4(aNormal, 0.)).xyz);
|
||||||
vec4 worldPos = rotatedPos + vec4(cPos + vec3(0.5), 0);
|
Color = aColor;
|
||||||
|
|
||||||
vec3 boxCoord = (worldPos.xyz - lightBoxMin) / lightBoxSize;
|
|
||||||
|
|
||||||
float df = diffuse(normalize(aNormal));
|
|
||||||
|
|
||||||
Diffuse = diffuse(normalize((rotation * vec4(aNormal, 0.)).xyz));
|
|
||||||
Color = vec4(aColor.rgb / df, aColor.a);
|
|
||||||
BoxCoord = boxCoord;
|
|
||||||
TexCoords = aTexCoords;
|
TexCoords = aTexCoords;
|
||||||
gl_Position = projection * view * worldPos;
|
gl_Position = projection * view * worldPos;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
#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 vec3 rotationDegrees;
|
||||||
|
layout (location = 6) in float speed;
|
||||||
|
layout (location = 7) in vec2 sourceUV;
|
||||||
|
layout (location = 8) in vec4 scrollTexture;
|
||||||
|
layout (location = 9) in float scrollMult;
|
||||||
|
|
||||||
|
out float Diffuse;
|
||||||
|
out vec2 TexCoords;
|
||||||
|
out vec4 Color;
|
||||||
|
out vec3 BoxCoord;
|
||||||
|
|
||||||
|
uniform vec3 lightBoxSize;
|
||||||
|
uniform vec3 lightBoxMin;
|
||||||
|
uniform vec3 cPos;
|
||||||
|
uniform vec3 cRot;
|
||||||
|
|
||||||
|
uniform float time;
|
||||||
|
uniform int ticks;
|
||||||
|
uniform mat4 projection;
|
||||||
|
uniform mat4 view;
|
||||||
|
|
||||||
|
mat4 rotate(vec3 axis, float angle)
|
||||||
|
{
|
||||||
|
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.);
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4 rotation(vec3 rot) {
|
||||||
|
return rotate(vec3(0, 1, 0), rot.y) * rotate(vec3(0, 0, 1), rot.z) * rotate(vec3(1, 0, 0), rot.x);
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4 contraptionRotation() {
|
||||||
|
vec3 rot = -fract(cRot / 360) * PI * 2;
|
||||||
|
return rotation(rot);
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4 localRotation() {
|
||||||
|
vec3 rot = fract(rotationDegrees / 360) * PI * 2;
|
||||||
|
return rotation(rot);
|
||||||
|
}
|
||||||
|
|
||||||
|
float diffuse(vec3 normal) {
|
||||||
|
float x = normal.x;
|
||||||
|
float y = normal.y;
|
||||||
|
float z = normal.z;
|
||||||
|
return min(x * x * 0.6f + y * y * ((3f + y) / 4f) + z * z * 0.8f, 1f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
mat4 localRotation = localRotation();
|
||||||
|
vec4 localPos = localRotation * vec4(aPos - 0.5, 1f) + vec4(instancePos, 0);
|
||||||
|
|
||||||
|
mat4 contraptionRotation = contraptionRotation();
|
||||||
|
vec4 worldPos = contraptionRotation * localPos + vec4(cPos + 0.5, 0);
|
||||||
|
|
||||||
|
float scrollSize = scrollTexture.w - scrollTexture.y;
|
||||||
|
float scroll = fract(speed * time / (36 * 16.)) * scrollSize * scrollMult;
|
||||||
|
|
||||||
|
BoxCoord = (worldPos.xyz - lightBoxMin) / lightBoxSize;
|
||||||
|
Diffuse = diffuse(normalize(contraptionRotation * localRotation * vec4(aNormal, 0.)).xyz);
|
||||||
|
Color = vec4(1.);
|
||||||
|
TexCoords = aTexCoords - sourceUV + scrollTexture.xy + vec2(0., scroll);
|
||||||
|
gl_Position = projection * view * worldPos;
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
#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;
|
||||||
|
|
||||||
|
out float Diffuse;
|
||||||
|
out vec2 TexCoords;
|
||||||
|
out vec4 Color;
|
||||||
|
out vec3 BoxCoord;
|
||||||
|
|
||||||
|
uniform vec3 lightBoxSize;
|
||||||
|
uniform vec3 lightBoxMin;
|
||||||
|
uniform vec3 cPos;
|
||||||
|
uniform vec3 cRot;
|
||||||
|
|
||||||
|
uniform float time;
|
||||||
|
uniform int ticks;
|
||||||
|
uniform mat4 projection;
|
||||||
|
uniform mat4 view;
|
||||||
|
|
||||||
|
mat4 rotate(vec3 axis, float angle) {
|
||||||
|
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.);
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4 kineticRotation() {
|
||||||
|
float degrees = rotationOffset + time * speed * -3./10.;
|
||||||
|
float angle = fract(degrees / 360.) * PI * 2.;
|
||||||
|
|
||||||
|
vec3 axis = normalize(rotationAxis);
|
||||||
|
return rotate(axis, angle);
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4 contraptionRotation() {
|
||||||
|
vec3 rot = -fract(cRot / 360) * PI * 2;
|
||||||
|
return rotate(vec3(0, 1, 0), rot.y) * rotate(vec3(0, 0, 1), rot.z) * rotate(vec3(1, 0, 0), rot.x);
|
||||||
|
}
|
||||||
|
|
||||||
|
float diffuse(vec3 normal) {
|
||||||
|
float x = normal.x;
|
||||||
|
float y = normal.y;
|
||||||
|
float z = normal.z;
|
||||||
|
return min(x * x * 0.6f + y * y * ((3f + y) / 4f) + z * z * 0.8f, 1f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
mat4 kineticRotation = kineticRotation();
|
||||||
|
vec4 localPos = kineticRotation * vec4(aPos - 0.5, 1f) + vec4(instancePos, 0);
|
||||||
|
|
||||||
|
mat4 contraptionRotation = contraptionRotation();
|
||||||
|
vec4 worldPos = contraptionRotation * localPos + vec4(cPos + 0.5, 0);
|
||||||
|
|
||||||
|
BoxCoord = (worldPos.xyz - lightBoxMin) / lightBoxSize;
|
||||||
|
Diffuse = diffuse(normalize(contraptionRotation * localRotation * vec4(aNormal, 0.)).xyz);
|
||||||
|
Color = vec4(1.);
|
||||||
|
TexCoords = aTexCoords;
|
||||||
|
gl_Position = projection * view * worldPos;
|
||||||
|
}
|
Loading…
Reference in a new issue