An absolutely ridiculous amount of refactoring. Shader system got a complete makeover, but still needs a little work.

Objective was GL compatibility, now runs with 3.3, 2.0 is target.
Remove old tile rendering code. Need to bring back old old (vanilla) tile rendering code.
This commit is contained in:
JozsefA 2021-02-03 23:21:10 -08:00
parent b766658415
commit 8c0e983f36
88 changed files with 915 additions and 1133 deletions

View File

@ -1,11 +1,9 @@
package com.simibubi.create;
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.processing.burner.BlazeBurnerBlock.HeatLevel;
import com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity;
import com.simibubi.create.foundation.render.InstancedTileRenderer;
import com.simibubi.create.foundation.render.instancing.InstancedTileRenderer;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.render.instancing.*;
import com.simibubi.create.foundation.utility.AngleHelper;
@ -222,41 +220,20 @@ public class AllBlockPartials {
return CreateClient.bufferCache.renderDirectionalPartial(this, referenceState, facing, ms);
}
@Deprecated
public <T extends KineticTileEntity> InstancedModel<RotatingData> renderOnRotating(InstanceContext<T> ctx, BlockState referenceState) {
return ctx.getRotating().getModel(this, referenceState);
public InstancedModel<RotatingData> renderOnRotating(InstancedTileRenderer<?> ctx, BlockState referenceState) {
return ctx.getMaterial(KineticRenderMaterials.ROTATING).getModel(this, referenceState);
}
public InstancedModel<RotatingData> renderOnRotating(InstancedTileRenderer ctx, BlockState referenceState) {
return ctx.get(KineticRenderMaterials.ROTATING).getModel(this, referenceState);
public InstancedModel<BeltData> renderOnBelt(InstancedTileRenderer<?> ctx, BlockState referenceState) {
return ctx.getMaterial(KineticRenderMaterials.BELTS).getModel(this, referenceState);
}
@Deprecated
public <T extends BeltTileEntity> InstancedModel<BeltData> renderOnBelt(InstanceContext<T> ctx, BlockState referenceState) {
return ctx.getBelts().getModel(this, referenceState);
}
public InstancedModel<BeltData> renderOnBelt(InstancedTileRenderer ctx, BlockState referenceState) {
return ctx.get(KineticRenderMaterials.BELTS).getModel(this, referenceState);
}
@Deprecated
public <T extends KineticTileEntity> InstancedModel<RotatingData> renderOnDirectionalSouthRotating(InstanceContext<T> ctx, BlockState referenceState) {
Direction facing = referenceState.get(FACING);
return renderOnDirectionalSouthRotating(ctx, referenceState, facing);
}
public InstancedModel<RotatingData> renderOnDirectionalSouthRotating(InstancedTileRenderer dispatcher, BlockState referenceState) {
public InstancedModel<RotatingData> renderOnDirectionalSouthRotating(InstancedTileRenderer<?> dispatcher, BlockState referenceState) {
Direction facing = referenceState.get(FACING);
return renderOnDirectionalSouthRotating(dispatcher, referenceState, facing);
}
@Deprecated
public <T extends KineticTileEntity> InstancedModel<RotatingData> renderOnDirectionalSouthRotating(InstanceContext<T> ctx, BlockState referenceState, Direction facing) {
return renderOnDirectionalSouthRotating(ctx.getKinetics(), referenceState, facing);
}
public InstancedModel<RotatingData> renderOnDirectionalSouthRotating(InstancedTileRenderer dispatcher, BlockState referenceState, Direction facing) {
public InstancedModel<RotatingData> renderOnDirectionalSouthRotating(InstancedTileRenderer<?> dispatcher, BlockState referenceState, Direction facing) {
Supplier<MatrixStack> ms = () -> {
MatrixStack stack = new MatrixStack();
MatrixStacker.of(stack)
@ -266,7 +243,7 @@ public class AllBlockPartials {
.unCentre();
return stack;
};
return dispatcher.get(KineticRenderMaterials.ROTATING).getModel(this, referenceState, facing, ms);
return dispatcher.getMaterial(KineticRenderMaterials.ROTATING).getModel(this, referenceState, facing, ms);
}
}

View File

@ -11,7 +11,7 @@ import com.simibubi.create.foundation.block.render.CustomBlockModels;
import com.simibubi.create.foundation.block.render.SpriteShifter;
import com.simibubi.create.foundation.item.CustomItemModels;
import com.simibubi.create.foundation.item.CustomRenderedItems;
import com.simibubi.create.foundation.render.InstancedTileRenderer;
import com.simibubi.create.foundation.render.KineticRenderer;
import com.simibubi.create.foundation.render.SuperByteBufferCache;
import com.simibubi.create.foundation.render.contraption.ContraptionRenderDispatcher;
import com.simibubi.create.foundation.render.gl.shader.ShaderHelper;
@ -44,7 +44,7 @@ public class CreateClient {
public static SchematicHandler schematicHandler;
public static SchematicAndQuillHandler schematicAndQuillHandler;
public static SuperByteBufferCache bufferCache;
public static InstancedTileRenderer kineticRenderer;
public static KineticRenderer kineticRenderer;
public static final Outliner outliner = new Outliner();
private static CustomBlockModels customBlockModels;
@ -72,7 +72,7 @@ public class CreateClient {
bufferCache.registerCompartment(KineticTileEntityRenderer.KINETIC_TILE);
bufferCache.registerCompartment(ContraptionRenderer.CONTRAPTION, 20);
kineticRenderer = new InstancedTileRenderer();
kineticRenderer = new KineticRenderer();
AllKeys.register();
AllContainerTypes.registerScreenFactories();

View File

@ -1,6 +1,6 @@
package com.simibubi.create.content.contraptions.base;
import com.simibubi.create.foundation.render.InstancedTileRenderer;
import com.simibubi.create.foundation.render.instancing.InstancedTileRenderer;
import com.simibubi.create.foundation.render.instancing.InstancedTileRenderRegistry;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.tileentity.TileEntityType;

View File

@ -1,7 +1,7 @@
package com.simibubi.create.content.contraptions.base;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.foundation.render.InstancedTileRenderer;
import com.simibubi.create.foundation.render.instancing.InstancedTileRenderer;
import com.simibubi.create.foundation.render.instancing.InstancedModel;
import com.simibubi.create.foundation.render.instancing.InstancedTileRenderRegistry;
import com.simibubi.create.foundation.render.instancing.RotatingData;

View File

@ -1,6 +1,6 @@
package com.simibubi.create.content.contraptions.base;
import com.simibubi.create.foundation.render.InstancedTileRenderer;
import com.simibubi.create.foundation.render.instancing.InstancedTileRenderer;
import com.simibubi.create.foundation.render.instancing.InstancedTileRenderRegistry;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.tileentity.TileEntityType;

View File

@ -6,7 +6,6 @@ import com.simibubi.create.content.contraptions.KineticDebugger;
import com.simibubi.create.content.contraptions.relays.elementary.CogWheelBlock;
import com.simibubi.create.foundation.render.Compartment;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.render.instancing.InstanceContext;
import com.simibubi.create.foundation.render.instancing.InstancedModel;
import com.simibubi.create.foundation.render.instancing.RotatingData;
import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer;
@ -44,42 +43,6 @@ public class KineticTileEntityRenderer extends SafeTileEntityRenderer<KineticTil
// addInstanceData(new InstanceContext.World<>(te));
}
public void addInstanceData(InstanceContext<KineticTileEntity> ctx) {
renderRotatingBuffer(ctx, getRotatedModel(ctx));
}
public void markForRebuild(InstanceContext<KineticTileEntity> ctx) {
getRotatedModel(ctx).clearInstanceData();
}
public static <T extends KineticTileEntity> void renderRotatingKineticBlock(InstanceContext<T> ctx, BlockState renderedState) {
InstancedModel<RotatingData> instancedRenderer = ctx.getRotating().getModel(KINETIC_TILE, renderedState);
renderRotatingBuffer(ctx, instancedRenderer);
}
public static <T extends KineticTileEntity> void markForRebuild(InstanceContext<T> ctx, BlockState renderedState) {
ctx.getRotating().getModel(KINETIC_TILE, renderedState).clearInstanceData();
}
public static <T extends KineticTileEntity> void renderRotatingBuffer(InstanceContext<T> ctx, InstancedModel<RotatingData> instancer) {
instancer.setupInstance(data -> {
T te = ctx.te;
final BlockPos pos = te.getPos();
Axis axis = ((IRotate) te.getBlockState()
.getBlock()).getRotationAxis(te.getBlockState());
data.setRotationalSpeed(te.getSpeed())
.setRotationOffset(getRotationOffsetForPosition(te, pos, axis))
.setRotationAxis(Direction.getFacingFromAxis(AxisDirection.POSITIVE, axis).getUnitVector())
.setTileEntity(te);
if (ctx.checkWorldLight()) {
data.setBlockLight(te.getWorld().getLightLevel(LightType.BLOCK, te.getPos()))
.setSkyLight(te.getWorld().getLightLevel(LightType.SKY, te.getPos()));
}
});
}
public static float getAngleForTe(KineticTileEntity te, final BlockPos pos, Axis axis) {
float time = AnimationTickHolder.getRenderTick();
float offset = getRotationOffsetForPosition(te, pos, axis);
@ -142,8 +105,5 @@ public class KineticTileEntityRenderer extends SafeTileEntityRenderer<KineticTil
return te.getBlockState();
}
protected InstancedModel<RotatingData> getRotatedModel(InstanceContext<? extends KineticTileEntity> ctx) {
return ctx.getRotating().getModel(KINETIC_TILE, getRenderedBlockState(ctx.te));
}
}

View File

@ -3,7 +3,7 @@ package com.simibubi.create.content.contraptions.base;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.content.contraptions.relays.elementary.CogWheelBlock;
import com.simibubi.create.content.contraptions.relays.elementary.ShaftBlock;
import com.simibubi.create.foundation.render.InstancedTileRenderer;
import com.simibubi.create.foundation.render.instancing.InstancedTileRenderer;
import com.simibubi.create.foundation.render.instancing.*;
import net.minecraft.block.BlockState;
import net.minecraft.util.Direction;
@ -13,7 +13,7 @@ import java.util.function.Consumer;
public abstract class KineticTileInstance<T extends KineticTileEntity> extends TileEntityInstance<T> {
public KineticTileInstance(InstancedTileRenderer modelManager, T tile) {
public KineticTileInstance(InstancedTileRenderer<?> modelManager, T tile) {
super(modelManager, tile);
}
@ -60,7 +60,7 @@ public abstract class KineticTileInstance<T extends KineticTileEntity> extends T
return ((IRotate) lastState.getBlock()).getRotationAxis(lastState);
}
protected final RenderMaterial<InstancedModel<RotatingData>> rotatingMaterial() {
return modelManager.get(KineticRenderMaterials.ROTATING);
protected final RenderMaterial<?, InstancedModel<RotatingData>> rotatingMaterial() {
return modelManager.getMaterial(KineticRenderMaterials.ROTATING);
}
}

View File

@ -1,7 +1,7 @@
package com.simibubi.create.content.contraptions.base;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.foundation.render.InstancedTileRenderer;
import com.simibubi.create.foundation.render.instancing.InstancedTileRenderer;
import com.simibubi.create.foundation.render.instancing.InstancedModel;
import com.simibubi.create.foundation.render.instancing.InstancedTileRenderRegistry;
import com.simibubi.create.foundation.render.instancing.RotatingData;

View File

@ -1,6 +1,6 @@
package com.simibubi.create.content.contraptions.base;
import com.simibubi.create.foundation.render.InstancedTileRenderer;
import com.simibubi.create.foundation.render.instancing.InstancedTileRenderer;
import com.simibubi.create.foundation.render.instancing.InstanceKey;
import com.simibubi.create.foundation.render.instancing.InstancedModel;
import com.simibubi.create.foundation.render.instancing.InstancedTileRenderRegistry;

View File

@ -3,7 +3,7 @@ package com.simibubi.create.content.contraptions.components.actors;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.base.SingleRotatingInstance;
import com.simibubi.create.foundation.render.InstancedTileRenderer;
import com.simibubi.create.foundation.render.instancing.InstancedTileRenderer;
import com.simibubi.create.foundation.render.instancing.InstancedModel;
import com.simibubi.create.foundation.render.instancing.InstancedTileRenderRegistry;
import com.simibubi.create.foundation.render.instancing.RotatingData;

View File

@ -6,11 +6,10 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.render.contraption.ContraptionProgram;
import com.simibubi.create.foundation.render.contraption.RenderedContraption;
import com.simibubi.create.foundation.render.instancing.InstanceContext;
import com.simibubi.create.foundation.render.instancing.InstancedModel;
import com.simibubi.create.foundation.render.instancing.RenderMaterial;
import com.simibubi.create.foundation.render.instancing.RotatingData;
import com.simibubi.create.foundation.render.instancing.actors.StaticRotatingActorData;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
@ -31,17 +30,12 @@ public class DrillRenderer extends KineticTileEntityRenderer {
super(dispatcher);
}
@Override
protected InstancedModel<RotatingData> getRotatedModel(InstanceContext<? extends KineticTileEntity> ctx) {
return AllBlockPartials.DRILL_HEAD.renderOnDirectionalSouthRotating(ctx, ctx.te.getBlockState());
}
protected static SuperByteBuffer getRotatingModel(BlockState state) {
return AllBlockPartials.DRILL_HEAD.renderOnDirectionalSouth(state);
}
public static void addInstanceForContraption(RenderedContraption contraption, MovementContext context) {
RenderMaterial<InstancedModel<StaticRotatingActorData>> renderMaterial = contraption.getActorMaterial();
RenderMaterial<?, InstancedModel<StaticRotatingActorData>> renderMaterial = contraption.getActorMaterial();
BlockState state = context.state;
InstancedModel<StaticRotatingActorData> model = renderMaterial.getModel(AllBlockPartials.DRILL_HEAD, state);

View File

@ -40,7 +40,7 @@ public class HarvesterRenderer extends SafeTileEntityRenderer<HarvesterTileEntit
}
public static void addInstanceForContraption(RenderedContraption contraption, MovementContext context) {
RenderMaterial<InstancedModel<StaticRotatingActorData>> renderMaterial = contraption.getActorMaterial();
RenderMaterial<?, InstancedModel<StaticRotatingActorData>> renderMaterial = contraption.getActorMaterial();
BlockState state = context.state;
InstancedModel<StaticRotatingActorData> model = renderMaterial.getModel(AllBlockPartials.HARVESTER_BLADE, state);

View File

@ -7,7 +7,6 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.content.contraptions.components.clock.CuckooClockTileEntity.Animation;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.render.instancing.InstanceContext;
import com.simibubi.create.foundation.render.instancing.InstancedModel;
import com.simibubi.create.foundation.render.instancing.RotatingData;
import com.simibubi.create.foundation.utility.AngleHelper;
@ -91,12 +90,6 @@ public class CuckooClockRenderer extends KineticTileEntityRenderer {
}
@Override
protected InstancedModel<RotatingData> getRotatedModel(InstanceContext<? extends KineticTileEntity> ctx) {
BlockState blockState = ctx.te.getBlockState();
return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(ctx, blockState, blockState.get(CuckooClockBlock.HORIZONTAL_FACING).getOpposite());
}
private SuperByteBuffer rotateHand(SuperByteBuffer buffer, float angle, Direction facing) {
float pivotX = 2 / 16f;
float pivotY = 6 / 16f;

View File

@ -4,7 +4,7 @@ import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.base.SingleRotatingInstance;
import com.simibubi.create.foundation.render.InstancedTileRenderer;
import com.simibubi.create.foundation.render.instancing.InstancedTileRenderer;
import com.simibubi.create.foundation.render.instancing.InstancedModel;
import com.simibubi.create.foundation.render.instancing.InstancedTileRenderRegistry;
import com.simibubi.create.foundation.render.instancing.RotatingData;

View File

@ -9,7 +9,6 @@ import com.simibubi.create.content.contraptions.components.deployer.DeployerTile
import com.simibubi.create.content.contraptions.components.deployer.DeployerTileEntity.State;
import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.render.instancing.InstanceContext;
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringRenderer;
import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer;
import com.simibubi.create.foundation.utility.AngleHelper;
@ -52,14 +51,6 @@ public class DeployerRenderer extends SafeTileEntityRenderer<DeployerTileEntity>
}
public void addInstanceData(InstanceContext<DeployerTileEntity> ctx) {
KineticTileEntityRenderer.renderRotatingKineticBlock(ctx, getRenderedBlockState(ctx.te));
}
public void markForRebuild(InstanceContext<DeployerTileEntity> ctx) {
KineticTileEntityRenderer.markForRebuild(ctx, getRenderedBlockState(ctx.te));
}
protected void renderItem(DeployerTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer,
int light, int overlay) {
BlockState deployerState = te.getBlockState();

View File

@ -5,7 +5,6 @@ import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.base.IRotate;
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.foundation.render.instancing.InstanceContext;
import com.simibubi.create.foundation.render.instancing.InstancedModel;
import com.simibubi.create.foundation.render.instancing.RotatingData;
import net.minecraft.client.renderer.IRenderTypeBuffer;
@ -29,74 +28,4 @@ public class EncasedFanRenderer extends KineticTileEntityRenderer {
super.renderSafe(te, partialTicks, ms, buffer, light, overlay);
}
@Override
public void addInstanceData(InstanceContext<KineticTileEntity> ctx) {
KineticTileEntity te = ctx.te;
Direction direction = te.getBlockState()
.get(FACING);
InstancedModel<RotatingData> shaftHalf =
AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(ctx, te.getBlockState(), direction.getOpposite());
InstancedModel<RotatingData> fanInner =
AllBlockPartials.ENCASED_FAN_INNER.renderOnDirectionalSouthRotating(ctx, te.getBlockState(), direction.getOpposite());
shaftHalf.setupInstance(data -> {
final BlockPos pos = te.getPos();
Direction.Axis axis = ((IRotate) te.getBlockState()
.getBlock()).getRotationAxis(te.getBlockState());
data.setRotationalSpeed(te.getSpeed())
.setRotationOffset(getRotationOffsetForPosition(te, pos, axis))
.setRotationAxis(Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis).getUnitVector())
.setTileEntity(te);
if (ctx.checkWorldLight()) {
BlockPos behind = te.getPos().offset(direction.getOpposite());
int blockLight = te.getWorld().getLightLevel(LightType.BLOCK, behind);
int skyLight = te.getWorld().getLightLevel(LightType.SKY, behind);
data.setBlockLight(blockLight)
.setSkyLight(skyLight);
}
});
fanInner.setupInstance(data -> {
final BlockPos pos = te.getPos();
Direction.Axis axis = ((IRotate) te.getBlockState()
.getBlock()).getRotationAxis(te.getBlockState());
float speed = te.getSpeed() * 5;
if (speed > 0)
speed = MathHelper.clamp(speed, 80, 64 * 20);
if (speed < 0)
speed = MathHelper.clamp(speed, -64 * 20, -80);
data.setRotationalSpeed(speed)
.setRotationOffset(getRotationOffsetForPosition(te, pos, axis))
.setRotationAxis(Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis).getUnitVector())
.setTileEntity(te);
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);
}
});
}
@Override
public void markForRebuild(InstanceContext<KineticTileEntity> ctx) {
KineticTileEntity te = ctx.te;
Direction direction = te.getBlockState()
.get(FACING);
InstancedModel<RotatingData> shaftHalf =
AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(ctx, te.getBlockState(), direction.getOpposite());
InstancedModel<RotatingData> fanInner =
AllBlockPartials.ENCASED_FAN_INNER.renderOnDirectionalSouthRotating(ctx, te.getBlockState(), direction.getOpposite());
shaftHalf.clearInstanceData();
fanInner.clearInstanceData();
}
}

View File

@ -3,7 +3,7 @@ package com.simibubi.create.content.contraptions.components.fan;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.base.IRotate;
import com.simibubi.create.content.contraptions.base.KineticTileInstance;
import com.simibubi.create.foundation.render.InstancedTileRenderer;
import com.simibubi.create.foundation.render.instancing.InstancedTileRenderer;
import com.simibubi.create.foundation.render.instancing.InstanceKey;
import com.simibubi.create.foundation.render.instancing.InstancedModel;
import com.simibubi.create.foundation.render.instancing.InstancedTileRenderRegistry;

View File

@ -7,7 +7,6 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.content.contraptions.components.flywheel.FlywheelBlock.ConnectionState;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.render.instancing.InstanceContext;
import com.simibubi.create.foundation.render.instancing.InstancedModel;
import com.simibubi.create.foundation.render.instancing.RotatingData;
import com.simibubi.create.foundation.utility.AngleHelper;
@ -75,12 +74,6 @@ public class FlywheelRenderer extends KineticTileEntityRenderer {
wheel.renderInto(ms, vb);
}
@Override
protected InstancedModel<RotatingData> getRotatedModel(InstanceContext<? extends KineticTileEntity> ctx) {
return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(ctx, ctx.te.getBlockState(), ctx.te.getBlockState()
.get(HORIZONTAL_FACING)
.getOpposite());
}
protected SuperByteBuffer transformConnector(SuperByteBuffer buffer, boolean upper, boolean rotating, float angle,
boolean flip) {

View File

@ -3,7 +3,7 @@ package com.simibubi.create.content.contraptions.components.millstone;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.base.SingleRotatingInstance;
import com.simibubi.create.foundation.render.InstancedTileRenderer;
import com.simibubi.create.foundation.render.instancing.InstancedTileRenderer;
import com.simibubi.create.foundation.render.instancing.InstancedModel;
import com.simibubi.create.foundation.render.instancing.InstancedTileRenderRegistry;
import com.simibubi.create.foundation.render.instancing.RotatingData;

View File

@ -3,7 +3,6 @@ package com.simibubi.create.content.contraptions.components.millstone;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.foundation.render.instancing.InstanceContext;
import com.simibubi.create.foundation.render.instancing.InstancedModel;
import com.simibubi.create.foundation.render.instancing.RotatingData;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
@ -14,9 +13,5 @@ public class MillstoneRenderer extends KineticTileEntityRenderer {
super(dispatcher);
}
@Override
protected InstancedModel<RotatingData> getRotatedModel(InstanceContext<? extends KineticTileEntity> ctx) {
return AllBlockPartials.MILLSTONE_COG.renderOnRotating(ctx, ctx.te.getBlockState());
}
}

View File

@ -6,7 +6,6 @@ import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.render.instancing.InstanceContext;
import com.simibubi.create.foundation.render.instancing.InstancedModel;
import com.simibubi.create.foundation.render.instancing.RotatingData;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
@ -55,9 +54,4 @@ public class MechanicalMixerRenderer extends KineticTileEntityRenderer {
.light(packedLightmapCoords)
.renderInto(ms, vb);
}
@Override
protected InstancedModel<RotatingData> getRotatedModel(InstanceContext<? extends KineticTileEntity> ctx) {
return AllBlockPartials.SHAFTLESS_COGWHEEL.renderOnRotating(ctx, ctx.te.getBlockState());
}
}

View File

@ -3,7 +3,6 @@ package com.simibubi.create.content.contraptions.components.motor;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.foundation.render.instancing.InstanceContext;
import com.simibubi.create.foundation.render.instancing.InstancedModel;
import com.simibubi.create.foundation.render.instancing.RotatingData;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
@ -14,9 +13,5 @@ public class CreativeMotorRenderer extends KineticTileEntityRenderer {
super(dispatcher);
}
@Override
protected InstancedModel<RotatingData> getRotatedModel(InstanceContext<? extends KineticTileEntity> ctx) {
return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(ctx, ctx.te.getBlockState());
}
}

View File

@ -4,7 +4,7 @@ import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.content.contraptions.base.SingleRotatingInstance;
import com.simibubi.create.foundation.render.InstancedTileRenderer;
import com.simibubi.create.foundation.render.instancing.InstancedTileRenderer;
import com.simibubi.create.foundation.render.instancing.InstancedModel;
import com.simibubi.create.foundation.render.instancing.InstancedTileRenderRegistry;
import com.simibubi.create.foundation.render.instancing.RotatingData;

View File

@ -6,7 +6,6 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.render.instancing.InstanceContext;
import com.simibubi.create.foundation.render.instancing.InstancedModel;
import com.simibubi.create.foundation.render.instancing.RotatingData;
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringRenderer;
@ -46,14 +45,6 @@ public class SawRenderer extends SafeTileEntityRenderer<SawTileEntity> {
}
public void addInstanceData(InstanceContext<SawTileEntity> ctx) {
KineticTileEntityRenderer.renderRotatingBuffer(ctx, getRotatedModel(ctx));
}
public void markForRebuild(InstanceContext<SawTileEntity> ctx) {
getRotatedModel(ctx).clearInstanceData();
}
protected void renderBlade(SawTileEntity te, MatrixStack ms, IRenderTypeBuffer buffer, int light){
BlockState blockState = te.getBlockState();
SuperByteBuffer superBuffer;
@ -133,15 +124,6 @@ public class SawRenderer extends SafeTileEntityRenderer<SawTileEntity> {
}
}
protected InstancedModel<RotatingData> getRotatedModel(InstanceContext<SawTileEntity> ctx) {
KineticTileEntity te = ctx.te;
BlockState state = te.getBlockState();
if (state.get(FACING).getAxis().isHorizontal())
return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(ctx, state.rotate(te.getWorld(), te.getPos(), Rotation.CLOCKWISE_180));
return ctx.getRotating().getModel(KineticTileEntityRenderer.KINETIC_TILE,
getRenderedBlockState(te));
}
protected BlockState getRenderedBlockState(KineticTileEntity te) {
return KineticTileEntityRenderer.shaft(KineticTileEntityRenderer.getRotationAxisOf(te));
}

View File

@ -5,7 +5,6 @@ import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.render.instancing.InstanceContext;
import com.simibubi.create.foundation.render.instancing.InstancedModel;
import com.simibubi.create.foundation.render.instancing.RotatingData;
import com.simibubi.create.foundation.utility.AngleHelper;
@ -45,10 +44,4 @@ public class BearingRenderer extends KineticTileEntityRenderer {
superBuffer.renderInto(ms, buffer.getBuffer(RenderType.getSolid()));
}
@Override
protected InstancedModel<RotatingData> getRotatedModel(InstanceContext<? extends KineticTileEntity> ctx) {
BlockState blockState = ctx.te.getBlockState();
return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(ctx, blockState, blockState.get(BearingBlock.FACING).getOpposite());
}
}

View File

@ -3,7 +3,7 @@ package com.simibubi.create.content.contraptions.fluids;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.base.SingleRotatingInstance;
import com.simibubi.create.foundation.render.InstancedTileRenderer;
import com.simibubi.create.foundation.render.instancing.InstancedTileRenderer;
import com.simibubi.create.foundation.render.instancing.InstancedModel;
import com.simibubi.create.foundation.render.instancing.InstancedTileRenderRegistry;
import com.simibubi.create.foundation.render.instancing.RotatingData;

View File

@ -5,7 +5,6 @@ import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.render.instancing.InstanceContext;
import com.simibubi.create.foundation.render.instancing.InstancedModel;
import com.simibubi.create.foundation.render.instancing.RotatingData;
import com.simibubi.create.foundation.utility.AngleHelper;
@ -52,9 +51,4 @@ public class PumpRenderer extends KineticTileEntityRenderer {
}
}
@Override
protected InstancedModel<RotatingData> getRotatedModel(InstanceContext<? extends KineticTileEntity> ctx) {
return AllBlockPartials.MECHANICAL_PUMP_COG.renderOnDirectionalSouthRotating(ctx, ctx.te.getBlockState());
}
}

View File

@ -2,7 +2,6 @@ package com.simibubi.create.content.contraptions.relays.advanced;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.foundation.render.instancing.InstanceContext;
import com.simibubi.create.foundation.render.instancing.InstancedModel;
import com.simibubi.create.foundation.render.instancing.RotatingData;
import com.simibubi.create.foundation.tileEntity.renderer.SmartTileEntityRenderer;
@ -22,17 +21,4 @@ public class SpeedControllerRenderer extends SmartTileEntityRenderer<SpeedContro
// addInstanceData(new InstanceContext.World<>(tileEntityIn));
}
public void addInstanceData(InstanceContext<SpeedControllerTileEntity> ctx) {
KineticTileEntityRenderer.renderRotatingBuffer(ctx, getRotatedModel(ctx));
}
public void markForRebuild(InstanceContext<SpeedControllerTileEntity> ctx) {
getRotatedModel(ctx).clearInstanceData();
}
private InstancedModel<RotatingData> getRotatedModel(InstanceContext<SpeedControllerTileEntity> ctx) {
return ctx.getRotating().getModel(KineticTileEntityRenderer.KINETIC_TILE,
KineticTileEntityRenderer.shaft(KineticTileEntityRenderer.getRotationAxisOf(ctx.te)));
}
}

View File

@ -5,11 +5,10 @@ import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.content.contraptions.base.KineticTileInstance;
import com.simibubi.create.foundation.block.render.SpriteShiftEntry;
import com.simibubi.create.foundation.render.InstancedTileRenderer;
import com.simibubi.create.foundation.render.instancing.InstancedTileRenderer;
import com.simibubi.create.foundation.render.instancing.*;
import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.MatrixStacker;
import net.minecraft.block.BlockState;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
@ -38,7 +37,7 @@ public class BeltInstance extends KineticTileInstance<BeltTileEntity> {
protected ArrayList<InstanceKey<BeltData>> keys;
protected InstanceKey<RotatingData> pulleyKey;
public BeltInstance(InstancedTileRenderer modelManager, BeltTileEntity tile) {
public BeltInstance(InstancedTileRenderer<?> modelManager, BeltTileEntity tile) {
super(modelManager, tile);
}

View File

@ -9,7 +9,6 @@ import com.simibubi.create.content.contraptions.relays.belt.transport.Transporte
import com.simibubi.create.foundation.block.render.SpriteShiftEntry;
import com.simibubi.create.foundation.render.ShadowRenderHelper;
import com.simibubi.create.foundation.render.instancing.BeltData;
import com.simibubi.create.foundation.render.instancing.InstanceContext;
import com.simibubi.create.foundation.render.instancing.InstancedModel;
import com.simibubi.create.foundation.render.instancing.RotatingData;
import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer;
@ -57,74 +56,6 @@ public class BeltRenderer extends SafeTileEntityRenderer<BeltTileEntity> {
return te.isController();
}
public void addInstanceData(InstanceContext<BeltTileEntity> ctx) {
BeltTileEntity te = ctx.te;
BlockState blockState = te.getBlockState();
if (!AllBlocks.BELT.has(blockState))
return;
BeltSlope beltSlope = blockState.get(BeltBlock.SLOPE);
BeltPart part = blockState.get(BeltBlock.PART);
Direction facing = blockState.get(BeltBlock.HORIZONTAL_FACING);
AxisDirection axisDirection = facing.getAxisDirection();
boolean downward = beltSlope == BeltSlope.DOWNWARD;
boolean upward = beltSlope == BeltSlope.UPWARD;
boolean diagonal = downward || upward;
boolean start = part == BeltPart.START;
boolean end = part == BeltPart.END;
boolean sideways = beltSlope == BeltSlope.SIDEWAYS;
boolean vertical = beltSlope == BeltSlope.VERTICAL;
boolean alongX = facing.getAxis() == Axis.X;
boolean alongZ = facing.getAxis() == Axis.Z;
if (downward || vertical && axisDirection == AxisDirection.POSITIVE) {
boolean b = start;
start = end;
end = b;
}
for (boolean bottom : Iterate.trueAndFalse) {
AllBlockPartials beltPartial = getBeltPartial(diagonal, start, end, bottom);
InstancedModel<BeltData> beltBuffer = beltPartial.renderOnBelt(ctx, blockState);
SpriteShiftEntry spriteShift = getSpriteShiftEntry(diagonal, bottom);
beltBuffer.setupInstance(data -> {
float speed = te.getSpeed();
if (((axisDirection == AxisDirection.NEGATIVE) ^ upward) ^
((alongX && !diagonal) || (alongZ && diagonal)) ^
vertical)
speed = -speed;
if (sideways && (facing == Direction.SOUTH || facing == Direction.WEST))
speed = -speed;
float rotX = !diagonal && beltSlope != BeltSlope.HORIZONTAL ? 90 : 0;
float rotY = facing.getHorizontalAngle() + (upward ? 180 : 0) + (sideways ? 90 : 0);
float rotZ = sideways ? 90 : (vertical ? 180 : 0);
data.setTileEntity(te)
.setBlockLight(te.getWorld().getLightLevel(LightType.BLOCK, te.getPos()))
.setSkyLight(te.getWorld().getLightLevel(LightType.SKY, te.getPos()))
.setRotation(rotX, rotY, rotZ)
.setRotationalSpeed(speed)
.setScrollTexture(spriteShift)
.setScrollMult(diagonal ? 3f / 8f : 0.5f);
});
// Diagonal belt do not have a separate bottom model
if (diagonal)
break;
}
if (te.hasPulley()) {
InstancedModel<RotatingData> rotatingBuffer = getPulleyModel(ctx, blockState, sideways);
KineticTileEntityRenderer.renderRotatingBuffer(ctx, rotatingBuffer);
}
}
public static SpriteShiftEntry getSpriteShiftEntry(boolean diagonal, boolean bottom) {
if (diagonal) return AllSpriteShifts.BELT_DIAGONAL;
if (bottom) return AllSpriteShifts.BELT_OFFSET;
@ -148,31 +79,6 @@ public class BeltRenderer extends SafeTileEntityRenderer<BeltTileEntity> {
}
}
private InstancedModel<RotatingData> getPulleyModel(InstanceContext<BeltTileEntity> ctx, BlockState blockState, boolean sideways) {
Direction dir = blockState.get(BeltBlock.HORIZONTAL_FACING)
.rotateY();
if (sideways)
dir = Direction.UP;
Axis axis = dir.getAxis();
Supplier<MatrixStack> ms = () -> {
MatrixStack modelTransform = new MatrixStack();
MatrixStacker msr = MatrixStacker.of(modelTransform);
msr.centre();
if (axis == Axis.X)
msr.rotateY(90);
if (axis == Axis.Y)
msr.rotateX(90);
msr.rotateX(90);
msr.unCentre();
return modelTransform;
};
return ctx.getRotating().getModel(AllBlockPartials.BELT_PULLEY, blockState, dir, ms);
}
protected void renderItems(BeltTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer,
int light, int overlay) {
if (!te.isController())

View File

@ -2,7 +2,7 @@ package com.simibubi.create.content.contraptions.relays.encased;
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.base.SingleRotatingInstance;
import com.simibubi.create.foundation.render.InstancedTileRenderer;
import com.simibubi.create.foundation.render.instancing.InstancedTileRenderer;
import com.simibubi.create.foundation.render.instancing.InstancedTileRenderRegistry;
import net.minecraft.block.BlockState;
import net.minecraft.tileentity.TileEntityType;

View File

@ -3,17 +3,15 @@ package com.simibubi.create.content.contraptions.relays.encased;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.base.IRotate;
import com.simibubi.create.content.contraptions.base.KineticTileInstance;
import com.simibubi.create.foundation.render.InstancedTileRenderer;
import com.simibubi.create.foundation.render.instancing.InstancedTileRenderer;
import com.simibubi.create.foundation.render.instancing.InstanceKey;
import com.simibubi.create.foundation.render.instancing.InstancedModel;
import com.simibubi.create.foundation.render.instancing.InstancedTileRenderRegistry;
import com.simibubi.create.foundation.render.instancing.RotatingData;
import com.simibubi.create.foundation.utility.Iterate;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.fml.DistExecutor;

View File

@ -5,7 +5,6 @@ import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.base.IRotate;
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.foundation.render.instancing.InstanceContext;
import com.simibubi.create.foundation.render.instancing.InstancedModel;
import com.simibubi.create.foundation.render.instancing.RotatingData;
import com.simibubi.create.foundation.utility.Iterate;
@ -29,63 +28,4 @@ public class SplitShaftRenderer extends KineticTileEntityRenderer {
super.renderSafe(te, partialTicks, ms, buffer, light, overlay);
}
@Override
public void addInstanceData(InstanceContext<KineticTileEntity> ctx) {
KineticTileEntity te = ctx.te;
Block block = te.getBlockState().getBlock();
final Axis boxAxis = ((IRotate) block).getRotationAxis(te.getBlockState());
final BlockPos pos = te.getPos();
int blockLight;
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) {
Axis axis = direction.getAxis();
if (boxAxis != axis)
continue;
InstancedModel<RotatingData> shaft = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(ctx, te.getBlockState(), direction);
shaft.setupInstance(data -> {
float speed = te.getSpeed();
float modifier = 1;
if (te instanceof SplitShaftTileEntity)
modifier = ((SplitShaftTileEntity) te).getRotationSpeedModifier(direction);
speed *= modifier;
data.setBlockLight(blockLight)
.setSkyLight(skyLight)
.setRotationalSpeed(speed)
.setRotationOffset(getRotationOffsetForPosition(te, pos, axis))
.setRotationAxis(Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis).getUnitVector())
.setTileEntity(te);
});
}
}
@Override
public void markForRebuild(InstanceContext<KineticTileEntity> ctx) {
KineticTileEntity te = ctx.te;
Block block = te.getBlockState().getBlock();
final Axis boxAxis = ((IRotate) block).getRotationAxis(te.getBlockState());
for (Direction direction : Iterate.directions) {
Axis axis = direction.getAxis();
if (boxAxis != axis) continue;
InstancedModel<RotatingData> shaft = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(ctx, te.getBlockState(), direction);
shaft.clearInstanceData();
}
}
}

View File

@ -2,13 +2,12 @@ package com.simibubi.create.content.contraptions.relays.gearbox;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.base.KineticTileInstance;
import com.simibubi.create.foundation.render.InstancedTileRenderer;
import com.simibubi.create.foundation.render.instancing.InstancedTileRenderer;
import com.simibubi.create.foundation.render.instancing.InstanceKey;
import com.simibubi.create.foundation.render.instancing.InstancedModel;
import com.simibubi.create.foundation.render.instancing.InstancedTileRenderRegistry;
import com.simibubi.create.foundation.render.instancing.RotatingData;
import com.simibubi.create.foundation.utility.Iterate;
import net.minecraft.block.BlockState;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.Direction;

View File

@ -5,7 +5,6 @@ import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.foundation.render.instancing.InstanceContext;
import com.simibubi.create.foundation.render.instancing.InstancedModel;
import com.simibubi.create.foundation.render.instancing.RotatingData;
import com.simibubi.create.foundation.utility.Iterate;
@ -32,69 +31,4 @@ public class GearboxRenderer extends KineticTileEntityRenderer {
super.renderSafe(te, partialTicks, ms, buffer, light, overlay);
}
@Override
public void addInstanceData(InstanceContext<KineticTileEntity> ctx) {
KineticTileEntity te = ctx.te;
final BlockPos pos = te.getPos();
int blockLight;
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 (Pair<Direction, InstancedModel<RotatingData>> shaft : getBuffers(ctx)) {
shaft.getSecond().setupInstance(data -> {
float speed = te.getSpeed();
Direction direction = shaft.getFirst();
Axis axis = direction.getAxis();
if (te.getSpeed() != 0 && te.hasSource()) {
BlockPos source = te.source.subtract(te.getPos());
Direction sourceFacing = Direction.getFacingFromVector(source.getX(), source.getY(), source.getZ());
if (sourceFacing.getAxis() == axis)
speed *= sourceFacing == direction ? 1 : -1;
else if (sourceFacing.getAxisDirection() == direction.getAxisDirection())
speed *= -1;
}
data.setBlockLight(blockLight)
.setSkyLight(skyLight)
.setRotationalSpeed(speed)
.setRotationOffset(getRotationOffsetForPosition(te, pos, axis))
.setRotationAxis(Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis).getUnitVector())
.setTileEntity(te);
});
}
}
@Override
public void markForRebuild(InstanceContext<KineticTileEntity> ctx) {
getBuffers(ctx).stream().map(Pair::getSecond).forEach(InstancedModel::clearInstanceData);
}
private List<Pair<Direction, InstancedModel<RotatingData>>> getBuffers(InstanceContext<KineticTileEntity> ctx) {
KineticTileEntity te = ctx.te;
final Axis boxAxis = te.getBlockState().get(BlockStateProperties.AXIS);
List<Pair<Direction, InstancedModel<RotatingData>>> buffers = Lists.newArrayListWithCapacity(4);
for (Direction direction : Iterate.directions) {
final Axis axis = direction.getAxis();
if (boxAxis == axis)
continue;
InstancedModel<RotatingData> buffer = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(ctx, te.getBlockState(), direction);
Pair<Direction, InstancedModel<RotatingData>> pair = Pair.of(direction, buffer);
buffers.add(pair);
}
return buffers;
}
}

View File

@ -3,7 +3,7 @@ package com.simibubi.create.content.logistics.block.mechanicalArm;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.base.SingleRotatingInstance;
import com.simibubi.create.foundation.render.InstancedTileRenderer;
import com.simibubi.create.foundation.render.instancing.InstancedTileRenderer;
import com.simibubi.create.foundation.render.instancing.InstancedModel;
import com.simibubi.create.foundation.render.instancing.InstancedTileRenderRegistry;
import com.simibubi.create.foundation.render.instancing.RotatingData;

View File

@ -7,7 +7,6 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.content.logistics.block.mechanicalArm.ArmTileEntity.Phase;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.render.instancing.InstanceContext;
import com.simibubi.create.foundation.render.instancing.InstancedModel;
import com.simibubi.create.foundation.render.instancing.RotatingData;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
@ -124,9 +123,4 @@ public class ArmRenderer extends KineticTileEntityRenderer {
ms.pop();
}
@Override
protected InstancedModel<RotatingData> getRotatedModel(InstanceContext<? extends KineticTileEntity> ctx) {
return AllBlockPartials.ARM_COG.renderOnRotating(ctx, ctx.te.getBlockState());
}
}

View File

@ -0,0 +1,34 @@
package com.simibubi.create.foundation.render;
import com.simibubi.create.Create;
import com.simibubi.create.foundation.render.contraption.ContraptionProgram;
import com.simibubi.create.foundation.render.gl.BasicProgram;
import com.simibubi.create.foundation.render.gl.shader.ProgramSpec;
import com.simibubi.create.foundation.render.gl.shader.ShaderConstants;
import net.minecraft.util.ResourceLocation;
import static com.simibubi.create.foundation.render.gl.shader.ShaderHelper.register;
public class AllProgramSpecs {
public static final ProgramSpec<BasicProgram> ROTATING = register(new ProgramSpec<>("rotating", Locations.ROTATING, Locations.INSTANCED, BasicProgram::new));
public static final ProgramSpec<BasicProgram> BELT = register(new ProgramSpec<>("belt", Locations.BELT, Locations.INSTANCED, BasicProgram::new));
public static final ProgramSpec<ContraptionProgram> CONTRAPTION_STRUCTURE = register(new ProgramSpec<>("contraption_structure", Locations.CONTRAPTION_STRUCTURE, Locations.CONTRAPTION, ContraptionProgram::new));
public static final ProgramSpec<ContraptionProgram> CONTRAPTION_ROTATING = register(new ProgramSpec<>("contraption_rotating", Locations.ROTATING, Locations.CONTRAPTION, ContraptionProgram::new, ShaderConstants.define("CONTRAPTION")));
public static final ProgramSpec<ContraptionProgram> CONTRAPTION_BELT = register(new ProgramSpec<>("contraption_belt", Locations.BELT, Locations.CONTRAPTION, ContraptionProgram::new, ShaderConstants.define("CONTRAPTION")));
public static final ProgramSpec<ContraptionProgram> CONTRAPTION_ACTOR = register(new ProgramSpec<>("contraption_actor", Locations.CONTRAPTION_ACTOR, Locations.CONTRAPTION, ContraptionProgram::new));
public static class Locations {
public static final ResourceLocation INSTANCED = loc("instanced.frag");
public static final ResourceLocation CONTRAPTION = loc("contraption.frag");
public static final ResourceLocation ROTATING = loc("rotating.vert");
public static final ResourceLocation BELT = loc("belt.vert");
public static final ResourceLocation CONTRAPTION_STRUCTURE = loc("contraption_structure.vert");
public static final ResourceLocation CONTRAPTION_ACTOR = loc("contraption_actor.vert");
private static ResourceLocation loc(String name) {
return new ResourceLocation(Create.ID, "shader/" + name);
}
}
}

View File

@ -0,0 +1,54 @@
package com.simibubi.create.foundation.render;
import com.simibubi.create.foundation.render.gl.GlPrimitiveType;
import com.simibubi.create.foundation.render.gl.attrib.CommonAttributes;
import com.simibubi.create.foundation.render.gl.attrib.VertexSpec;
import com.simibubi.create.foundation.render.gl.attrib.VertexAttribute;
import com.simibubi.create.foundation.render.gl.attrib.VertexFormat;
import static com.simibubi.create.foundation.render.gl.attrib.VertexAttribute.copy;
import static com.simibubi.create.foundation.render.gl.attrib.CommonAttributes.*;
public class AllVertexSpecs {
public static final VertexAttribute ROTATION_CENTER = copy("rotationCenter", CommonAttributes.VEC3);
public static final VertexAttribute SPEED = copy("speed", CommonAttributes.FLOAT);
public static final VertexAttribute OFFSET = copy("offset", CommonAttributes.FLOAT);
public static final VertexAttribute TARGET_UV = copy("scrollTexture", CommonAttributes.VEC4);
public static final VertexAttribute SCROLL_MULT = new VertexAttribute("scrollMult", GlPrimitiveType.BYTE, 1, true);
public static final VertexFormat FORMAT = new VertexFormat(CommonAttributes.INSTANCE_POSITION, CommonAttributes.LIGHT, CommonAttributes.RGB, SPEED, OFFSET);
public static final VertexSpec KINETIC = new VertexSpec()
.attrib(POSITION)
.attrib(NORMAL)
.attrib(UV)
.pushGroup(1) // instance data
.attrib(INSTANCE_POSITION)
.attrib(LIGHT)
.attrib(RGB)
.attrib(SPEED)
.attrib(OFFSET);
public static final VertexSpec BELT = new VertexSpec(KINETIC)
.attrib(ROTATION)
.attrib("uv", UV)
.attrib(TARGET_UV)
.attrib(SCROLL_MULT);
public static final VertexSpec ROTATING = new VertexSpec(KINETIC)
.attrib("rotationAxis", NORMAL);
public static final VertexSpec ACTOR = new VertexSpec()
.attrib(POSITION)
.attrib(NORMAL)
.attrib(UV)
.pushGroup(1) // instance data
.attrib(INSTANCE_POSITION)
.attrib(LIGHT)
.attrib(OFFSET)
.attrib("localRotationAxis", NORMAL)
.attrib("localRotation", ROTATION)
.attrib(ROTATION_CENTER);
}

View File

@ -3,7 +3,7 @@ package com.simibubi.create.foundation.render;
import com.simibubi.create.foundation.render.gl.backend.Backend;
import com.simibubi.create.foundation.render.gl.GlBuffer;
import com.simibubi.create.foundation.render.gl.GlVertexArray;
import com.simibubi.create.foundation.render.instancing.VertexFormat;
import com.simibubi.create.foundation.render.gl.attrib.VertexFormat;
import net.minecraft.client.renderer.BufferBuilder;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20;

View File

@ -68,20 +68,20 @@ public class FastRenderDispatcher {
}
public static void renderLayer(RenderType type, MatrixStack stack, double cameraX, double cameraY, double cameraZ) {
Matrix4f view = Matrix4f.translate((float) -cameraX, (float) -cameraY, (float) -cameraZ);
view.multiplyBackward(stack.peek().getModel());
Matrix4f viewProjection = Matrix4f.translate((float) -cameraX, (float) -cameraY, (float) -cameraZ);
viewProjection.multiplyBackward(stack.peek().getModel());
viewProjection.multiplyBackward(getProjectionMatrix());
Matrix4f projection = getProjectionMatrix();
type.startDrawing();
RenderSystem.enableDepthTest();
RenderSystem.enableCull();
GL11.glCullFace(GL11.GL_BACK);
CreateClient.kineticRenderer.render(type, projection, view);
CreateClient.kineticRenderer.render(type, viewProjection);
RenderSystem.disableCull();
//RenderSystem.disableDepthTest();
ContraptionRenderDispatcher.renderLayer(type, projection, view);
ContraptionRenderDispatcher.renderLayer(type, viewProjection);
ShaderHelper.releaseShader();
type.endDrawing();
}

View File

@ -0,0 +1,12 @@
package com.simibubi.create.foundation.render;
import com.simibubi.create.foundation.render.gl.BasicProgram;
import com.simibubi.create.foundation.render.instancing.*;
public class KineticRenderer extends InstancedTileRenderer<BasicProgram> {
@Override
public void registerMaterials() {
materials.put(KineticRenderMaterials.BELTS, new RenderMaterial<>(AllProgramSpecs.BELT, BeltModel::new));
materials.put(KineticRenderMaterials.ROTATING, new RenderMaterial<>(AllProgramSpecs.ROTATING, RotatingModel::new));
}
}

View File

@ -1,19 +1,19 @@
package com.simibubi.create.foundation.render.contraption;
import com.simibubi.create.foundation.render.InstancedTileRenderer;
import com.simibubi.create.foundation.render.gl.shader.AllShaderPrograms;
import com.simibubi.create.foundation.render.AllProgramSpecs;
import com.simibubi.create.foundation.render.instancing.InstancedTileRenderer;
import com.simibubi.create.foundation.render.instancing.BeltModel;
import com.simibubi.create.foundation.render.instancing.KineticRenderMaterials;
import com.simibubi.create.foundation.render.instancing.RenderMaterial;
import com.simibubi.create.foundation.render.instancing.RotatingModel;
import com.simibubi.create.foundation.render.instancing.actors.RotatingActorModel;
public class ContraptionKineticRenderer extends InstancedTileRenderer {
public class ContraptionKineticRenderer extends InstancedTileRenderer<ContraptionProgram> {
@Override
public void registerMaterials() {
materials.put(KineticRenderMaterials.BELTS, new RenderMaterial<>(AllShaderPrograms.CONTRAPTION_BELT, BeltModel::new));
materials.put(KineticRenderMaterials.ROTATING, new RenderMaterial<>(AllShaderPrograms.CONTRAPTION_ROTATING, RotatingModel::new));
materials.put(KineticRenderMaterials.ACTORS, new RenderMaterial<>(AllShaderPrograms.CONTRAPTION_ACTOR, RotatingActorModel::new));
materials.put(KineticRenderMaterials.BELTS, new RenderMaterial<>(AllProgramSpecs.CONTRAPTION_BELT, BeltModel::new));
materials.put(KineticRenderMaterials.ROTATING, new RenderMaterial<>(AllProgramSpecs.CONTRAPTION_ROTATING, RotatingModel::new));
materials.put(KineticRenderMaterials.ACTORS, new RenderMaterial<>(AllProgramSpecs.CONTRAPTION_ACTOR, RotatingActorModel::new));
}
}

View File

@ -2,7 +2,7 @@ package com.simibubi.create.foundation.render.contraption;
import com.simibubi.create.foundation.render.BufferedModel;
import com.simibubi.create.foundation.render.instancing.InstancedModel;
import com.simibubi.create.foundation.render.instancing.VertexFormat;
import com.simibubi.create.foundation.render.gl.attrib.VertexFormat;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.LightTexture;
import org.lwjgl.opengl.GL11;
@ -10,8 +10,8 @@ import org.lwjgl.opengl.GL40;
import java.nio.ByteBuffer;
import static com.simibubi.create.foundation.render.instancing.VertexAttribute.LIGHT;
import static com.simibubi.create.foundation.render.instancing.VertexAttribute.RGBA;
import static com.simibubi.create.foundation.render.gl.attrib.CommonAttributes.LIGHT;
import static com.simibubi.create.foundation.render.gl.attrib.CommonAttributes.RGBA;
public class ContraptionModel extends BufferedModel {
public static final VertexFormat FORMAT = new VertexFormat(InstancedModel.FORMAT, RGBA, LIGHT);

View File

@ -0,0 +1,35 @@
package com.simibubi.create.foundation.render.contraption;
import com.simibubi.create.foundation.render.gl.BasicProgram;
import com.simibubi.create.foundation.render.light.GridAlignedBB;
import net.minecraft.client.renderer.Matrix4f;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.opengl.GL20;
public class ContraptionProgram extends BasicProgram {
protected final int uLightBoxSize;
protected final int uLightBoxMin;
protected final int uModel;
protected int uLightVolume;
public ContraptionProgram(ResourceLocation name, int handle) {
super(name, handle);
uLightBoxSize = getUniformLocation("uLightBoxSize");
uLightBoxMin = getUniformLocation("uLightBoxMin");
uModel = getUniformLocation("uModel");
}
@Override
protected void registerSamplers() {
super.registerSamplers();
uLightVolume = setSamplerBinding("uLightVolume", 4);
}
public void bind(Matrix4f model, GridAlignedBB lightVolume) {
bind();
GL20.glUniform3f(uLightBoxSize, lightVolume.sizeX(), lightVolume.sizeY(), lightVolume.sizeZ());
GL20.glUniform3f(uLightBoxMin, lightVolume.minX, lightVolume.minY, lightVolume.minZ);
uploadMatrixUniform(uModel, model);
}
}

View File

@ -5,7 +5,7 @@ import com.simibubi.create.content.contraptions.components.structureMovement.Abs
import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntityRenderer;
import com.simibubi.create.content.contraptions.components.structureMovement.Contraption;
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionHandler;
import com.simibubi.create.foundation.render.gl.shader.AllShaderPrograms;
import com.simibubi.create.foundation.render.AllProgramSpecs;
import com.simibubi.create.foundation.render.gl.shader.ShaderCallback;
import com.simibubi.create.foundation.render.gl.shader.ShaderHelper;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
@ -86,7 +86,7 @@ public class ContraptionRenderDispatcher {
return renderer;
}
public static void renderLayer(RenderType layer, Matrix4f projectionMat, Matrix4f viewMat) {
public static void renderLayer(RenderType layer, Matrix4f viewProjection) {
removeDeadContraptions();
if (renderers.isEmpty()) return;
@ -95,15 +95,14 @@ public class ContraptionRenderDispatcher {
GL11.glEnable(GL13.GL_TEXTURE_3D);
GL13.glActiveTexture(GL40.GL_TEXTURE4); // the shaders expect light volumes to be in texture 4
ShaderCallback callback = ShaderHelper.getViewProjectionCallback(projectionMat, viewMat);
int structureShader = ShaderHelper.useShader(AllShaderPrograms.CONTRAPTION_STRUCTURE, callback);
ContraptionProgram structureShader = ShaderHelper.getProgram(AllProgramSpecs.CONTRAPTION_STRUCTURE);
structureShader.bind(viewProjection, 0);
for (RenderedContraption renderer : renderers.values()) {
renderer.doRenderLayer(layer, structureShader);
}
for (RenderedContraption renderer : renderers.values()) {
renderer.kinetics.render(layer, projectionMat, viewMat, renderer::setup);
renderer.kinetics.render(layer, viewProjection, renderer::setup);
renderer.teardown();
}

View File

@ -1,12 +1,10 @@
package com.simibubi.create.foundation.render.contraption;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.platform.GlStateManager;
import com.simibubi.create.AllMovementBehaviours;
import com.simibubi.create.content.contraptions.components.structureMovement.Contraption;
import com.simibubi.create.content.contraptions.components.structureMovement.MovementBehaviour;
import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext;
import com.simibubi.create.foundation.render.gl.shader.ShaderHelper;
import com.simibubi.create.foundation.render.instancing.*;
import com.simibubi.create.foundation.render.instancing.actors.StaticRotatingActorData;
import com.simibubi.create.foundation.render.light.ContraptionLighter;
@ -28,7 +26,6 @@ import net.minecraftforge.client.model.data.EmptyModelData;
import org.apache.commons.lang3.tuple.MutablePair;
import org.lwjgl.opengl.GL11;
import java.nio.FloatBuffer;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
@ -70,11 +67,11 @@ public class RenderedContraption {
return lighter;
}
public RenderMaterial<InstancedModel<StaticRotatingActorData>> getActorMaterial() {
return kinetics.get(KineticRenderMaterials.ACTORS);
public RenderMaterial<?, InstancedModel<StaticRotatingActorData>> getActorMaterial() {
return kinetics.getMaterial(KineticRenderMaterials.ACTORS);
}
public void doRenderLayer(RenderType layer, int shader) {
public void doRenderLayer(RenderType layer, ContraptionProgram shader) {
ContraptionModel buffer = renderLayers.get(layer);
if (buffer != null) {
setup(shader);
@ -131,8 +128,8 @@ public class RenderedContraption {
this.model = model;
}
void setup(int shader) {
setupShaderUniforms(shader);
void setup(ContraptionProgram shader) {
shader.bind(model, lighter.lightVolume.getTextureVolume());
lighter.lightVolume.use();
}
@ -140,29 +137,6 @@ public class RenderedContraption {
lighter.lightVolume.release();
}
void setupShaderUniforms(int shader) {
FloatBuffer buf = ShaderHelper.VEC3_BUFFER;
int lightBoxSize = GlStateManager.getUniformLocation(shader, "lightBoxSize");
buf.put(0, (float) lighter.lightVolume.getSizeX());
buf.put(1, (float) lighter.lightVolume.getSizeY());
buf.put(2, (float) lighter.lightVolume.getSizeZ());
buf.rewind();
GlStateManager.uniform3(lightBoxSize, buf);
int lightBoxMin = GlStateManager.getUniformLocation(shader, "lightBoxMin");
buf.put(0, (float) lighter.lightVolume.getMinX());
buf.put(1, (float) lighter.lightVolume.getMinY());
buf.put(2, (float) lighter.lightVolume.getMinZ());
buf.rewind();
GlStateManager.uniform3(lightBoxMin, buf);
int model = GlStateManager.getUniformLocation(shader, "model");
this.model.write(ShaderHelper.MATRIX_BUFFER);
ShaderHelper.MATRIX_BUFFER.rewind();
GlStateManager.uniformMatrix4(model, false, ShaderHelper.MATRIX_BUFFER);
}
void invalidate() {
for (ContraptionModel buffer : renderLayers.values()) {
buffer.delete();

View File

@ -0,0 +1,51 @@
package com.simibubi.create.foundation.render.gl;
import com.simibubi.create.foundation.render.gl.shader.GlProgram;
import com.simibubi.create.foundation.render.gl.shader.ShaderHelper;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import net.minecraft.client.renderer.Matrix4f;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.opengl.GL20;
public class BasicProgram extends GlProgram {
protected final int uTicks;
protected final int uTime;
protected final int uViewProjection;
protected final int uDebug;
protected int uBlockAtlas;
protected int uLightMap;
public BasicProgram(ResourceLocation name, int handle) {
super(name, handle);
uTicks = getUniformLocation("uTicks");
uTime = getUniformLocation("uTime");
uViewProjection = getUniformLocation("uViewProjection");
uDebug = getUniformLocation("uDebug");
bind();
registerSamplers();
unbind();
}
protected void registerSamplers() {
uBlockAtlas = setSamplerBinding("uBlockAtlas", 0);
uLightMap = setSamplerBinding("uLightMap", 2);
}
public void bind(Matrix4f viewProjection, int debugMode) {
super.bind();
GL20.glUniform1i(uTicks, AnimationTickHolder.ticks);
GL20.glUniform1f(uTime, AnimationTickHolder.getRenderTick());
uploadMatrixUniform(uViewProjection, viewProjection);
GL20.glUniform1i(uDebug, debugMode);
}
protected static void uploadMatrixUniform(int uniform, Matrix4f mat) {
ShaderHelper.MATRIX_BUFFER.position(0);
mat.write(ShaderHelper.MATRIX_BUFFER);
ShaderHelper.MATRIX_BUFFER.rewind();
GL20.glUniformMatrix4fv(uniform, false, ShaderHelper.MATRIX_BUFFER);
}
}

View File

@ -0,0 +1,26 @@
package com.simibubi.create.foundation.render.gl;
public class SamplerBinding {
private final SamplerType type;
private final String variableName;
private final int binding;
public SamplerBinding(SamplerType type, String variableName, int binding) {
this.type = type;
this.variableName = variableName;
this.binding = binding;
}
public SamplerType getType() {
return type;
}
public String getVariableName() {
return variableName;
}
public int getBinding() {
return binding;
}
}

View File

@ -0,0 +1,25 @@
package com.simibubi.create.foundation.render.gl;
import org.lwjgl.opengl.GL20;
public enum SamplerType {
SAMPLER2D(GL20.GL_TEXTURE_2D, "sampler2D"),
SAMPLER3D(GL20.GL_TEXTURE_3D, "sampler3D"),
;
private final int glEnum;
private final String shaderToken;
SamplerType(int glEnum, String shaderToken) {
this.glEnum = glEnum;
this.shaderToken = shaderToken;
}
public int getGlEnum() {
return glEnum;
}
public String getShaderToken() {
return shaderToken;
}
}

View File

@ -0,0 +1,27 @@
package com.simibubi.create.foundation.render.gl.attrib;
import java.util.ArrayList;
public class AttributeGroup {
private final int divisor;
private final ArrayList<VertexAttribute> attributes;
public AttributeGroup(int divisor) {
this.divisor = divisor;
this.attributes = new ArrayList<>();
}
public AttributeGroup attrib(VertexAttribute attrib) {
attributes.add(attrib);
return this;
}
public int getDivisor() {
return divisor;
}
public ArrayList<VertexAttribute> getAttributes() {
return attributes;
}
}

View File

@ -0,0 +1,23 @@
package com.simibubi.create.foundation.render.gl.attrib;
import com.simibubi.create.foundation.render.gl.GlPrimitiveType;
public class CommonAttributes {
public static final VertexAttribute MAT4 = new VertexAttribute("aMat4", GlPrimitiveType.FLOAT, 16);
public static final VertexAttribute VEC4 = new VertexAttribute("aVec4", GlPrimitiveType.FLOAT, 4);
public static final VertexAttribute VEC3 = new VertexAttribute("aVec3", GlPrimitiveType.FLOAT, 3);
public static final VertexAttribute VEC2 = new VertexAttribute("aVec2", GlPrimitiveType.FLOAT, 2);
public static final VertexAttribute FLOAT = new VertexAttribute("aFloat", GlPrimitiveType.FLOAT, 1);
public static final VertexAttribute POSITION = VertexAttribute.copy("aPos", VEC3);
public static final VertexAttribute NORMAL = new VertexAttribute("aNormal", GlPrimitiveType.BYTE, 3, true);
public static final VertexAttribute UV = VertexAttribute.copy("aTexCoords", VEC2);
public static final VertexAttribute ROTATION = VertexAttribute.copy("eulerAngles", VEC3);
public static final VertexAttribute INSTANCE_POSITION = VertexAttribute.copy("instancePos", VEC3);
public static final VertexAttribute RGBA = new VertexAttribute("rgba", GlPrimitiveType.UBYTE, 4, true);
public static final VertexAttribute RGB = new VertexAttribute("rgb", GlPrimitiveType.UBYTE, 3, true);
public static final VertexAttribute LIGHT = new VertexAttribute("light", GlPrimitiveType.UBYTE, 2, true);
}

View File

@ -1,23 +1,9 @@
package com.simibubi.create.foundation.render.instancing;
package com.simibubi.create.foundation.render.gl.attrib;
import com.simibubi.create.foundation.render.gl.GlPrimitiveType;
import org.lwjgl.opengl.GL20;
public class VertexAttribute {
public static final VertexAttribute MAT4 = new VertexAttribute("mat4", GlPrimitiveType.FLOAT, 16);
public static final VertexAttribute VEC4 = new VertexAttribute("vec4", GlPrimitiveType.FLOAT, 4);
public static final VertexAttribute VEC3 = new VertexAttribute("vec3", GlPrimitiveType.FLOAT, 3);
public static final VertexAttribute VEC2 = new VertexAttribute("vec2", GlPrimitiveType.FLOAT, 2);
public static final VertexAttribute FLOAT = new VertexAttribute("float", GlPrimitiveType.FLOAT, 1);
public static final VertexAttribute POSITION = copy("pos", VEC3);
public static final VertexAttribute INSTANCE_POSITION = copy("instancePos", VEC3);
public static final VertexAttribute ROTATION = copy("eulerAngles", VEC3);
public static final VertexAttribute NORMAL = new VertexAttribute("normal", GlPrimitiveType.BYTE, 3, true);
public static final VertexAttribute RGBA = new VertexAttribute("rgba", GlPrimitiveType.UBYTE, 4, true);
public static final VertexAttribute RGB = new VertexAttribute("rgb", GlPrimitiveType.UBYTE, 3, true);
public static final VertexAttribute UV = copy("uv", VEC2);
public static final VertexAttribute LIGHT = new VertexAttribute("light", GlPrimitiveType.UBYTE, 2, true);
private final String name;
private final GlPrimitiveType type;

View File

@ -1,4 +1,4 @@
package com.simibubi.create.foundation.render.instancing;
package com.simibubi.create.foundation.render.gl.attrib;
public class VertexFormat {

View File

@ -0,0 +1,61 @@
package com.simibubi.create.foundation.render.gl.attrib;
import com.google.common.collect.Lists;
import java.util.ArrayList;
import java.util.function.Consumer;
public class VertexSpec {
private final ArrayList<AttributeGroup> groups;
public VertexSpec() {
groups = Lists.newArrayList(new AttributeGroup(0));
}
public VertexSpec(VertexSpec that) {
groups = new ArrayList<>();
for (AttributeGroup group : that.groups) {
AttributeGroup copy = new AttributeGroup(group.getDivisor());
for (VertexAttribute attribute : group.getAttributes()) {
copy.attrib(attribute);
}
groups.add(copy);
}
}
public VertexSpec pushGroup() {
return pushGroup(0);
}
public VertexSpec group(int divisor, Consumer<AttributeGroup> builder) {
AttributeGroup group = new AttributeGroup(divisor);
builder.accept(group);
return group(group);
}
public VertexSpec pushGroup(int divisor) {
return group(new AttributeGroup(divisor));
}
public VertexSpec group(AttributeGroup group) {
groups.add(group);
return this;
}
public VertexSpec attrib(String name, VertexAttribute attrib) {
return attrib(VertexAttribute.copy(name, attrib));
}
public VertexSpec attrib(VertexAttribute attrib) {
last().attrib(attrib);
return this;
}
private AttributeGroup last() {
return groups.get(groups.size() - 1);
}
}

View File

@ -1,55 +0,0 @@
package com.simibubi.create.foundation.render.gl.shader;
import com.simibubi.create.Create;
import net.minecraft.util.ResourceLocation;
public enum AllShaderPrograms {
ROTATING("shader/rotating.vert", "shader/instanced.frag"),
BELT("shader/belt.vert", "shader/instanced.frag"),
CONTRAPTION_STRUCTURE("shader/contraption_structure.vert", "shader/contraption.frag"),
CONTRAPTION_ROTATING("shader/contraption_rotating.vert", "shader/contraption.frag"),
CONTRAPTION_BELT("shader/contraption_belt.vert", "shader/contraption.frag"),
CONTRAPTION_ACTOR("shader/contraption_actor.vert", "shader/contraption.frag"),
;
public final String vert;
public final String frag;
AllShaderPrograms(String vert, String frag) {
this.vert = vert;
this.frag = frag;
}
}
//public class AllShaderPrograms {
// public static final ProgramBuilder ROTATING = new ProgramBuilder(name("rotating"))
// .vert(vert("rotating"))
// .frag(frag("instanced"));
// public static final ProgramBuilder BELT = new ProgramBuilder(name("belt"))
// .vert(vert("belt"))
// .frag(frag("instanced"));
// public static final ProgramBuilder CONTRAPTION_STRUCTURE = new ProgramBuilder(name("contraption_structure"))
// .vert(vert("contraption_structure"))
// .frag(frag("contraption_structure"));
// public static final ProgramBuilder CONTRAPTION_ROTATING = new ProgramBuilder(name("contraption_rotating"))
// .vert(vert("contraption_rotating"))
// .frag(frag("contraption"));
// public static final ProgramBuilder CONTRAPTION_BELT = new ProgramBuilder(name("contraption_belt"))
// .vert(vert("contraption_belt"))
// .frag(frag("contraption"));
// public static final ProgramBuilder CONTRAPTION_ACTOR = new ProgramBuilder(name("contraption_actor"))
// .vert(vert("contraption_actor"))
// .frag(frag("contraption"));
//
// private static ResourceLocation vert(String file) {
// return new ResourceLocation(Create.ID, "shader/" + file + ".vert");
// }
//
// private static ResourceLocation frag(String file) {
// return new ResourceLocation(Create.ID, "shader/" + file + ".vert");
// }
//
// private static ResourceLocation name(String name) {
// return new ResourceLocation(Create.ID, name);
// }
//}

View File

@ -0,0 +1,119 @@
package com.simibubi.create.foundation.render.gl.shader;
import com.simibubi.create.foundation.render.gl.GlObject;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.opengl.GL20;
public abstract class GlProgram extends GlObject {
public final ResourceLocation name;
protected GlProgram(ResourceLocation name, int handle) {
setHandle(handle);
this.name = name;
}
public static Builder builder(ResourceLocation name) {
return new Builder(name);
}
public void bind() {
GL20.glUseProgram(handle());
}
public void unbind() {
GL20.glUseProgram(0);
}
/**
* Retrieves the index of the uniform with the given name.
* @param uniform The name of the uniform to find the index of
* @return The uniform's index
* @throws NullPointerException If no uniform exists with the given name
*/
public int getUniformLocation(String uniform) {
int index = GL20.glGetUniformLocation(this.handle(), uniform);
if (index < 0) {
ShaderHelper.log.error("No uniform exists in program '" + this.name + "' with name: " + uniform);
}
return index;
}
/**
* Binds a sampler uniform to the given texture unit.
* @param name The name of the sampler uniform.
* @param binding The index of the texture unit.
* @return The sampler uniform's index.
* @throws NullPointerException If no uniform exists with the given name.
*/
public int setSamplerBinding(String name, int binding) {
int samplerUniform = getUniformLocation(name);
if (samplerUniform >= 0) {
GL20.glUniform1i(samplerUniform, binding);
}
return samplerUniform;
}
@Override
protected void deleteInternal(int handle) {
GL20.glDeleteProgram(handle);
}
public static class Builder {
private final ResourceLocation name;
private final int program;
public Builder(ResourceLocation name) {
this.name = name;
this.program = GL20.glCreateProgram();
}
public Builder attachShader(GlShader shader) {
GL20.glAttachShader(this.program, shader.handle());
return this;
}
/**
* Links the attached shaders to this program and returns a user-defined container which wraps the shader
* program. This container can, for example, provide methods for updating the specific uniforms of that shader
* set.
*
* @param factory The factory which will create the shader program's container
* @param <P> The type which should be instantiated with the new program's handle
* @return An instantiated shader container as provided by the factory
*/
public <P extends GlProgram> P build(ProgramFactory<P> factory) {
GL20.glLinkProgram(this.program);
String log = GL20.glGetProgramInfoLog(this.program);
if (!log.isEmpty()) {
ShaderHelper.log.warn("Program link log for " + this.name + ": " + log);
}
int result = GL20.glGetProgrami(this.program, GL20.GL_LINK_STATUS);
if (result != GL20.GL_TRUE) {
throw new RuntimeException("Shader program linking failed, see log for details");
}
return factory.create(this.name, this.program);
}
// public Builder bindAttribute(String name, GlVertexAttribute attribute) {
// GL20.glBindAttribLocation(this.program, attribute.getIndex(), name);
//
// return this;
// }
}
@FunctionalInterface
public interface ProgramFactory<P extends GlProgram> {
P create(ResourceLocation name, int handle);
}
}

View File

@ -0,0 +1,53 @@
package com.simibubi.create.foundation.render.gl.shader;
import com.simibubi.create.foundation.render.gl.GlObject;
import com.simibubi.create.foundation.render.gl.shader.ShaderHelper;
import com.simibubi.create.foundation.render.gl.shader.ShaderType;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.opengl.GL20;
public class GlShader extends GlObject {
public final ResourceLocation name;
public final ShaderType type;
public GlShader(ShaderType type, ResourceLocation name, String source, PreProcessor preProcessor) {
this.type = type;
this.name = name;
int handle = GL20.glCreateShader(type.glEnum);
if (preProcessor != null) {
source = preProcessor.process(source);
ShaderHelper.log.info("Preprocessor run on " + name + ":\n" + source);
}
GL20.glShaderSource(handle, source);
GL20.glCompileShader(handle);
String log = GL20.glGetShaderInfoLog(handle);
if (!log.isEmpty()) {
ShaderHelper.log.warn("Shader compilation log for " + name + ": " + log);
}
if (GL20.glGetShaderi(handle, GL20.GL_COMPILE_STATUS) != GL20.GL_TRUE) {
throw new RuntimeException("Could not compile shader");
}
setHandle(handle);
}
@Override
protected void deleteInternal(int handle) {
GL20.glDeleteShader(handle);
}
@FunctionalInterface
public interface PreProcessor {
String process(String source);
default PreProcessor andThen(PreProcessor that) {
return source -> that.process(this.process(source));
}
}
}

View File

@ -1,49 +0,0 @@
package com.simibubi.create.foundation.render.gl.shader;
import net.minecraft.util.ResourceLocation;
import java.util.EnumMap;
import java.util.Map;
public class ProgramBuilder {
private final ResourceLocation name;
private final Map<ShaderType, ResourceLocation> shaders;
private ShaderConstants constants;
public ProgramBuilder(ResourceLocation name) {
this.name = name;
shaders = new EnumMap<>(ShaderType.class);
}
public ResourceLocation getName() {
return name;
}
public Map<ShaderType, ResourceLocation> getShaders() {
return shaders;
}
public ShaderConstants getConstants() {
return constants;
}
public ProgramBuilder setConstants(ShaderConstants constants) {
this.constants = constants;
return this;
}
public ProgramBuilder vert(ResourceLocation file) {
return shader(ShaderType.VERTEX, file);
}
public ProgramBuilder frag(ResourceLocation file) {
return shader(ShaderType.FRAGMENT, file);
}
public ProgramBuilder shader(ShaderType type, ResourceLocation file) {
shaders.put(type, file);
return this;
}
}

View File

@ -0,0 +1,37 @@
package com.simibubi.create.foundation.render.gl.shader;
import com.simibubi.create.Create;
import net.minecraft.util.ResourceLocation;
public class ProgramSpec<P extends GlProgram> {
public final ResourceLocation name;
public final ResourceLocation vert;
public final ResourceLocation frag;
public final ShaderConstants defines;
public final GlProgram.ProgramFactory<P> factory;
public ProgramSpec(String name, ResourceLocation vert, ResourceLocation frag, GlProgram.ProgramFactory<P> factory) {
this(name, vert, frag, factory, null);
}
public ProgramSpec(String name, ResourceLocation vert, ResourceLocation frag, GlProgram.ProgramFactory<P> factory, ShaderConstants defines) {
this.name = new ResourceLocation(Create.ID, name);
this.vert = vert;
this.frag = frag;
this.defines = defines;
this.factory = factory;
}
public ResourceLocation getVert() {
return vert;
}
public ResourceLocation getFrag() {
return frag;
}
}

View File

@ -4,14 +4,14 @@ package com.simibubi.create.foundation.render.gl.shader;
* A Callback for when a shader is called. Used to define shader uniforms.
*/
@FunctionalInterface
public interface ShaderCallback {
public interface ShaderCallback<P extends GlProgram> {
void call(int shader);
void call(P program);
default ShaderCallback andThen(ShaderCallback other) {
return i -> {
call(i);
other.call(i);
default ShaderCallback<P> andThen(ShaderCallback<P> other) {
return program -> {
call(program);
other.call(program);
};
}
}

View File

@ -1,8 +1,13 @@
package com.simibubi.create.foundation.render.gl.shader;
import java.io.BufferedReader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Spliterator;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class ShaderConstants {
public class ShaderConstants implements GlShader.PreProcessor {
private final ArrayList<String> defines;
@ -10,7 +15,11 @@ public class ShaderConstants {
defines = new ArrayList<>();
}
public ShaderConstants define(String def) {
public static ShaderConstants define(String def) {
return new ShaderConstants().def(def);
}
public ShaderConstants def(String def) {
defines.add(def);
return this;
}
@ -18,4 +27,21 @@ public class ShaderConstants {
public ArrayList<String> getDefines() {
return defines;
}
public Stream<String> directives() {
return defines.stream().map(it -> "#define " + it);
}
@Override
public String process(String source) {
return new BufferedReader(new StringReader(source)).lines().flatMap(line -> {
Stream<String> map = Stream.of(line);
if (line.startsWith("#version")) {
map = Stream.concat(map, directives());
}
return map;
}).collect(Collectors.joining("\n"));
}
}

View File

@ -1,14 +1,13 @@
package com.simibubi.create.foundation.render.gl.shader;
import com.mojang.blaze3d.platform.GlStateManager;
import com.simibubi.create.Create;
import com.simibubi.create.content.contraptions.KineticDebugger;
import com.simibubi.create.foundation.render.gl.BasicProgram;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.Matrix4f;
import net.minecraft.client.shader.IShaderManager;
import net.minecraft.client.renderer.texture.TextureUtil;
import net.minecraft.client.shader.ShaderLinkHelper;
import net.minecraft.client.shader.ShaderLoader;
import net.minecraft.resources.IReloadableResourceManager;
import net.minecraft.resources.IResourceManager;
import net.minecraft.util.ResourceLocation;
@ -16,6 +15,7 @@ import net.minecraftforge.resource.ISelectiveResourceReloadListener;
import net.minecraftforge.resource.VanillaResourceType;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.lwjgl.opengl.GL20;
import org.lwjgl.system.MemoryUtil;
import javax.annotation.Nullable;
@ -23,143 +23,87 @@ import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.FloatBuffer;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.Map;
public class ShaderHelper {
public static final Logger log = LogManager.getLogger("shader");
public static final Logger log = LogManager.getLogger(ShaderHelper.class);
public static final FloatBuffer FLOAT_BUFFER = MemoryUtil.memAllocFloat(1); // TODO: these leak 80 bytes of memory per program launch
public static final FloatBuffer VEC3_BUFFER = MemoryUtil.memAllocFloat(3);
public static final FloatBuffer MATRIX_BUFFER = MemoryUtil.memAllocFloat(16);
private static final Map<AllShaderPrograms, ShaderProgram> PROGRAMS = new EnumMap<>(AllShaderPrograms.class);
private static final Map<ResourceLocation, ProgramSpec<?>> REGISTRY = new HashMap<>();
private static final Map<ProgramSpec<?>, GlProgram> PROGRAMS = new HashMap<>();
public static <P extends GlProgram, S extends ProgramSpec<P>> S register(S spec) {
ResourceLocation name = spec.name;
if (REGISTRY.containsKey(name)) {
throw new IllegalStateException("Program spec '" + name + "' already registered.");
}
REGISTRY.put(name, spec);
return spec;
}
@SuppressWarnings("deprecation")
public static void initShaders() {
// Can be null when running datagenerators due to the unfortunate time we call this
if (Minecraft.getInstance() != null
&& Minecraft.getInstance().getResourceManager() instanceof IReloadableResourceManager) {
((IReloadableResourceManager) Minecraft.getInstance().getResourceManager()).addReloadListener(
(ISelectiveResourceReloadListener) (manager, predicate) -> {
if (predicate.test(VanillaResourceType.SHADERS)) {
PROGRAMS.values().forEach(ShaderLinkHelper::deleteShader);
PROGRAMS.clear();
for (AllShaderPrograms shader : AllShaderPrograms.values()) {
createProgram(manager, shader);
}
}
});
Minecraft mc = Minecraft.getInstance();
if (mc != null && mc.getResourceManager() instanceof IReloadableResourceManager) {
ISelectiveResourceReloadListener listener = (manager, predicate) -> {
if (predicate.test(VanillaResourceType.SHADERS)) {
PROGRAMS.values().forEach(GlProgram::delete);
PROGRAMS.clear();
for (ProgramSpec<?> shader : REGISTRY.values()) {
loadProgram(manager, shader);
}
}
};
((IReloadableResourceManager) mc.getResourceManager()).addReloadListener(listener);
}
}
public static int getShaderHandle(AllShaderPrograms shader) {
ShaderProgram shaderProgram = PROGRAMS.get(shader);
return shaderProgram.getProgram();
}
public static ShaderCallback getViewProjectionCallback(Matrix4f projectionMat, Matrix4f viewMat) {
return shader -> {
ShaderHelper.MATRIX_BUFFER.position(0);
projectionMat.write(ShaderHelper.MATRIX_BUFFER);
int projection = GlStateManager.getUniformLocation(shader, "projection");
GlStateManager.uniformMatrix4(projection, false, ShaderHelper.MATRIX_BUFFER);
ShaderHelper.MATRIX_BUFFER.position(0);
viewMat.write(ShaderHelper.MATRIX_BUFFER);
int view = GlStateManager.getUniformLocation(shader, "view");
GlStateManager.uniformMatrix4(view, false, ShaderHelper.MATRIX_BUFFER);
};
}
public static int useShader(AllShaderPrograms shader) {
return useShader(shader, null);
}
public static int useShader(AllShaderPrograms shader, @Nullable ShaderCallback cb) {
ShaderProgram prog = PROGRAMS.get(shader);
if (prog == null) {
return -1;
}
int program = prog.getProgram();
ShaderLinkHelper.useProgram(program);
int time = GlStateManager.getUniformLocation(program, "time");
FLOAT_BUFFER.position(0);
FLOAT_BUFFER.put(0, AnimationTickHolder.getRenderTick());
GlStateManager.uniform1(time, FLOAT_BUFFER);
int ticks = GlStateManager.getUniformLocation(program, "ticks");
GlStateManager.uniform1(ticks, AnimationTickHolder.ticks);
int debug = GlStateManager.getUniformLocation(program, "debug");
GlStateManager.uniform1(debug, KineticDebugger.isActive() ? 1 : 0);
if (cb != null) {
cb.call(program);
}
return program;
@SuppressWarnings("unchecked")
public static <P extends GlProgram, S extends ProgramSpec<P>> P getProgram(S spec) {
return (P) PROGRAMS.get(spec);
}
public static void releaseShader() {
ShaderLinkHelper.useProgram(0);
GL20.glUseProgram(0);
}
private static void createProgram(IResourceManager manager, AllShaderPrograms shader) {
private static <P extends GlProgram, S extends ProgramSpec<P>> void loadProgram(IResourceManager manager, S programSpec) {
GlShader vert = null;
GlShader frag = null;
try {
ShaderLoader vert = createShader(manager, shader.vert, ShaderLoader.ShaderType.VERTEX);
ShaderLoader frag = createShader(manager, shader.frag, ShaderLoader.ShaderType.FRAGMENT);
int progId = ShaderLinkHelper.createProgram();
ShaderProgram prog = new ShaderProgram(progId, vert, frag);
ShaderLinkHelper.linkProgram(prog);
PROGRAMS.put(shader, prog);
vert = loadShader(manager, programSpec.getVert(), ShaderType.VERTEX, programSpec.defines);
frag = loadShader(manager, programSpec.getFrag(), ShaderType.FRAGMENT, programSpec.defines);
log.info("Loaded program {}", shader.name());
P program = GlProgram.builder(programSpec.name)
.attachShader(vert)
.attachShader(frag)
.build(programSpec.factory);
PROGRAMS.put(programSpec, program);
log.info("Loaded program {}", programSpec.name);
} catch (IOException ex) {
log.error("Failed to load program {}", shader.name(), ex);
log.error("Failed to load program {}", programSpec.name, ex);
} finally {
if (vert != null) vert.delete();
if (frag != null) frag.delete();
}
}
private static ShaderLoader createShader(IResourceManager manager, String filename, ShaderLoader.ShaderType shaderType) throws IOException {
ResourceLocation loc = new ResourceLocation(Create.ID, filename);
try (InputStream is = new BufferedInputStream(manager.getResource(loc).getInputStream())) {
return ShaderLoader.func_216534_a(shaderType, loc.toString(), is); // , shaderType.name().toLowerCase(Locale.ROOT));
}
}
private static GlShader loadShader(IResourceManager manager, ResourceLocation name, ShaderType type, GlShader.PreProcessor preProcessor) throws IOException {
try (InputStream is = new BufferedInputStream(manager.getResource(name).getInputStream())) {
String source = TextureUtil.func_225687_b_(is);
private static class ShaderProgram implements IShaderManager {
private final int program;
private final ShaderLoader vert;
private final ShaderLoader frag;
private ShaderProgram(int program, ShaderLoader vert, ShaderLoader frag) {
this.program = program;
this.vert = vert;
this.frag = frag;
}
@Override
public int getProgram() {
return program;
}
@Override
public void markDirty() {
}
@Override
public ShaderLoader getVertexShaderLoader() {
return vert;
}
@Override
public ShaderLoader getFragmentShaderLoader() {
return frag;
if (source == null) {
throw new IOException("Could not load program " + name);
} else {
return new GlShader(type, name, source, preProcessor);
}
}
}
}

View File

@ -1,6 +1,15 @@
package com.simibubi.create.foundation.render.gl.shader;
import org.lwjgl.opengl.GL20;
public enum ShaderType {
VERTEX,
FRAGMENT,
VERTEX(GL20.GL_VERTEX_SHADER),
FRAGMENT(GL20.GL_FRAGMENT_SHADER),
;
public final int glEnum;
ShaderType(int glEnum) {
this.glEnum = glEnum;
}
}

View File

@ -2,18 +2,20 @@ package com.simibubi.create.foundation.render.instancing;
import com.simibubi.create.foundation.block.render.SpriteShiftEntry;
import com.simibubi.create.foundation.render.gl.GlPrimitiveType;
import com.simibubi.create.foundation.render.gl.attrib.CommonAttributes;
import com.simibubi.create.foundation.render.gl.attrib.VertexAttribute;
import com.simibubi.create.foundation.render.gl.attrib.VertexFormat;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.vertex.VertexFormatElement;
import java.nio.ByteBuffer;
import static com.simibubi.create.foundation.render.instancing.VertexAttribute.*;
import static com.simibubi.create.foundation.render.gl.attrib.VertexAttribute.*;
public class BeltData extends KineticData<BeltData> {
public static final VertexAttribute TARGET_UV = copy("scrollTexture", VEC4);
public static final VertexAttribute TARGET_UV = copy("scrollTexture", CommonAttributes.VEC4);
public static final VertexAttribute SCROLL_MULT = new VertexAttribute("scrollMult", GlPrimitiveType.BYTE, 1, true);
public static VertexFormat FORMAT = new VertexFormat(KineticData.FORMAT, ROTATION, UV, TARGET_UV, SCROLL_MULT);
public static VertexFormat FORMAT = new VertexFormat(KineticData.FORMAT, CommonAttributes.ROTATION, CommonAttributes.UV, TARGET_UV, SCROLL_MULT);
private float rotX;
private float rotY;

View File

@ -1,5 +1,6 @@
package com.simibubi.create.foundation.render.instancing;
import com.simibubi.create.foundation.render.gl.attrib.VertexFormat;
import net.minecraft.client.renderer.BufferBuilder;
public class BeltModel extends InstancedModel<BeltData> {

View File

@ -1,6 +1,7 @@
package com.simibubi.create.foundation.render.instancing;
import com.simibubi.create.foundation.render.gl.GlBuffer;
import com.simibubi.create.foundation.render.gl.attrib.VertexFormat;
import net.minecraft.client.renderer.BufferBuilder;
public abstract class DynamicInstancedModel<S extends InstanceData, D extends InstanceData> extends InstancedModel<S> {

View File

@ -1,6 +1,5 @@
package com.simibubi.create.foundation.render.instancing;
import com.simibubi.create.foundation.render.InstancedTileRenderer;
import net.minecraft.tileentity.TileEntity;
@FunctionalInterface

View File

@ -1,44 +0,0 @@
package com.simibubi.create.foundation.render.instancing;
import com.simibubi.create.CreateClient;
import com.simibubi.create.foundation.render.InstancedTileRenderer;
import net.minecraft.tileentity.TileEntity;
@Deprecated
public abstract class InstanceContext<T extends TileEntity> {
public final T te;
public InstanceContext(T te) {
this.te = te;
}
public RenderMaterial<InstancedModel<RotatingData>> getRotating() {
return getKinetics().get(KineticRenderMaterials.ROTATING);
}
public RenderMaterial<InstancedModel<BeltData>> getBelts() {
return getKinetics().get(KineticRenderMaterials.BELTS);
}
public abstract InstancedTileRenderer getKinetics();
public abstract boolean checkWorldLight();
public static class World<T extends TileEntity> extends InstanceContext<T> {
public World(T te) {
super(te);
}
@Override
public InstancedTileRenderer getKinetics() {
return CreateClient.kineticRenderer;
}
@Override
public boolean checkWorldLight() {
return true;
}
}
}

View File

@ -3,6 +3,8 @@ package com.simibubi.create.foundation.render.instancing;
import com.simibubi.create.foundation.render.BufferedModel;
import com.simibubi.create.foundation.render.RenderMath;
import com.simibubi.create.foundation.render.gl.attrib.CommonAttributes;
import com.simibubi.create.foundation.render.gl.attrib.VertexFormat;
import com.simibubi.create.foundation.render.gl.backend.Backend;
import com.simibubi.create.foundation.render.gl.GlBuffer;
import net.minecraft.client.renderer.BufferBuilder;
@ -15,10 +17,8 @@ import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.function.Consumer;
import static com.simibubi.create.foundation.render.instancing.VertexAttribute.*;
public abstract class InstancedModel<D extends InstanceData> extends BufferedModel {
public static final VertexFormat FORMAT = new VertexFormat(POSITION, NORMAL, UV);
public static final VertexFormat FORMAT = new VertexFormat(CommonAttributes.POSITION, CommonAttributes.NORMAL, CommonAttributes.UV);
protected GlBuffer instanceVBO;
protected int glBufferSize = -1;

View File

@ -1,7 +1,6 @@
package com.simibubi.create.foundation.render.instancing;
import com.google.common.collect.Maps;
import com.simibubi.create.foundation.render.InstancedTileRenderer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityType;

View File

@ -1,9 +1,9 @@
package com.simibubi.create.foundation.render;
package com.simibubi.create.foundation.render.instancing;
import com.simibubi.create.foundation.render.gl.shader.AllShaderPrograms;
import com.simibubi.create.foundation.render.FastRenderDispatcher;
import com.simibubi.create.foundation.render.gl.BasicProgram;
import com.simibubi.create.foundation.render.gl.shader.ShaderCallback;
import com.simibubi.create.foundation.render.gl.shader.ShaderHelper;
import com.simibubi.create.foundation.render.instancing.*;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import net.minecraft.client.renderer.Matrix4f;
import net.minecraft.client.renderer.RenderType;
@ -13,23 +13,20 @@ import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.Map;
public class InstancedTileRenderer {
protected Map<TileEntity, TileEntityInstance<?>> renderers = new HashMap<>();
public abstract class InstancedTileRenderer<P extends BasicProgram> {
protected Map<TileEntity, TileEntityInstance<?>> instances = new HashMap<>();
protected Map<MaterialType<?>, RenderMaterial<?>> materials = new HashMap<>();
protected Map<MaterialType<?>, RenderMaterial<P, ?>> materials = new HashMap<>();
public InstancedTileRenderer() {
protected InstancedTileRenderer() {
registerMaterials();
}
public void registerMaterials() {
materials.put(KineticRenderMaterials.BELTS, new RenderMaterial<>(AllShaderPrograms.BELT, BeltModel::new));
materials.put(KineticRenderMaterials.ROTATING, new RenderMaterial<>(AllShaderPrograms.ROTATING, RotatingModel::new));
}
public abstract void registerMaterials();
@SuppressWarnings("unchecked")
public <M extends InstancedModel<?>> RenderMaterial<M> get(MaterialType<M> materialType) {
return (RenderMaterial<M>) materials.get(materialType);
public <M extends InstancedModel<?>> RenderMaterial<P, M> getMaterial(MaterialType<M> materialType) {
return (RenderMaterial<P, M>) materials.get(materialType);
}
@Nullable
@ -40,7 +37,7 @@ public class InstancedTileRenderer {
@SuppressWarnings("unchecked")
@Nullable
public <T extends TileEntity> TileEntityInstance<? super T> getInstance(T tile, boolean create) {
TileEntityInstance<?> instance = renderers.get(tile);
TileEntityInstance<?> instance = instances.get(tile);
if (instance != null) {
return (TileEntityInstance<? super T>) instance;
@ -49,7 +46,7 @@ public class InstancedTileRenderer {
if (renderer != null) {
FastRenderDispatcher.addedLastTick.get(tile.getWorld()).add(tile);
renderers.put(tile, renderer);
instances.put(tile, renderer);
}
return renderer;
@ -88,7 +85,7 @@ public class InstancedTileRenderer {
if (instance != null) {
instance.remove();
renderers.remove(tile);
instances.remove(tile);
}
}
}
@ -97,25 +94,25 @@ public class InstancedTileRenderer {
// Clean up twice a second. This doesn't have to happen every tick,
// but this does need to be run to ensure we don't miss anything.
if (AnimationTickHolder.ticks % 10 == 0) {
renderers.keySet().stream().filter(TileEntity::isRemoved).forEach(renderers::remove);
instances.keySet().stream().filter(TileEntity::isRemoved).forEach(instances::remove);
}
}
public void invalidate() {
for (RenderMaterial<?> material : materials.values()) {
for (RenderMaterial<?, ?> material : materials.values()) {
material.delete();
}
renderers.clear();
instances.clear();
}
public void render(RenderType layer, Matrix4f projection, Matrix4f view) {
render(layer, projection, view, null);
public void render(RenderType layer, Matrix4f viewProjection) {
render(layer, viewProjection, null);
}
public void render(RenderType layer, Matrix4f projection, Matrix4f view, ShaderCallback callback) {
for (RenderMaterial<?> material : materials.values()) {
public void render(RenderType layer, Matrix4f viewProjection, ShaderCallback<P> callback) {
for (RenderMaterial<P, ?> material : materials.values()) {
if (material.canRenderInLayer(layer))
material.render(layer, projection, view, callback);
material.render(layer, viewProjection, callback);
}
ShaderHelper.releaseShader();

View File

@ -1,19 +1,22 @@
package com.simibubi.create.foundation.render.instancing;
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.foundation.render.gl.attrib.CommonAttributes;
import com.simibubi.create.foundation.render.gl.attrib.VertexAttribute;
import com.simibubi.create.foundation.render.gl.attrib.VertexFormat;
import com.simibubi.create.foundation.utility.ColorHelper;
import net.minecraft.client.renderer.Vector3f;
import net.minecraft.util.math.BlockPos;
import java.nio.ByteBuffer;
import static com.simibubi.create.foundation.render.instancing.VertexAttribute.*;
import static com.simibubi.create.foundation.render.gl.attrib.VertexAttribute.*;
public class KineticData<D extends KineticData<D>> extends InstanceData {
public static final VertexAttribute ROTATION_CENTER = copy("rotationCenter", VEC3);
public static final VertexAttribute SPEED = copy("speed", FLOAT);
public static final VertexAttribute OFFSET = copy("offset", FLOAT);
public static final VertexFormat FORMAT = new VertexFormat(INSTANCE_POSITION, LIGHT, RGB, SPEED, OFFSET);
public static final VertexAttribute ROTATION_CENTER = copy("rotationCenter", CommonAttributes.VEC3);
public static final VertexAttribute SPEED = copy("speed", CommonAttributes.FLOAT);
public static final VertexAttribute OFFSET = copy("offset", CommonAttributes.FLOAT);
public static final VertexFormat FORMAT = new VertexFormat(CommonAttributes.INSTANCE_POSITION, CommonAttributes.LIGHT, CommonAttributes.RGB, SPEED, OFFSET);
private float x;
private float y;

View File

@ -7,7 +7,8 @@ import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.foundation.render.Compartment;
import com.simibubi.create.foundation.render.SuperByteBufferCache;
import com.simibubi.create.foundation.render.gl.shader.AllShaderPrograms;
import com.simibubi.create.foundation.render.gl.BasicProgram;
import com.simibubi.create.foundation.render.gl.shader.ProgramSpec;
import com.simibubi.create.foundation.render.gl.shader.ShaderCallback;
import com.simibubi.create.foundation.render.gl.shader.ShaderHelper;
import net.minecraft.block.BlockState;
@ -29,24 +30,24 @@ import java.util.function.Supplier;
import static com.simibubi.create.foundation.render.Compartment.PARTIAL;
public class RenderMaterial<MODEL extends InstancedModel<?>> {
public class RenderMaterial<P extends BasicProgram, MODEL extends InstancedModel<?>> {
protected final Map<Compartment<?>, Cache<Object, MODEL>> models;
protected final ModelFactory<MODEL> factory;
protected final AllShaderPrograms shader;
protected final ProgramSpec<P> programSpec;
protected final Predicate<RenderType> layerPredicate;
/**
* Creates a material that renders in the default layer (CUTOUT_MIPPED)
*/
public RenderMaterial(AllShaderPrograms shader, ModelFactory<MODEL> factory) {
this(shader, factory, type -> type == RenderType.getCutoutMipped());
public RenderMaterial(ProgramSpec<P> programSpec, ModelFactory<MODEL> factory) {
this(programSpec, factory, type -> type == RenderType.getCutoutMipped());
}
public RenderMaterial(AllShaderPrograms shader, ModelFactory<MODEL> factory, Predicate<RenderType> layerPredicate) {
public RenderMaterial(ProgramSpec<P> programSpec, ModelFactory<MODEL> factory, Predicate<RenderType> layerPredicate) {
this.models = new HashMap<>();
this.factory = factory;
this.shader = shader;
this.programSpec = programSpec;
this.layerPredicate = layerPredicate;
registerCompartment(Compartment.PARTIAL);
registerCompartment(Compartment.DIRECTIONAL_PARTIAL);
@ -57,16 +58,16 @@ public class RenderMaterial<MODEL extends InstancedModel<?>> {
return layerPredicate.test(layer);
}
public void render(RenderType layer, Matrix4f projection, Matrix4f view) {
render(layer, projection, view, null);
public void render(RenderType layer, Matrix4f projection) {
render(layer, projection, null);
}
public void render(RenderType layer, Matrix4f projection, Matrix4f view, ShaderCallback setup) {
ShaderCallback cb = ShaderHelper.getViewProjectionCallback(projection, view);
public void render(RenderType layer, Matrix4f viewProjection, ShaderCallback<P> setup) {
P program = ShaderHelper.getProgram(programSpec);
program.bind(viewProjection, 0);
if (setup != null) cb = cb.andThen(setup);
if (setup != null) setup.call(program);
ShaderHelper.useShader(shader, cb);
makeRenderCalls();
teardown();
}

View File

@ -1,11 +1,12 @@
package com.simibubi.create.foundation.render.instancing;
import com.simibubi.create.foundation.render.gl.attrib.VertexFormat;
import net.minecraft.client.renderer.Vector3f;
import net.minecraft.util.Direction;
import java.nio.ByteBuffer;
import static com.simibubi.create.foundation.render.instancing.VertexAttribute.NORMAL;
import static com.simibubi.create.foundation.render.gl.attrib.CommonAttributes.NORMAL;
public class RotatingData extends KineticData<RotatingData> {
public static VertexFormat FORMAT = new VertexFormat(KineticData.FORMAT, NORMAL);

View File

@ -1,5 +1,6 @@
package com.simibubi.create.foundation.render.instancing;
import com.simibubi.create.foundation.render.gl.attrib.VertexFormat;
import net.minecraft.client.renderer.BufferBuilder;
public class RotatingModel extends InstancedModel<RotatingData> {

View File

@ -1,6 +1,5 @@
package com.simibubi.create.foundation.render.instancing;
import com.simibubi.create.foundation.render.InstancedTileRenderer;
import net.minecraft.block.BlockState;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
@ -8,13 +7,13 @@ import net.minecraft.world.World;
public abstract class TileEntityInstance<T extends TileEntity> {
protected final InstancedTileRenderer modelManager;
protected final InstancedTileRenderer<?> modelManager;
protected final T tile;
protected final World world;
protected final BlockPos pos;
protected BlockState lastState;
public TileEntityInstance(InstancedTileRenderer modelManager, T tile) {
public TileEntityInstance(InstancedTileRenderer<?> modelManager, T tile) {
this.modelManager = modelManager;
this.tile = tile;
this.world = tile.getWorld();

View File

@ -1,13 +1,12 @@
package com.simibubi.create.foundation.render.instancing.actors;
import com.simibubi.create.foundation.render.instancing.InstanceData;
import com.simibubi.create.foundation.render.instancing.VertexFormat;
import com.simibubi.create.foundation.render.gl.attrib.VertexFormat;
import net.minecraft.client.renderer.Vector3f;
import java.nio.ByteBuffer;
import static com.simibubi.create.foundation.render.instancing.VertexAttribute.*;
import static com.simibubi.create.foundation.render.instancing.VertexAttribute.NORMAL;
import static com.simibubi.create.foundation.render.gl.attrib.CommonAttributes.NORMAL;
public class DynamicRotatingActorData extends InstanceData {
public static VertexFormat FORMAT = new VertexFormat(NORMAL);

View File

@ -1,7 +1,7 @@
package com.simibubi.create.foundation.render.instancing.actors;
import com.simibubi.create.foundation.render.instancing.DynamicInstancedModel;
import com.simibubi.create.foundation.render.instancing.VertexFormat;
import com.simibubi.create.foundation.render.gl.attrib.VertexFormat;
import net.minecraft.client.renderer.BufferBuilder;
public class RotatingActorModel extends DynamicInstancedModel<StaticRotatingActorData, DynamicRotatingActorData> {

View File

@ -1,16 +1,15 @@
package com.simibubi.create.foundation.render.instancing.actors;
import com.simibubi.create.foundation.render.gl.attrib.CommonAttributes;
import com.simibubi.create.foundation.render.instancing.InstanceData;
import com.simibubi.create.foundation.render.instancing.VertexFormat;
import com.simibubi.create.foundation.render.gl.attrib.VertexFormat;
import net.minecraft.client.renderer.Vector3f;
import net.minecraft.util.math.BlockPos;
import java.nio.ByteBuffer;
import static com.simibubi.create.foundation.render.instancing.VertexAttribute.*;
public class StaticRotatingActorData extends InstanceData {
public static VertexFormat FORMAT = new VertexFormat(POSITION, LIGHT, FLOAT, NORMAL, VEC3, NORMAL);
public static VertexFormat FORMAT = new VertexFormat(CommonAttributes.POSITION, CommonAttributes.LIGHT, CommonAttributes.FLOAT, CommonAttributes.NORMAL, CommonAttributes.VEC3, CommonAttributes.NORMAL);
private float x;
private float y;

View File

@ -16,15 +16,23 @@ layout (location = 10) in vec4 scrollTexture;
layout (location = 11) in float scrollMult;
out vec2 TexCoords;
out vec2 Light;
out float Diffuse;
out vec4 Color;
out float Diffuse;
out vec2 Light;
#if defined(CONTRAPTION)
out vec3 BoxCoord;
uniform vec3 uLightBoxSize;
uniform vec3 uLightBoxMin;
uniform mat4 uModel;
#endif
uniform int uTicks;
uniform float uTime;
uniform mat4 uViewProjection;
uniform int uDebug;
uniform float time;
uniform int ticks;
uniform mat4 projection;
uniform mat4 view;
uniform int debug;
mat4 rotate(vec3 axis, float angle) {
float s = sin(angle);
@ -37,10 +45,6 @@ mat4 rotate(vec3 axis, float angle) {
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);
}
float diffuse(vec3 normal) {
float x = normal.x;
float y = normal.y;
@ -48,6 +52,10 @@ float diffuse(vec3 normal) {
return min(x * x * .6 + y * y * ((3 + y) / 4) + z * z * .8, 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 localRotation() {
vec3 rot = fract(eulerAngles / 360) * PI * 2;
return rotation(rot);
@ -55,23 +63,41 @@ mat4 localRotation() {
void main() {
mat4 localRotation = localRotation();
vec4 renderPos = localRotation * vec4(aPos - vec3(.5), 1) + vec4(instancePos + vec3(.5), 0);
vec4 worldPos = localRotation * vec4(aPos - .5, 1) + vec4(instancePos + .5, 0);
#ifdef CONTRAPTION
worldPos = uModel * worldPos;
BoxCoord = (worldPos.xyz - uLightBoxMin) / uLightBoxSize;
mat4 normalMat = uModel * localRotation;
#else
mat4 normalMat = localRotation;
#endif
vec3 norm = normalize(normalMat * vec4(aNormal, 0)).xyz;
float scrollSize = scrollTexture.w - scrollTexture.y;
float scroll = fract(speed * time / (36 * 16) + offset) * scrollSize * scrollMult;
vec3 norm = (localRotation * vec4(aNormal, 0)).xyz;
float scroll = fract(speed * uTime / (36 * 16) + offset) * scrollSize * scrollMult;
Diffuse = diffuse(norm);
Light = light;
TexCoords = aTexCoords - uv + scrollTexture.xy + vec2(0, scroll);
gl_Position = projection * view * renderPos;
Light = light;
gl_Position = uViewProjection * worldPos;
if (debug == 1) {
Color = vec4(networkTint, 1);
} else if (debug == 2) {
#ifdef CONTRAPTION
if (uDebug == 2) {
Color = vec4(norm, 1);
} else {
Color = vec4(1);
}
#else
if (uDebug == 1) {
Color = vec4(networkTint, 1);
} else if (uDebug == 2) {
Color = vec4(norm, 1);
} else {
Color = vec4(1);
}
#endif
}

View File

@ -1,24 +1,25 @@
#version 440 core
#version 330 core
in vec2 TexCoords;
in vec4 Color;
in float Diffuse;
in vec2 Light;
in vec3 BoxCoord;
in vec2 ModelLight;
out vec4 fragColor;
layout(binding=0) uniform sampler2D BlockAtlas;
layout(binding=2) uniform sampler2D LightMap;
layout(binding=4) uniform sampler3D LightVolume;
uniform sampler2D uBlockAtlas;
uniform sampler2D uLightMap;
uniform sampler3D uLightVolume;
vec4 light() {
vec2 lm = texture(LightVolume, BoxCoord).rg * 0.9375 + 0.03125;
return texture2D(LightMap, max(lm, ModelLight));
vec2 lm = texture(uLightVolume, BoxCoord).rg * 0.9375 + 0.03125;
return texture2D(uLightMap, max(lm, Light));
}
void main() {
vec4 tex = texture2D(BlockAtlas, TexCoords);
vec4 tex = texture2D(uBlockAtlas, TexCoords);
fragColor = vec4(tex.rgb * light().rgb * Diffuse * Color.rgb, tex.a);
}

View File

@ -20,17 +20,16 @@ out float Diffuse;
out vec2 TexCoords;
out vec4 Color;
out vec3 BoxCoord;
out vec2 ModelLight;
out vec2 Light;
uniform vec3 lightBoxSize;
uniform vec3 lightBoxMin;
uniform mat4 model;
uniform vec3 uLightBoxSize;
uniform vec3 uLightBoxMin;
uniform mat4 uModel;
uniform float time;
uniform int ticks;
uniform mat4 projection;
uniform mat4 view;
uniform int debug;
uniform int uTicks;
uniform float uTime;
uniform mat4 uViewProjection;
uniform int uDebug;
mat4 rotate(vec3 axis, float angle) {
@ -57,7 +56,7 @@ mat4 rotation(vec3 rot) {
mat4 kineticRotation() {
const float speed = -20;
float degrees = rotationOffset + time * speed * -3/10;
float degrees = rotationOffset + uTime * speed * -3/10;
float angle = fract(degrees / 360) * PI * 2;
return rotate(normalize(localRotationAxis), angle);
@ -72,17 +71,17 @@ void main() {
mat4 localRot = rotation(rot);
localPos = localRot * vec4(localPos.xyz - .5, 1) + vec4(instancePos + .5, 0);
vec4 worldPos = model * localPos;
vec4 worldPos = uModel * localPos;
vec3 norm = normalize(model * localRot * kineticRotation * vec4(aNormal, 0)).xyz;
vec3 norm = normalize(uModel * localRot * kineticRotation * vec4(aNormal, 0)).xyz;
BoxCoord = (worldPos.xyz - lightBoxMin) / lightBoxSize;
BoxCoord = (worldPos.xyz - uLightBoxMin) / uLightBoxSize;
Diffuse = diffuse(norm);
TexCoords = aTexCoords;
ModelLight = modelLight;
gl_Position = projection * view * worldPos;
Light = modelLight;
gl_Position = uViewProjection * worldPos;
if (debug == 2) {
if (uDebug == 2) {
Color = vec4(norm, 1);
} else {
Color = vec4(1);

View File

@ -1,84 +0,0 @@
#version 420 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 networkTint;
layout (location = 6) in float speed;
layout (location = 7) in float offset;
layout (location = 8) in vec3 eulerAngles;
layout (location = 9) in vec2 uv;
layout (location = 10) in vec4 scrollTexture;
layout (location = 11) in float scrollMult;
out float Diffuse;
out vec2 TexCoords;
out vec4 Color;
out vec3 BoxCoord;
out vec2 ModelLight;
uniform vec3 lightBoxSize;
uniform vec3 lightBoxMin;
uniform mat4 model;
uniform float time;
uniform int ticks;
uniform mat4 projection;
uniform mat4 view;
uniform int debug;
mat4 rotate(vec3 axis, float angle) {
float s = sin(angle);
float c = cos(angle);
float oc = 1 - 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);
}
float diffuse(vec3 normal) {
float x = normal.x;
float y = normal.y;
float z = normal.z;
return min(x * x * .6 + y * y * ((3 + y) / 4) + z * z * .8, 1);
}
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 localRotation() {
vec3 rot = fract(eulerAngles / 360) * PI * 2;
return rotation(rot);
}
void main() {
mat4 localRotation = localRotation();
vec4 localPos = localRotation * vec4(aPos - .5, 1) + vec4(instancePos + .5, 0);
vec4 worldPos = model * localPos;
float scrollSize = scrollTexture.w - scrollTexture.y;
float scroll = fract(speed * time / (36 * 16) + offset) * scrollSize * scrollMult;
vec3 norm = normalize(model * localRotation * vec4(aNormal, 0)).xyz;
BoxCoord = (worldPos.xyz - lightBoxMin) / lightBoxSize;
Diffuse = diffuse(norm);
TexCoords = aTexCoords - uv + scrollTexture.xy + vec2(0, scroll);
ModelLight = light;
gl_Position = projection * view * worldPos;
if (debug == 2) {
Color = vec4(norm, 1);
} else {
Color = vec4(1);
}
}

View File

@ -1,79 +0,0 @@
#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 networkTint;
layout (location = 6) in float speed;
layout (location = 7) in float offset;
layout (location = 8) in vec3 rotationAxis;
out float Diffuse;
out vec2 TexCoords;
out vec4 Color;
out vec3 BoxCoord;
out vec2 ModelLight;
uniform vec3 lightBoxSize;
uniform vec3 lightBoxMin;
uniform mat4 model;
uniform float time;
uniform int ticks;
uniform mat4 projection;
uniform mat4 view;
uniform int debug;
mat4 rotate(vec3 axis, float angle) {
float s = sin(angle);
float c = cos(angle);
float oc = 1 - 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);
}
float diffuse(vec3 normal) {
float x = normal.x;
float y = normal.y;
float z = normal.z;
return min(x * x * .6 + y * y * ((3 + y) / 4) + z * z * .8, 1);
}
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 kineticRotation() {
float degrees = offset + time * speed * -3/10;
float angle = fract(degrees / 360) * PI * 2;
return rotate(rotationAxis, angle);
}
void main() {
mat4 kineticRotation = kineticRotation();
vec4 localPos = kineticRotation * vec4(aPos - 0.5, 1) + vec4(instancePos + .5, 0);
vec4 worldPos = model * localPos;
vec3 norm = normalize(model * kineticRotation * vec4(aNormal, 0)).xyz;
BoxCoord = (worldPos.xyz - lightBoxMin) / lightBoxSize;
Diffuse = diffuse(norm);
TexCoords = aTexCoords;
ModelLight = light;
gl_Position = projection * view * worldPos;
if (debug == 2) {
Color = vec4(norm, 1);
} else {
Color = vec4(1);
}
}

View File

@ -1,4 +1,4 @@
#version 440 core
#version 330 core
#define PI 3.1415926538
layout (location = 0) in vec3 aPos;
@ -11,17 +11,16 @@ out float Diffuse;
out vec2 TexCoords;
out vec4 Color;
out vec3 BoxCoord;
out vec2 ModelLight;
out vec2 Light;
uniform vec3 lightBoxSize;
uniform vec3 lightBoxMin;
uniform mat4 model;
uniform vec3 uLightBoxSize;
uniform vec3 uLightBoxMin;
uniform mat4 uModel;
uniform float time;
uniform int ticks;
uniform mat4 projection;
uniform mat4 view;
uniform int debug;
uniform int uTicks;
uniform float uTime;
uniform mat4 uViewProjection;
uniform int uDebug;
mat4 rotate(vec3 axis, float angle) {
float s = sin(angle);
@ -42,18 +41,18 @@ float diffuse(vec3 normal) {
}
void main() {
vec4 worldPos = model * vec4(aPos, 1);
vec4 worldPos = uModel * vec4(aPos, 1);
vec3 norm = (model * vec4(aNormal, 0)).xyz;
vec3 norm = (uModel * vec4(aNormal, 0)).xyz;
BoxCoord = (worldPos.xyz - lightBoxMin) / lightBoxSize;
BoxCoord = (worldPos.xyz - uLightBoxMin) / uLightBoxSize;
Diffuse = diffuse(norm);
Color = aColor / diffuse(aNormal);
TexCoords = aTexCoords;
ModelLight = modelLight;
gl_Position = projection * view * worldPos;
Light = modelLight;
gl_Position = uViewProjection * worldPos;
if (debug == 2) {
if (uDebug == 2) {
Color = vec4(norm, 1);
} else {
Color = aColor / diffuse(aNormal);

View File

@ -1,4 +1,4 @@
#version 440 core
#version 330 core
in vec2 TexCoords;
in vec2 Light;
@ -7,16 +7,16 @@ in vec4 Color;
out vec4 fragColor;
layout(binding=0) uniform sampler2D BlockAtlas;
layout(binding=2) uniform sampler2D LightMap;
uniform sampler2D uBlockAtlas;
uniform sampler2D uLightMap;
vec4 light() {
vec2 lm = Light * 0.9375 + 0.03125;
return texture2D(LightMap, lm);
return texture2D(uLightMap, lm);
}
void main() {
vec4 tex = texture2D(BlockAtlas, TexCoords);
vec4 tex = texture2D(uBlockAtlas, TexCoords);
fragColor = vec4(tex.rgb * light().rgb * Diffuse, tex.a) * Color;
}

View File

@ -12,15 +12,22 @@ layout (location = 7) in float offset;
layout (location = 8) in vec3 rotationAxis;
out vec2 TexCoords;
out vec2 Light;
out float Diffuse;
out vec4 Color;
out float Diffuse;
out vec2 Light;
uniform float time;
uniform int ticks;
uniform mat4 projection;
uniform mat4 view;
uniform int debug;
#if defined(CONTRAPTION)
out vec3 BoxCoord;
uniform vec3 uLightBoxSize;
uniform vec3 uLightBoxMin;
uniform mat4 uModel;
#endif
uniform int uTicks;
uniform float uTime;
uniform mat4 uViewProjection;
uniform int uDebug;
mat4 rotate(vec3 axis, float angle) {
float s = sin(angle);
@ -45,7 +52,7 @@ mat4 rotation(vec3 rot) {
}
mat4 kineticRotation() {
float degrees = offset + time * speed * -3/10;
float degrees = offset + uTime * speed * -3/10;
float angle = fract(degrees / 360) * PI * 2;
return rotate(rotationAxis, angle);
@ -53,20 +60,38 @@ mat4 kineticRotation() {
void main() {
mat4 kineticRotation = kineticRotation();
vec4 localPos = kineticRotation * vec4(aPos - 0.5, 1) + vec4(instancePos + .5, 0);
vec4 worldPos = kineticRotation * vec4(aPos - 0.5, 1) + vec4(instancePos + .5, 0);
vec3 norm = (kineticRotation * vec4(aNormal, 0)).xyz;
#ifdef CONTRAPTION
worldPos = uModel * worldPos;
BoxCoord = (worldPos.xyz - uLightBoxMin) / uLightBoxSize;
mat4 normalMat = uModel * kineticRotation;
#else
mat4 normalMat = kineticRotation;
#endif
vec3 norm = normalize(normalMat * vec4(aNormal, 0)).xyz;
Diffuse = diffuse(norm);
TexCoords = aTexCoords;
gl_Position = projection * view * localPos;
Light = light;
gl_Position = uViewProjection * worldPos;
if (debug == 1) {
Color = vec4(networkTint, 1);
} else if (debug == 2) {
#ifdef CONTRAPTION
if (uDebug == 2) {
Color = vec4(norm, 1);
} else {
Color = vec4(1);
}
#else
if (uDebug == 1) {
Color = vec4(networkTint, 1);
} else if (uDebug == 2) {
Color = vec4(norm, 1);
} else {
Color = vec4(1);
}
#endif
}