mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-11-14 14:33:57 +01:00
merge experimental rendering from 1.16 to 1.15 part II
This commit is contained in:
parent
7d43bb056a
commit
102e392ab4
@ -13,7 +13,8 @@ import com.simibubi.create.content.contraptions.fluids.FluidTransportBehaviour.A
|
|||||||
import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock.HeatLevel;
|
import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock.HeatLevel;
|
||||||
import com.simibubi.create.foundation.utility.*;
|
import com.simibubi.create.foundation.utility.*;
|
||||||
|
|
||||||
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
|
import com.simibubi.create.foundation.utility.render.BeltBuffer;
|
||||||
|
import com.simibubi.create.foundation.utility.render.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;
|
||||||
@ -216,15 +217,19 @@ public class AllBlockPartials {
|
|||||||
return CreateClient.bufferCache.renderDirectionalPartial(this, referenceState, facing, ms);
|
return CreateClient.bufferCache.renderDirectionalPartial(this, referenceState, facing, ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
public InstancedBuffer renderOnInstanced(BlockState referenceState) {
|
public RotatingBuffer renderOnRotating(BlockState referenceState) {
|
||||||
return CreateClient.kineticRenderer.renderPartialInstanced(this, referenceState);
|
return CreateClient.kineticRenderer.renderPartialRotating(this, referenceState);
|
||||||
}
|
}
|
||||||
|
|
||||||
public InstancedBuffer renderOnDirectionalSouthInstanced(BlockState referenceState) {
|
public BeltBuffer renderOnBelt(BlockState referenceState) {
|
||||||
Direction facing = referenceState.get(FACING);
|
return CreateClient.kineticRenderer.renderPartialBelt(this, referenceState);
|
||||||
return renderOnDirectionalSouthInstanced(referenceState, facing);
|
|
||||||
}
|
}
|
||||||
public InstancedBuffer renderOnDirectionalSouthInstanced(BlockState referenceState, Direction facing) {
|
|
||||||
|
public RotatingBuffer renderOnDirectionalSouthRotating(BlockState referenceState) {
|
||||||
|
Direction facing = referenceState.get(FACING);
|
||||||
|
return renderOnDirectionalSouthRotating(referenceState, facing);
|
||||||
|
}
|
||||||
|
public RotatingBuffer renderOnDirectionalSouthRotating(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)
|
||||||
|
@ -9,6 +9,7 @@ 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.InstancedBuffer;
|
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
|
||||||
|
import com.simibubi.create.foundation.utility.render.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;
|
||||||
|
|
||||||
@ -49,11 +50,11 @@ public class KineticTileEntityRenderer extends SafeTileEntityRenderer<KineticTil
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void renderRotatingKineticBlock(KineticTileEntity te, BlockState renderedState, int light) {
|
public static void renderRotatingKineticBlock(KineticTileEntity te, BlockState renderedState, int light) {
|
||||||
InstancedBuffer instancedRenderer = CreateClient.kineticRenderer.renderBlockInstanced(KINETIC_TILE, renderedState);
|
RotatingBuffer instancedRenderer = CreateClient.kineticRenderer.renderBlockInstanced(KINETIC_TILE, renderedState);
|
||||||
renderRotatingBuffer(te, instancedRenderer, light);
|
renderRotatingBuffer(te, instancedRenderer, light);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void renderRotatingBuffer(KineticTileEntity te, InstancedBuffer instancer, int light) {
|
public static void renderRotatingBuffer(KineticTileEntity te, RotatingBuffer instancer, int light) {
|
||||||
instancer.setupInstance(data -> {
|
instancer.setupInstance(data -> {
|
||||||
final BlockPos pos = te.getPos();
|
final BlockPos pos = te.getPos();
|
||||||
Axis axis = ((IRotate) te.getBlockState()
|
Axis axis = ((IRotate) te.getBlockState()
|
||||||
@ -129,7 +130,7 @@ public class KineticTileEntityRenderer extends SafeTileEntityRenderer<KineticTil
|
|||||||
return te.getBlockState();
|
return te.getBlockState();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected InstancedBuffer getRotatedModel(KineticTileEntity te) {
|
protected RotatingBuffer getRotatedModel(KineticTileEntity te) {
|
||||||
return CreateClient.kineticRenderer.renderBlockInstanced(KINETIC_TILE, getRenderedBlockState(te));
|
return CreateClient.kineticRenderer.renderBlockInstanced(KINETIC_TILE, getRenderedBlockState(te));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ 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.InstancedBuffer;
|
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
|
||||||
|
import com.simibubi.create.foundation.utility.render.RotatingBuffer;
|
||||||
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;
|
||||||
|
|
||||||
@ -27,8 +28,8 @@ public class DrillRenderer extends KineticTileEntityRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected InstancedBuffer getRotatedModel(KineticTileEntity te) {
|
protected RotatingBuffer getRotatedModel(KineticTileEntity te) {
|
||||||
return AllBlockPartials.DRILL_HEAD.renderOnDirectionalSouthInstanced(te.getBlockState());
|
return AllBlockPartials.DRILL_HEAD.renderOnDirectionalSouthRotating(te.getBlockState());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static SuperByteBuffer getRotatingModel(BlockState state) {
|
protected static SuperByteBuffer getRotatingModel(BlockState state) {
|
||||||
|
@ -8,6 +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.InstancedBuffer;
|
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
|
||||||
|
import com.simibubi.create.foundation.utility.render.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;
|
||||||
@ -91,14 +92,14 @@ public class CuckooClockRenderer extends KineticTileEntityRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected InstancedBuffer getRotatedModel(KineticTileEntity te) {
|
protected RotatingBuffer getRotatedModel(KineticTileEntity te) {
|
||||||
return transform(AllBlockPartials.SHAFT_HALF, te);
|
return transform(AllBlockPartials.SHAFT_HALF, te);
|
||||||
}
|
}
|
||||||
|
|
||||||
private InstancedBuffer transform(AllBlockPartials partial, KineticTileEntity te) {
|
private RotatingBuffer transform(AllBlockPartials partial, KineticTileEntity te) {
|
||||||
return partial.renderOnDirectionalSouthInstanced(te.getBlockState(), te.getBlockState()
|
return partial.renderOnDirectionalSouthRotating(te.getBlockState(), te.getBlockState()
|
||||||
.get(CuckooClockBlock.HORIZONTAL_FACING)
|
.get(CuckooClockBlock.HORIZONTAL_FACING)
|
||||||
.getOpposite());
|
.getOpposite());
|
||||||
}
|
}
|
||||||
|
|
||||||
private SuperByteBuffer rotateHand(SuperByteBuffer buffer, float angle, Direction facing) {
|
private SuperByteBuffer rotateHand(SuperByteBuffer buffer, float angle, Direction facing) {
|
||||||
|
@ -9,6 +9,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.InstancedBuffer;
|
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.utility.render.RotatingBuffer;
|
||||||
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;
|
||||||
@ -31,10 +32,10 @@ public class EncasedFanRenderer extends KineticTileEntityRenderer {
|
|||||||
int lightBehind = WorldRenderer.getLightmapCoordinates(te.getWorld(), te.getPos().offset(direction.getOpposite()));
|
int lightBehind = WorldRenderer.getLightmapCoordinates(te.getWorld(), te.getPos().offset(direction.getOpposite()));
|
||||||
int lightInFront = WorldRenderer.getLightmapCoordinates(te.getWorld(), te.getPos().offset(direction));
|
int lightInFront = WorldRenderer.getLightmapCoordinates(te.getWorld(), te.getPos().offset(direction));
|
||||||
|
|
||||||
InstancedBuffer shaftHalf =
|
RotatingBuffer shaftHalf =
|
||||||
AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthInstanced(te.getBlockState(), direction.getOpposite());
|
AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(te.getBlockState(), direction.getOpposite());
|
||||||
InstancedBuffer fanInner =
|
RotatingBuffer fanInner =
|
||||||
AllBlockPartials.ENCASED_FAN_INNER.renderOnDirectionalSouthInstanced(te.getBlockState(), direction.getOpposite());
|
AllBlockPartials.ENCASED_FAN_INNER.renderOnDirectionalSouthRotating(te.getBlockState(), direction.getOpposite());
|
||||||
|
|
||||||
renderRotatingBuffer(te, shaftHalf, lightBehind);
|
renderRotatingBuffer(te, shaftHalf, lightBehind);
|
||||||
fanInner.setupInstance(data -> {
|
fanInner.setupInstance(data -> {
|
||||||
|
@ -10,6 +10,7 @@ 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.InstancedBuffer;
|
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
|
||||||
|
import com.simibubi.create.foundation.utility.render.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;
|
||||||
@ -75,10 +76,10 @@ public class FlywheelRenderer extends KineticTileEntityRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected InstancedBuffer getRotatedModel(KineticTileEntity te) {
|
protected RotatingBuffer getRotatedModel(KineticTileEntity te) {
|
||||||
return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthInstanced(te.getBlockState(), te.getBlockState()
|
return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(te.getBlockState(), te.getBlockState()
|
||||||
.get(HORIZONTAL_FACING)
|
.get(HORIZONTAL_FACING)
|
||||||
.getOpposite());
|
.getOpposite());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected SuperByteBuffer transformConnector(SuperByteBuffer buffer, boolean upper, boolean rotating, float angle,
|
protected SuperByteBuffer transformConnector(SuperByteBuffer buffer, boolean upper, boolean rotating, float angle,
|
||||||
|
@ -6,6 +6,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.InstancedBuffer;
|
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.utility.render.RotatingBuffer;
|
||||||
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
||||||
|
|
||||||
public class MillstoneRenderer extends KineticTileEntityRenderer {
|
public class MillstoneRenderer extends KineticTileEntityRenderer {
|
||||||
@ -15,8 +16,8 @@ public class MillstoneRenderer extends KineticTileEntityRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected InstancedBuffer getRotatedModel(KineticTileEntity te) {
|
protected RotatingBuffer getRotatedModel(KineticTileEntity te) {
|
||||||
return CreateClient.kineticRenderer.renderPartialInstanced(AllBlockPartials.MILLSTONE_COG, te.getBlockState());
|
return CreateClient.kineticRenderer.renderPartialRotating(AllBlockPartials.MILLSTONE_COG, te.getBlockState());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -5,6 +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.InstancedBuffer;
|
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.utility.render.RotatingBuffer;
|
||||||
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
||||||
|
|
||||||
public class CreativeMotorRenderer extends KineticTileEntityRenderer {
|
public class CreativeMotorRenderer extends KineticTileEntityRenderer {
|
||||||
@ -14,8 +15,8 @@ public class CreativeMotorRenderer extends KineticTileEntityRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected InstancedBuffer getRotatedModel(KineticTileEntity te) {
|
protected RotatingBuffer getRotatedModel(KineticTileEntity te) {
|
||||||
return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthInstanced(te.getBlockState());
|
return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(te.getBlockState());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ 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.InstancedBuffer;
|
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
|
||||||
|
import com.simibubi.create.foundation.utility.render.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;
|
||||||
@ -123,10 +124,10 @@ public class SawRenderer extends SafeTileEntityRenderer<SawTileEntity> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected InstancedBuffer getRotatedModel(KineticTileEntity te) {
|
protected RotatingBuffer getRotatedModel(KineticTileEntity 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.renderOnDirectionalSouthInstanced(state.rotate(te.getWorld(), te.getPos(), Rotation.CLOCKWISE_180));
|
return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(state.rotate(te.getWorld(), te.getPos(), Rotation.CLOCKWISE_180));
|
||||||
return CreateClient.kineticRenderer.renderBlockInstanced(KineticTileEntityRenderer.KINETIC_TILE,
|
return CreateClient.kineticRenderer.renderBlockInstanced(KineticTileEntityRenderer.KINETIC_TILE,
|
||||||
getRenderedBlockState(te));
|
getRenderedBlockState(te));
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,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.AngleHelper;
|
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||||
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
|
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
|
||||||
|
import com.simibubi.create.foundation.utility.render.RotatingBuffer;
|
||||||
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
|
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
|
||||||
|
|
||||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||||
@ -44,10 +45,10 @@ public class BearingRenderer extends KineticTileEntityRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected InstancedBuffer getRotatedModel(KineticTileEntity te) {
|
protected RotatingBuffer getRotatedModel(KineticTileEntity te) {
|
||||||
return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthInstanced(te.getBlockState(), te.getBlockState()
|
return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(te.getBlockState(), te.getBlockState()
|
||||||
.get(BearingBlock.FACING)
|
.get(BearingBlock.FACING)
|
||||||
.getOpposite());
|
.getOpposite());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ 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.InstancedBuffer;
|
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
|
||||||
|
import com.simibubi.create.foundation.utility.render.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;
|
||||||
@ -52,8 +53,8 @@ public class PumpRenderer extends KineticTileEntityRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected InstancedBuffer getRotatedModel(KineticTileEntity te) {
|
protected RotatingBuffer getRotatedModel(KineticTileEntity te) {
|
||||||
return AllBlockPartials.MECHANICAL_PUMP_COG.renderOnDirectionalSouthInstanced(te.getBlockState());
|
return AllBlockPartials.MECHANICAL_PUMP_COG.renderOnDirectionalSouthRotating(te.getBlockState());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ 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.InstancedBuffer;
|
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.utility.render.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;
|
||||||
|
|
||||||
@ -23,7 +24,7 @@ public class SpeedControllerRenderer extends SmartTileEntityRenderer<SpeedContro
|
|||||||
KineticTileEntityRenderer.renderRotatingBuffer(tileEntityIn, getRotatedModel(tileEntityIn), light);
|
KineticTileEntityRenderer.renderRotatingBuffer(tileEntityIn, getRotatedModel(tileEntityIn), light);
|
||||||
}
|
}
|
||||||
|
|
||||||
private InstancedBuffer getRotatedModel(SpeedControllerTileEntity te) {
|
private RotatingBuffer 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)));
|
||||||
}
|
}
|
||||||
|
@ -16,16 +16,14 @@ 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.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.BeltBuffer;
|
||||||
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
|
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
|
||||||
|
import com.simibubi.create.foundation.utility.render.RotatingBuffer;
|
||||||
import com.simibubi.create.foundation.utility.render.ShadowRenderHelper;
|
import com.simibubi.create.foundation.utility.render.ShadowRenderHelper;
|
||||||
|
|
||||||
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;
|
||||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
import net.minecraft.client.renderer.*;
|
||||||
import net.minecraft.client.renderer.ItemRenderer;
|
|
||||||
import net.minecraft.client.renderer.RenderType;
|
|
||||||
import net.minecraft.client.renderer.Vector3f;
|
|
||||||
import net.minecraft.client.renderer.model.ItemCameraTransforms.TransformType;
|
import net.minecraft.client.renderer.model.ItemCameraTransforms.TransformType;
|
||||||
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
@ -96,7 +94,10 @@ public class BeltRenderer extends SafeTileEntityRenderer<BeltTileEntity> {
|
|||||||
: start ? AllBlockPartials.BELT_START
|
: start ? AllBlockPartials.BELT_START
|
||||||
: end ? AllBlockPartials.BELT_END : AllBlockPartials.BELT_MIDDLE;
|
: end ? AllBlockPartials.BELT_END : AllBlockPartials.BELT_MIDDLE;
|
||||||
|
|
||||||
InstancedBuffer beltBuffer = beltPartial.renderOnInstanced(blockState);
|
BeltBuffer beltBuffer = beltPartial.renderOnBelt(blockState);
|
||||||
|
SpriteShiftEntry spriteShift =
|
||||||
|
diagonal ? AllSpriteShifts.BELT_DIAGONAL : bottom ? AllSpriteShifts.BELT_OFFSET : AllSpriteShifts.BELT;
|
||||||
|
|
||||||
int cycleLength = diagonal ? 12 : 16;
|
int cycleLength = diagonal ? 12 : 16;
|
||||||
int cycleOffset = bottom ? 8 : 0;
|
int cycleOffset = bottom ? 8 : 0;
|
||||||
|
|
||||||
@ -108,12 +109,16 @@ public class BeltRenderer extends SafeTileEntityRenderer<BeltTileEntity> {
|
|||||||
|| sideways && axisDirection == AxisDirection.NEGATIVE)
|
|| sideways && axisDirection == AxisDirection.NEGATIVE)
|
||||||
speed = -speed;
|
speed = -speed;
|
||||||
|
|
||||||
data.setPackedLight(light)
|
Matrix4f m = new Matrix4f();
|
||||||
.setPosition(te.getPos())
|
m.loadIdentity();
|
||||||
.setRotationalSpeed(speed)
|
m.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(AngleHelper.horizontalAngle(facing) + (upward ? 180 : 0) + (sideways ? 270 : 0)));
|
||||||
.setRotationAxis(0, 0, 0)
|
m.multiply(Vector3f.POSITIVE_Z.getDegreesQuaternion(sideways ? 90 : 0));
|
||||||
.setCycleLength(cycleLength)
|
m.multiply(Vector3f.POSITIVE_X.getDegreesQuaternion(!diagonal && beltSlope != BeltSlope.HORIZONTAL ? 90 : 0));
|
||||||
.setCycleOffset(cycleOffset);
|
|
||||||
|
data.setPosition(te.getPos())
|
||||||
|
.setModel(m)
|
||||||
|
.setPackedLight(light)
|
||||||
|
.setRotationalSpeed(speed);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Diagonal belt do not have a separate bottom model
|
// Diagonal belt do not have a separate bottom model
|
||||||
@ -138,7 +143,7 @@ public class BeltRenderer extends SafeTileEntityRenderer<BeltTileEntity> {
|
|||||||
msr.rotateX(90);
|
msr.rotateX(90);
|
||||||
msr.unCentre();
|
msr.unCentre();
|
||||||
|
|
||||||
InstancedBuffer superBuffer = CreateClient.kineticRenderer
|
RotatingBuffer superBuffer = CreateClient.kineticRenderer
|
||||||
.renderDirectionalPartialInstanced(AllBlockPartials.BELT_PULLEY, blockState, dir, modelTransform);
|
.renderDirectionalPartialInstanced(AllBlockPartials.BELT_PULLEY, blockState, dir, modelTransform);
|
||||||
KineticTileEntityRenderer.renderRotatingBuffer(te, superBuffer, light);
|
KineticTileEntityRenderer.renderRotatingBuffer(te, superBuffer, light);
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ 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.InstancedBuffer;
|
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.utility.render.RotatingBuffer;
|
||||||
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;
|
||||||
@ -34,7 +35,7 @@ public class SplitShaftRenderer extends KineticTileEntityRenderer {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
||||||
InstancedBuffer shaft = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthInstanced(te.getBlockState(), direction);
|
RotatingBuffer shaft = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(te.getBlockState(), direction);
|
||||||
|
|
||||||
shaft.setupInstance(data -> {
|
shaft.setupInstance(data -> {
|
||||||
float speed = te.getSpeed();
|
float speed = te.getSpeed();
|
||||||
|
@ -7,6 +7,7 @@ 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.InstancedBuffer;
|
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.utility.render.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;
|
||||||
import net.minecraft.state.properties.BlockStateProperties;
|
import net.minecraft.state.properties.BlockStateProperties;
|
||||||
@ -31,7 +32,7 @@ public class GearboxRenderer extends KineticTileEntityRenderer {
|
|||||||
if (boxAxis == axis)
|
if (boxAxis == axis)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
InstancedBuffer shaft = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthInstanced(te.getBlockState(), direction);
|
RotatingBuffer shaft = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(te.getBlockState(), direction);
|
||||||
|
|
||||||
shaft.setupInstance(data -> {
|
shaft.setupInstance(data -> {
|
||||||
float speed = te.getSpeed();
|
float speed = te.getSpeed();
|
||||||
|
@ -9,6 +9,7 @@ import com.simibubi.create.content.logistics.block.mechanicalArm.ArmTileEntity.P
|
|||||||
import com.simibubi.create.foundation.utility.*;
|
import com.simibubi.create.foundation.utility.*;
|
||||||
|
|
||||||
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
|
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
|
||||||
|
import com.simibubi.create.foundation.utility.render.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;
|
||||||
@ -116,8 +117,8 @@ public class ArmRenderer extends KineticTileEntityRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected InstancedBuffer getRotatedModel(KineticTileEntity te) {
|
protected RotatingBuffer getRotatedModel(KineticTileEntity te) {
|
||||||
return AllBlockPartials.ARM_COG.renderOnInstanced(te.getBlockState());
|
return AllBlockPartials.ARM_COG.renderOnRotating(te.getBlockState());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,121 @@
|
|||||||
|
package com.simibubi.create.foundation.utility.render;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
|
import net.minecraft.client.renderer.BufferBuilder;
|
||||||
|
import net.minecraft.client.renderer.GLAllocation;
|
||||||
|
import net.minecraft.client.renderer.LightTexture;
|
||||||
|
import net.minecraft.client.renderer.Matrix4f;
|
||||||
|
import net.minecraft.client.renderer.vertex.VertexFormatElement;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import org.lwjgl.opengl.GL11;
|
||||||
|
import org.lwjgl.opengl.GL15;
|
||||||
|
import org.lwjgl.opengl.GL20;
|
||||||
|
import org.lwjgl.opengl.GL40;
|
||||||
|
|
||||||
|
import java.nio.Buffer;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
public class BeltBuffer extends InstancedBuffer<BeltBuffer.BeltData> {
|
||||||
|
public BeltBuffer(BufferBuilder buf) {
|
||||||
|
super(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected BeltData newInstance() {
|
||||||
|
return new BeltData();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int numAttributes() {
|
||||||
|
return 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void finishBufferingInternal() {
|
||||||
|
int floatSize = VertexFormatElement.Type.FLOAT.getSize();
|
||||||
|
int intSize = VertexFormatElement.Type.INT.getSize();
|
||||||
|
int stride = floatSize * 22;
|
||||||
|
|
||||||
|
int instanceSize = instanceCount * stride;
|
||||||
|
|
||||||
|
ByteBuffer buffer = GLAllocation.createDirectByteBuffer(instanceSize);
|
||||||
|
buffer.order(template.order());
|
||||||
|
((Buffer) buffer).limit(instanceSize);
|
||||||
|
|
||||||
|
data.forEach(instanceData -> instanceData.buffer(buffer));
|
||||||
|
buffer.rewind();
|
||||||
|
|
||||||
|
GlStateManager.bindBuffers(GL15.GL_ARRAY_BUFFER, instanceVBO);
|
||||||
|
GlStateManager.bufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
// render position
|
||||||
|
GL20.glVertexAttribPointer(3, 3, GL11.GL_FLOAT, false, stride, 0);
|
||||||
|
|
||||||
|
// model matrix
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
GL20.glVertexAttribPointer(4 + i, 4, GL11.GL_FLOAT, false, stride, floatSize * (4 * i + 3));
|
||||||
|
}
|
||||||
|
|
||||||
|
// light map
|
||||||
|
GL20.glVertexAttribPointer(8, 2, GL11.GL_FLOAT, false, stride, floatSize * 16L);
|
||||||
|
|
||||||
|
// rotational speed and offset
|
||||||
|
GL20.glVertexAttribPointer(9, 1, GL11.GL_FLOAT, false, stride, floatSize * 18L);
|
||||||
|
|
||||||
|
for (int i = 3; i <= numAttributes(); i++) {
|
||||||
|
GL40.glVertexAttribDivisor(i, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deselect (bind to 0) the VBO
|
||||||
|
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class BeltData {
|
||||||
|
private float x;
|
||||||
|
private float y;
|
||||||
|
private float z;
|
||||||
|
private Matrix4f model;
|
||||||
|
private int packedLight;
|
||||||
|
private float rotationalSpeed;
|
||||||
|
|
||||||
|
public BeltData setPosition(BlockPos pos) {
|
||||||
|
this.x = pos.getX();
|
||||||
|
this.y = pos.getY();
|
||||||
|
this.z = pos.getZ();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BeltData setModel(Matrix4f model) {
|
||||||
|
this.model = model;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BeltData setPackedLight(int packedLight) {
|
||||||
|
this.packedLight = packedLight;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BeltData setRotationalSpeed(float rotationalSpeed) {
|
||||||
|
this.rotationalSpeed = rotationalSpeed;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void buffer(ByteBuffer buf) {
|
||||||
|
float blockLightCoordinates = LightTexture.getBlockLightCoordinates(packedLight) / (float) 0xF;
|
||||||
|
float skyLightCoordinates = LightTexture.getSkyLightCoordinates(packedLight) / (float) 0xF;
|
||||||
|
|
||||||
|
buf.putFloat(x);
|
||||||
|
buf.putFloat(y);
|
||||||
|
buf.putFloat(z);
|
||||||
|
|
||||||
|
InstancedBuffer.MATRIX_BUF.rewind();
|
||||||
|
model.write(InstancedBuffer.MATRIX_BUF.asFloatBuffer());
|
||||||
|
InstancedBuffer.MATRIX_BUF.rewind();
|
||||||
|
|
||||||
|
buf.put(InstancedBuffer.MATRIX_BUF);
|
||||||
|
buf.putFloat(blockLightCoordinates);
|
||||||
|
buf.putFloat(skyLightCoordinates);
|
||||||
|
buf.putFloat(rotationalSpeed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -8,6 +8,7 @@ import com.mojang.blaze3d.systems.RenderSystem;
|
|||||||
import com.simibubi.create.AllBlockPartials;
|
import com.simibubi.create.AllBlockPartials;
|
||||||
import com.simibubi.create.Create;
|
import com.simibubi.create.Create;
|
||||||
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.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
@ -36,12 +37,14 @@ import static com.simibubi.create.foundation.utility.render.SuperByteBufferCache
|
|||||||
|
|
||||||
@Mod.EventBusSubscriber(modid = Create.ID, value = Dist.CLIENT)
|
@Mod.EventBusSubscriber(modid = Create.ID, value = Dist.CLIENT)
|
||||||
public class FastKineticRenderer {
|
public class FastKineticRenderer {
|
||||||
Map<SuperByteBufferCache.Compartment<?>, Cache<Object, InstancedBuffer>> cache;
|
Map<SuperByteBufferCache.Compartment<?>, Cache<Object, RotatingBuffer>> rotating;
|
||||||
|
Map<SuperByteBufferCache.Compartment<?>, Cache<Object, BeltBuffer>> belts;
|
||||||
|
|
||||||
Queue<Runnable> runs;
|
Queue<Runnable> runs;
|
||||||
|
|
||||||
public FastKineticRenderer() {
|
public FastKineticRenderer() {
|
||||||
cache = new HashMap<>();
|
rotating = new HashMap<>();
|
||||||
|
belts = new HashMap<>();
|
||||||
runs = new ConcurrentLinkedQueue<>();
|
runs = new ConcurrentLinkedQueue<>();
|
||||||
registerCompartment(SuperByteBufferCache.GENERIC_TILE);
|
registerCompartment(SuperByteBufferCache.GENERIC_TILE);
|
||||||
registerCompartment(SuperByteBufferCache.PARTIAL);
|
registerCompartment(SuperByteBufferCache.PARTIAL);
|
||||||
@ -49,8 +52,14 @@ public class FastKineticRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void tick() {
|
public void tick() {
|
||||||
for (Cache<Object, InstancedBuffer> cache : cache.values()) {
|
for (Cache<Object, RotatingBuffer> cache : rotating.values()) {
|
||||||
for (InstancedBuffer renderer : cache.asMap().values()) {
|
for (RotatingBuffer renderer : cache.asMap().values()) {
|
||||||
|
renderer.clearInstanceData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Cache<Object, BeltBuffer> cache : belts.values()) {
|
||||||
|
for (BeltBuffer renderer : cache.asMap().values()) {
|
||||||
renderer.clearInstanceData();
|
renderer.clearInstanceData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -69,7 +78,22 @@ public class FastKineticRenderer {
|
|||||||
GameRenderer gameRenderer = Minecraft.getInstance().gameRenderer;
|
GameRenderer gameRenderer = Minecraft.getInstance().gameRenderer;
|
||||||
LightTexture lightManager = gameRenderer.getLightmapTextureManager();
|
LightTexture lightManager = gameRenderer.getLightmapTextureManager();
|
||||||
|
|
||||||
ShaderHelper.useShader(Shader.ROTATING_INSTANCED, shader -> {
|
Texture blockAtlasTexture = Minecraft.getInstance().textureManager.getTexture(PlayerContainer.BLOCK_ATLAS_TEXTURE);
|
||||||
|
Texture lightTexture = Minecraft.getInstance().textureManager.getTexture(lightManager.resourceLocation);
|
||||||
|
|
||||||
|
GL40.glActiveTexture(GL40.GL_TEXTURE0);
|
||||||
|
GL40.glBindTexture(GL11.GL_TEXTURE_2D, blockAtlasTexture.getGlTextureId());
|
||||||
|
|
||||||
|
GL40.glActiveTexture(GL40.GL_TEXTURE0 + 1);
|
||||||
|
GL40.glBindTexture(GL11.GL_TEXTURE_2D, lightTexture.getGlTextureId());
|
||||||
|
RenderSystem.texParameter(3553, 10241, 9729);
|
||||||
|
RenderSystem.texParameter(3553, 10240, 9729);
|
||||||
|
RenderSystem.texParameter(3553, 10242, 10496);
|
||||||
|
RenderSystem.texParameter(3553, 10243, 10496);
|
||||||
|
RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
|
||||||
|
RenderSystem.enableTexture();
|
||||||
|
|
||||||
|
ShaderCallback callback = shader -> {
|
||||||
ShaderHelper.MATRIX_BUFFER.position(0);
|
ShaderHelper.MATRIX_BUFFER.position(0);
|
||||||
event.getProjectionMatrix().write(ShaderHelper.MATRIX_BUFFER);
|
event.getProjectionMatrix().write(ShaderHelper.MATRIX_BUFFER);
|
||||||
|
|
||||||
@ -85,32 +109,22 @@ public class FastKineticRenderer {
|
|||||||
translate.write(ShaderHelper.MATRIX_BUFFER);
|
translate.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);
|
||||||
|
};
|
||||||
|
ShaderHelper.useShader(Shader.ROTATING_INSTANCED, callback);
|
||||||
|
|
||||||
Texture blockAtlasTexture = Minecraft.getInstance().textureManager.getTexture(PlayerContainer.BLOCK_ATLAS_TEXTURE);
|
rotating.values()
|
||||||
Texture lightTexture = Minecraft.getInstance().textureManager.getTexture(lightManager.resourceLocation);
|
.stream()
|
||||||
|
.flatMap(cache -> cache.asMap().values().stream())
|
||||||
|
.filter(type -> !type.isEmpty())
|
||||||
|
.forEach(InstancedBuffer::render);
|
||||||
|
|
||||||
GL40.glActiveTexture(GL40.GL_TEXTURE0);
|
ShaderHelper.useShader(Shader.BELT_INSTANCED, callback);
|
||||||
GL40.glBindTexture(GL11.GL_TEXTURE_2D, blockAtlasTexture.getGlTextureId());
|
|
||||||
|
|
||||||
GL40.glActiveTexture(GL40.GL_TEXTURE0 + 1);
|
belts.values()
|
||||||
GL40.glBindTexture(GL11.GL_TEXTURE_2D, lightTexture.getGlTextureId());
|
.stream()
|
||||||
RenderSystem.texParameter(3553, 10241, 9729);
|
.flatMap(cache -> cache.asMap().values().stream())
|
||||||
RenderSystem.texParameter(3553, 10240, 9729);
|
.filter(type -> !type.isEmpty())
|
||||||
RenderSystem.texParameter(3553, 10242, 10496);
|
.forEach(InstancedBuffer::render);
|
||||||
RenderSystem.texParameter(3553, 10243, 10496);
|
|
||||||
RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
|
|
||||||
RenderSystem.enableTexture();
|
|
||||||
});
|
|
||||||
|
|
||||||
cache.values()
|
|
||||||
.stream()
|
|
||||||
.flatMap(cache -> {
|
|
||||||
ConcurrentMap<Object, InstancedBuffer> map = cache.asMap();
|
|
||||||
|
|
||||||
return map.values().stream();
|
|
||||||
})
|
|
||||||
.filter(type -> !type.isEmpty())
|
|
||||||
.forEach(InstancedBuffer::render);
|
|
||||||
|
|
||||||
ShaderHelper.releaseShader();
|
ShaderHelper.releaseShader();
|
||||||
|
|
||||||
@ -129,29 +143,45 @@ public class FastKineticRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void registerCompartment(SuperByteBufferCache.Compartment<?> instance) {
|
public void registerCompartment(SuperByteBufferCache.Compartment<?> instance) {
|
||||||
cache.put(instance, CacheBuilder.newBuilder().build());
|
rotating.put(instance, CacheBuilder.newBuilder().build());
|
||||||
|
belts.put(instance, CacheBuilder.newBuilder().build());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerCompartment(SuperByteBufferCache.Compartment<?> instance, long ticksUntilExpired) {
|
public void registerCompartment(SuperByteBufferCache.Compartment<?> instance, long ticksUntilExpired) {
|
||||||
cache.put(instance, CacheBuilder.newBuilder().expireAfterAccess(ticksUntilExpired * 50, TimeUnit.MILLISECONDS).build());
|
rotating.put(instance, CacheBuilder.newBuilder().expireAfterAccess(ticksUntilExpired * 50, TimeUnit.MILLISECONDS).build());
|
||||||
|
belts.put(instance, CacheBuilder.newBuilder().expireAfterAccess(ticksUntilExpired * 50, TimeUnit.MILLISECONDS).build());
|
||||||
}
|
}
|
||||||
|
|
||||||
public InstancedBuffer renderPartialInstanced(AllBlockPartials partial, BlockState referenceState) {
|
public RotatingBuffer renderPartialRotating(AllBlockPartials partial, BlockState referenceState) {
|
||||||
return getInstanced(PARTIAL, partial, () -> rotatingInstancedRenderer(partial.get(), referenceState));
|
return getRotating(PARTIAL, partial, () -> rotatingInstancedRenderer(partial.get(), referenceState));
|
||||||
}
|
}
|
||||||
|
|
||||||
public InstancedBuffer renderDirectionalPartialInstanced(AllBlockPartials partial, BlockState referenceState, Direction dir,
|
public BeltBuffer renderPartialBelt(AllBlockPartials partial, BlockState referenceState) {
|
||||||
|
return getBelt(PARTIAL, partial, () -> beltInstancedRenderer(partial.get(), referenceState));
|
||||||
|
}
|
||||||
|
|
||||||
|
public RotatingBuffer renderDirectionalPartialInstanced(AllBlockPartials partial, BlockState referenceState, Direction dir,
|
||||||
MatrixStack modelTransform) {
|
MatrixStack modelTransform) {
|
||||||
return getInstanced(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 InstancedBuffer renderBlockInstanced(SuperByteBufferCache.Compartment<BlockState> compartment, BlockState toRender) {
|
public RotatingBuffer renderBlockInstanced(SuperByteBufferCache.Compartment<BlockState> compartment, BlockState toRender) {
|
||||||
return getInstanced(compartment, toRender, () -> rotatingInstancedRenderer(toRender));
|
return getRotating(compartment, toRender, () -> rotatingInstancedRenderer(toRender));
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> InstancedBuffer getInstanced(SuperByteBufferCache.Compartment<T> compartment, T key, Supplier<InstancedBuffer> supplier) {
|
public <T> RotatingBuffer getRotating(SuperByteBufferCache.Compartment<T> compartment, T key, Supplier<RotatingBuffer> supplier) {
|
||||||
Cache<Object, InstancedBuffer> compartmentCache = this.cache.get(compartment);
|
Cache<Object, RotatingBuffer> compartmentCache = this.rotating.get(compartment);
|
||||||
|
try {
|
||||||
|
return compartmentCache.get(key, supplier::get);
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> BeltBuffer getBelt(SuperByteBufferCache.Compartment<T> compartment, T key, Supplier<BeltBuffer> supplier) {
|
||||||
|
Cache<Object, BeltBuffer> 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) {
|
||||||
@ -161,23 +191,33 @@ public class FastKineticRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private InstancedBuffer rotatingInstancedRenderer(BlockState renderedState) {
|
private RotatingBuffer 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 InstancedBuffer rotatingInstancedRenderer(IBakedModel model, BlockState renderedState) {
|
private RotatingBuffer rotatingInstancedRenderer(IBakedModel model, BlockState renderedState) {
|
||||||
return rotatingInstancedRenderer(model, renderedState, new MatrixStack());
|
return rotatingInstancedRenderer(model, renderedState, new MatrixStack());
|
||||||
}
|
}
|
||||||
|
|
||||||
private InstancedBuffer rotatingInstancedRenderer(IBakedModel model, BlockState referenceState, MatrixStack ms) {
|
private BeltBuffer beltInstancedRenderer(IBakedModel model, BlockState renderedState) {
|
||||||
|
return beltInstancedRenderer(model, renderedState, new MatrixStack());
|
||||||
|
}
|
||||||
|
|
||||||
|
private RotatingBuffer rotatingInstancedRenderer(IBakedModel model, BlockState referenceState, MatrixStack ms) {
|
||||||
BufferBuilder builder = SuperByteBufferCache.getBufferBuilder(model, referenceState, ms);
|
BufferBuilder builder = SuperByteBufferCache.getBufferBuilder(model, referenceState, ms);
|
||||||
|
|
||||||
return new InstancedBuffer(builder);
|
return new RotatingBuffer(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
private BeltBuffer beltInstancedRenderer(IBakedModel model, BlockState referenceState, MatrixStack ms) {
|
||||||
|
BufferBuilder builder = SuperByteBufferCache.getBufferBuilder(model, referenceState, ms);
|
||||||
|
|
||||||
|
return new BeltBuffer(builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void invalidate() {
|
public void invalidate() {
|
||||||
cache.values().forEach(cache -> {
|
rotating.values().forEach(cache -> {
|
||||||
cache.asMap().values().forEach(InstancedBuffer::invalidate);
|
cache.asMap().values().forEach(InstancedBuffer::invalidate);
|
||||||
cache.invalidateAll();
|
cache.invalidateAll();
|
||||||
});
|
});
|
||||||
|
@ -5,10 +5,7 @@ import com.mojang.blaze3d.platform.GlStateManager;
|
|||||||
import com.simibubi.create.CreateClient;
|
import com.simibubi.create.CreateClient;
|
||||||
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.LightTexture;
|
|
||||||
import net.minecraft.client.renderer.Vector3f;
|
|
||||||
import net.minecraft.client.renderer.vertex.VertexFormatElement;
|
import net.minecraft.client.renderer.vertex.VertexFormatElement;
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import org.lwjgl.opengl.*;
|
import org.lwjgl.opengl.*;
|
||||||
|
|
||||||
import java.nio.Buffer;
|
import java.nio.Buffer;
|
||||||
@ -16,12 +13,14 @@ import java.nio.ByteBuffer;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public class InstancedBuffer extends TemplateBuffer {
|
public abstract class InstancedBuffer<T> extends TemplateBuffer {
|
||||||
|
|
||||||
public int vao, ebo, invariantVBO, instanceVBO, instanceCount;
|
protected static ByteBuffer MATRIX_BUF = GLAllocation.createDirectByteBuffer(16 << 2);
|
||||||
|
|
||||||
private final ArrayList<InstanceData> data = new ArrayList<>();
|
protected int vao, ebo, invariantVBO, instanceVBO, instanceCount;
|
||||||
private boolean shouldBuild = true;
|
|
||||||
|
protected final ArrayList<T> data = new ArrayList<>();
|
||||||
|
protected boolean shouldBuild = true;
|
||||||
|
|
||||||
public InstancedBuffer(BufferBuilder buf) {
|
public InstancedBuffer(BufferBuilder buf) {
|
||||||
super(buf);
|
super(buf);
|
||||||
@ -113,166 +112,52 @@ public class InstancedBuffer extends TemplateBuffer {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setupInstance(Consumer<InstanceData> setup) {
|
protected void addData(T instance) {
|
||||||
|
data.add(instance);
|
||||||
|
instanceCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract T newInstance();
|
||||||
|
|
||||||
|
protected abstract int numAttributes();
|
||||||
|
|
||||||
|
public void setupInstance(Consumer<T> setup) {
|
||||||
if (!shouldBuild) return;
|
if (!shouldBuild) return;
|
||||||
|
|
||||||
InstanceData instanceData = new InstanceData();
|
T instanceData = newInstance();
|
||||||
setup.accept(instanceData);
|
setup.accept(instanceData);
|
||||||
|
|
||||||
data.add(instanceData);
|
addData(instanceData);
|
||||||
instanceCount++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void render() {
|
public void render() {
|
||||||
|
|
||||||
GL30.glBindVertexArray(vao);
|
GL30.glBindVertexArray(vao);
|
||||||
if (finishBuffering()) {
|
finishBuffering();
|
||||||
|
|
||||||
for (int i = 0; i <= 8; i++) {
|
for (int i = 0; i <= 10; i++) {
|
||||||
GL40.glEnableVertexAttribArray(i);
|
GL40.glEnableVertexAttribArray(i);
|
||||||
}
|
|
||||||
|
|
||||||
GlStateManager.bindBuffers(GL15.GL_ELEMENT_ARRAY_BUFFER, ebo);
|
|
||||||
|
|
||||||
GL40.glDrawElementsInstanced(GL11.GL_QUADS, count, GL11.GL_UNSIGNED_SHORT, 0, instanceCount);
|
|
||||||
|
|
||||||
for (int i = 0; i <= 8; i++) {
|
|
||||||
GL40.glDisableVertexAttribArray(i);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GlStateManager.bindBuffers(GL15.GL_ELEMENT_ARRAY_BUFFER, ebo);
|
||||||
|
|
||||||
|
GL40.glDrawElementsInstanced(GL11.GL_QUADS, count, GL11.GL_UNSIGNED_SHORT, 0, instanceCount);
|
||||||
|
|
||||||
|
for (int i = 0; i <= 10; i++) {
|
||||||
|
GL40.glDisableVertexAttribArray(i);
|
||||||
|
}
|
||||||
|
|
||||||
GL30.glBindVertexArray(0);
|
GL30.glBindVertexArray(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean finishBuffering() {
|
private void finishBuffering() {
|
||||||
if (!shouldBuild) return true;
|
if (!shouldBuild) return;
|
||||||
|
|
||||||
int floatSize = VertexFormatElement.Type.FLOAT.getSize();
|
finishBufferingInternal();
|
||||||
int intSize = VertexFormatElement.Type.INT.getSize();
|
|
||||||
int stride = floatSize * 10 + intSize * 2;
|
|
||||||
|
|
||||||
int instanceSize = data.size() * stride;
|
|
||||||
|
|
||||||
if (instanceSize == 0) return false;
|
|
||||||
|
|
||||||
ByteBuffer buffer = GLAllocation.createDirectByteBuffer(instanceSize);
|
|
||||||
buffer.order(template.order());
|
|
||||||
((Buffer) buffer).limit(instanceSize);
|
|
||||||
|
|
||||||
data.forEach(instanceData -> instanceData.buffer(buffer));
|
|
||||||
buffer.rewind();
|
|
||||||
|
|
||||||
GlStateManager.bindBuffers(GL15.GL_ARRAY_BUFFER, instanceVBO);
|
|
||||||
GlStateManager.bufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
|
|
||||||
|
|
||||||
// the render position
|
|
||||||
GL20.glVertexAttribPointer(3, 3, GL11.GL_FLOAT, false, stride, 0);
|
|
||||||
|
|
||||||
// vertex lighting
|
|
||||||
GL20.glVertexAttribPointer(4, 2, GL11.GL_FLOAT, false, stride, floatSize * 3L);
|
|
||||||
|
|
||||||
// rotational speed and offset
|
|
||||||
GL20.glVertexAttribPointer(5, 1, GL11.GL_FLOAT, false, stride, floatSize * 5L);
|
|
||||||
GL20.glVertexAttribPointer(6, 1, GL11.GL_FLOAT, false, stride, floatSize * 6L);
|
|
||||||
// rotation axis
|
|
||||||
GL20.glVertexAttribPointer(7, 3, GL11.GL_FLOAT, false, stride, floatSize * 7L);
|
|
||||||
// uv scrolling
|
|
||||||
GL20.glVertexAttribPointer(8, 2, GL11.GL_INT, false, stride, floatSize * 10L);
|
|
||||||
|
|
||||||
for (int i = 3; i <= 8; i++) {
|
|
||||||
GL40.glVertexAttribDivisor(i, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deselect (bind to 0) the VBO
|
|
||||||
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
|
|
||||||
|
|
||||||
shouldBuild = false;
|
shouldBuild = false;
|
||||||
data.clear();
|
data.clear();
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class InstanceData {
|
protected abstract void finishBufferingInternal();
|
||||||
private float x;
|
|
||||||
private float y;
|
|
||||||
private float z;
|
|
||||||
private int packedLight = 0;
|
|
||||||
private float rotationalSpeed;
|
|
||||||
private float rotationOffset;
|
|
||||||
private float rotationAxisX;
|
|
||||||
private float rotationAxisY;
|
|
||||||
private float rotationAxisZ;
|
|
||||||
private int cycleLength;
|
|
||||||
private int cycleOffset;
|
|
||||||
|
|
||||||
public InstanceData setPackedLight(int packedLight) {
|
|
||||||
this.packedLight = packedLight;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public InstanceData setRotationalSpeed(float rotationalSpeed) {
|
|
||||||
this.rotationalSpeed = rotationalSpeed;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public InstanceData setRotationOffset(float rotationOffset) {
|
|
||||||
this.rotationOffset = rotationOffset;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public InstanceData setPosition(Vector3f pos) {
|
|
||||||
this.x = pos.getX();
|
|
||||||
this.y = pos.getY();
|
|
||||||
this.z = pos.getZ();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public InstanceData setPosition(BlockPos pos) {
|
|
||||||
this.x = pos.getX();
|
|
||||||
this.y = pos.getY();
|
|
||||||
this.z = pos.getZ();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public InstanceData setRotationAxis(Vector3f axis) {
|
|
||||||
this.rotationAxisX = axis.getX();
|
|
||||||
this.rotationAxisY = axis.getY();
|
|
||||||
this.rotationAxisZ = axis.getZ();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public InstanceData setRotationAxis(float rotationAxisX, float rotationAxisY, float rotationAxisZ) {
|
|
||||||
this.rotationAxisX = rotationAxisX;
|
|
||||||
this.rotationAxisY = rotationAxisY;
|
|
||||||
this.rotationAxisZ = rotationAxisZ;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public InstanceData setCycleLength(int cycleLength) {
|
|
||||||
this.cycleLength = cycleLength;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public InstanceData setCycleOffset(int cycleOffset) {
|
|
||||||
this.cycleOffset = cycleOffset;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
void buffer(ByteBuffer buf) {
|
|
||||||
float blockLightCoordinates = LightTexture.getBlockLightCoordinates(packedLight) / (float) 0xF;
|
|
||||||
float skyLightCoordinates = LightTexture.getSkyLightCoordinates(packedLight) / (float) 0xF;
|
|
||||||
|
|
||||||
buf.putFloat(x);
|
|
||||||
buf.putFloat(y);
|
|
||||||
buf.putFloat(z);
|
|
||||||
buf.putFloat(blockLightCoordinates);
|
|
||||||
buf.putFloat(skyLightCoordinates);
|
|
||||||
buf.putFloat(rotationalSpeed);
|
|
||||||
buf.putFloat(rotationOffset);
|
|
||||||
buf.putFloat(rotationAxisX);
|
|
||||||
buf.putFloat(rotationAxisY);
|
|
||||||
buf.putFloat(rotationAxisZ);
|
|
||||||
buf.putInt(cycleLength);
|
|
||||||
buf.putInt(cycleOffset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,143 @@
|
|||||||
|
package com.simibubi.create.foundation.utility.render;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
|
import com.simibubi.create.foundation.block.render.SpriteShiftEntry;
|
||||||
|
import net.minecraft.client.renderer.BufferBuilder;
|
||||||
|
import net.minecraft.client.renderer.GLAllocation;
|
||||||
|
import net.minecraft.client.renderer.LightTexture;
|
||||||
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||||
|
import net.minecraft.client.renderer.vertex.VertexFormatElement;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.vector.Vector3f;
|
||||||
|
import org.lwjgl.opengl.GL11;
|
||||||
|
import org.lwjgl.opengl.GL15;
|
||||||
|
import org.lwjgl.opengl.GL20;
|
||||||
|
import org.lwjgl.opengl.GL40;
|
||||||
|
|
||||||
|
import java.nio.Buffer;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
public class RotatingBuffer extends InstancedBuffer<RotatingBuffer.InstanceData> {
|
||||||
|
public RotatingBuffer(BufferBuilder buf) {
|
||||||
|
super(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected InstanceData newInstance() {
|
||||||
|
return new InstanceData();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int numAttributes() {
|
||||||
|
return 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void finishBufferingInternal() {
|
||||||
|
int floatSize = VertexFormatElement.Type.FLOAT.getSize();
|
||||||
|
int stride = floatSize * 10;
|
||||||
|
|
||||||
|
int instanceSize = instanceCount * stride;
|
||||||
|
|
||||||
|
ByteBuffer buffer = GLAllocation.createDirectByteBuffer(instanceSize);
|
||||||
|
buffer.order(template.order());
|
||||||
|
((Buffer) buffer).limit(instanceSize);
|
||||||
|
|
||||||
|
data.forEach(instanceData -> instanceData.buffer(buffer));
|
||||||
|
buffer.rewind();
|
||||||
|
|
||||||
|
GlStateManager.bindBuffers(GL15.GL_ARRAY_BUFFER, instanceVBO);
|
||||||
|
GlStateManager.bufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
// the render position
|
||||||
|
GL20.glVertexAttribPointer(3, 3, GL11.GL_FLOAT, false, stride, 0);
|
||||||
|
|
||||||
|
// vertex lighting
|
||||||
|
GL20.glVertexAttribPointer(4, 2, GL11.GL_FLOAT, false, stride, floatSize * 3L);
|
||||||
|
|
||||||
|
// rotational speed and offset
|
||||||
|
GL20.glVertexAttribPointer(5, 1, GL11.GL_FLOAT, false, stride, floatSize * 5L);
|
||||||
|
GL20.glVertexAttribPointer(6, 1, GL11.GL_FLOAT, false, stride, floatSize * 6L);
|
||||||
|
// rotation axis
|
||||||
|
GL20.glVertexAttribPointer(7, 3, GL11.GL_FLOAT, false, stride, floatSize * 7L);
|
||||||
|
|
||||||
|
for (int i = 3; i <= numAttributes(); i++) {
|
||||||
|
GL40.glVertexAttribDivisor(i, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deselect (bind to 0) the VBO
|
||||||
|
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class InstanceData {
|
||||||
|
private float x;
|
||||||
|
private float y;
|
||||||
|
private float z;
|
||||||
|
private int packedLight;
|
||||||
|
private float rotationalSpeed;
|
||||||
|
private float rotationOffset;
|
||||||
|
private float rotationAxisX;
|
||||||
|
private float rotationAxisY;
|
||||||
|
private float rotationAxisZ;
|
||||||
|
|
||||||
|
public InstanceData setPackedLight(int packedLight) {
|
||||||
|
this.packedLight = packedLight;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public InstanceData setRotationalSpeed(float rotationalSpeed) {
|
||||||
|
this.rotationalSpeed = rotationalSpeed;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public InstanceData setRotationOffset(float rotationOffset) {
|
||||||
|
this.rotationOffset = rotationOffset;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public InstanceData setPosition(Vector3f pos) {
|
||||||
|
this.x = pos.getX();
|
||||||
|
this.y = pos.getY();
|
||||||
|
this.z = pos.getZ();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public InstanceData setPosition(BlockPos pos) {
|
||||||
|
this.x = pos.getX();
|
||||||
|
this.y = pos.getY();
|
||||||
|
this.z = pos.getZ();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public InstanceData setRotationAxis(Vector3f axis) {
|
||||||
|
this.rotationAxisX = axis.getX();
|
||||||
|
this.rotationAxisY = axis.getY();
|
||||||
|
this.rotationAxisZ = axis.getZ();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public InstanceData setRotationAxis(float rotationAxisX, float rotationAxisY, float rotationAxisZ) {
|
||||||
|
this.rotationAxisX = rotationAxisX;
|
||||||
|
this.rotationAxisY = rotationAxisY;
|
||||||
|
this.rotationAxisZ = rotationAxisZ;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void buffer(ByteBuffer buf) {
|
||||||
|
float blockLightCoordinates = LightTexture.getBlockLightCoordinates(packedLight) / (float) 0xF;
|
||||||
|
float skyLightCoordinates = LightTexture.getSkyLightCoordinates(packedLight) / (float) 0xF;
|
||||||
|
|
||||||
|
buf.putFloat(x);
|
||||||
|
buf.putFloat(y);
|
||||||
|
buf.putFloat(z);
|
||||||
|
buf.putFloat(blockLightCoordinates);
|
||||||
|
buf.putFloat(skyLightCoordinates);
|
||||||
|
buf.putFloat(rotationalSpeed);
|
||||||
|
buf.putFloat(rotationOffset);
|
||||||
|
buf.putFloat(rotationAxisX);
|
||||||
|
buf.putFloat(rotationAxisY);
|
||||||
|
buf.putFloat(rotationAxisZ);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,8 @@
|
|||||||
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/instanced.vert", "shader/instanced.frag");
|
ROTATING_INSTANCED("shader/rotating.vert", "shader/instanced.frag"),
|
||||||
|
BELT_INSTANCED("shader/belt.vert", "shader/instanced.frag"),;
|
||||||
|
|
||||||
public final String vert;
|
public final String vert;
|
||||||
public final String frag;
|
public final String frag;
|
||||||
|
35
src/main/resources/assets/create/shader/belt.vert
Normal file
35
src/main/resources/assets/create/shader/belt.vert
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#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 mat4 model;
|
||||||
|
layout (location = 8) in vec2 light;
|
||||||
|
layout (location = 9) in float speed;
|
||||||
|
|
||||||
|
out vec2 TexCoords;
|
||||||
|
out vec2 Light;
|
||||||
|
|
||||||
|
uniform float time;
|
||||||
|
uniform int ticks;
|
||||||
|
uniform mat4 projection;
|
||||||
|
uniform mat4 view;
|
||||||
|
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
// float textureIndex = fract((speed * time / 36 + cycle[1]) / cycle[0]) * cycle[0];
|
||||||
|
// if (textureIndex < 0) {
|
||||||
|
// textureIndex += cycle[0];
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// vec2 scrollPos = vec2(fract(textureIndex / 4), floor(textureIndex / 16));
|
||||||
|
|
||||||
|
vec4 renderPos = model * vec4(aPos - vec3(0.5), 1f);
|
||||||
|
renderPos += vec4(instancePos + vec3(0.5), 0);
|
||||||
|
|
||||||
|
TexCoords = aTexCoords;
|
||||||
|
gl_Position = projection * view * renderPos;
|
||||||
|
}
|
@ -9,7 +9,6 @@ layout (location = 4) in vec2 light;
|
|||||||
layout (location = 5) in float speed;
|
layout (location = 5) in float speed;
|
||||||
layout (location = 6) in float rotationOffset;
|
layout (location = 6) in float rotationOffset;
|
||||||
layout (location = 7) in vec3 rotationAxis;
|
layout (location = 7) in vec3 rotationAxis;
|
||||||
layout (location = 8) in int[2] uvScroll; // uvScroll[0] <- cycleLength, uvScroll[1] <- cycleOffset
|
|
||||||
|
|
||||||
out vec2 TexCoords;
|
out vec2 TexCoords;
|
||||||
out vec2 Light;
|
out vec2 Light;
|
||||||
@ -19,9 +18,12 @@ uniform int ticks;
|
|||||||
uniform mat4 projection;
|
uniform mat4 projection;
|
||||||
uniform mat4 view;
|
uniform mat4 view;
|
||||||
|
|
||||||
mat4 rotationMatrix(vec3 axis, float angle)
|
mat4 kineticRotation()
|
||||||
{
|
{
|
||||||
axis = normalize(axis);
|
float degrees = rotationOffset + time * speed * -3./10.;
|
||||||
|
float angle = fract(degrees / 360.) * PI * 2.;
|
||||||
|
|
||||||
|
vec3 axis = normalize(rotationAxis);
|
||||||
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;
|
||||||
@ -34,26 +36,11 @@ mat4 rotationMatrix(vec3 axis, float angle)
|
|||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
vec4 renderPos;
|
vec4 renderPos = kineticRotation() * vec4(aPos - vec3(0.5), 1);
|
||||||
int textureIndex = 0;
|
|
||||||
if (abs(rotationAxis.x) + abs(rotationAxis.y) + abs(rotationAxis.z) < 0.2) {
|
|
||||||
renderPos = vec4(aPos + instancePos, 1f);
|
|
||||||
|
|
||||||
textureIndex = int((speed * time / 36) + uvScroll[1]) % uvScroll[0];
|
renderPos += vec4(instancePos + vec3(0.5), 0);
|
||||||
if (textureIndex < 0) {
|
|
||||||
textureIndex += uvScroll[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
TexCoords = aTexCoords;
|
||||||
float degrees = rotationOffset + time * speed * 3./10.;
|
|
||||||
float angle = fract(-degrees / 360.) * PI * 2.;
|
|
||||||
|
|
||||||
renderPos = rotationMatrix(rotationAxis, angle) * vec4(aPos - vec3(0.5), 1f);
|
|
||||||
|
|
||||||
renderPos += vec4(instancePos + vec3(0.5), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
TexCoords = aTexCoords + vec2(float(textureIndex % 4) / 4f, float(textureIndex / 4) / 4f);
|
|
||||||
|
|
||||||
gl_Position = projection * view * renderPos;
|
gl_Position = projection * view * renderPos;
|
||||||
Light = light;
|
Light = light;
|
Loading…
Reference in New Issue
Block a user