merge experimental rendering from 1.16 to 1.15 part II

This commit is contained in:
JozsefA 2021-01-04 20:10:38 -08:00 committed by grimmauld
parent 7d43bb056a
commit 102e392ab4
23 changed files with 506 additions and 270 deletions

View file

@ -13,7 +13,8 @@ import com.simibubi.create.content.contraptions.fluids.FluidTransportBehaviour.A
import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock.HeatLevel;
import com.simibubi.create.foundation.utility.*;
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
import com.simibubi.create.foundation.utility.render.BeltBuffer;
import com.simibubi.create.foundation.utility.render.RotatingBuffer;
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
import net.minecraft.block.BlockState;
import net.minecraft.client.renderer.model.IBakedModel;
@ -216,15 +217,19 @@ public class AllBlockPartials {
return CreateClient.bufferCache.renderDirectionalPartial(this, referenceState, facing, ms);
}
public InstancedBuffer renderOnInstanced(BlockState referenceState) {
return CreateClient.kineticRenderer.renderPartialInstanced(this, referenceState);
public RotatingBuffer renderOnRotating(BlockState referenceState) {
return CreateClient.kineticRenderer.renderPartialRotating(this, referenceState);
}
public InstancedBuffer renderOnDirectionalSouthInstanced(BlockState referenceState) {
Direction facing = referenceState.get(FACING);
return renderOnDirectionalSouthInstanced(referenceState, facing);
public BeltBuffer renderOnBelt(BlockState referenceState) {
return CreateClient.kineticRenderer.renderPartialBelt(this, referenceState);
}
public InstancedBuffer renderOnDirectionalSouthInstanced(BlockState referenceState, Direction facing) {
public RotatingBuffer renderOnDirectionalSouthRotating(BlockState referenceState) {
Direction facing = referenceState.get(FACING);
return renderOnDirectionalSouthRotating(referenceState, facing);
}
public RotatingBuffer renderOnDirectionalSouthRotating(BlockState referenceState, Direction facing) {
MatrixStack ms = new MatrixStack();
// TODO 1.15 find a way to cache this model matrix computation
MatrixStacker.of(ms)

View file

@ -9,6 +9,7 @@ import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.ColorHelper;
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
import com.simibubi.create.foundation.utility.render.RotatingBuffer;
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
import com.simibubi.create.foundation.utility.render.SuperByteBufferCache.Compartment;
@ -49,11 +50,11 @@ public class KineticTileEntityRenderer extends SafeTileEntityRenderer<KineticTil
}
public static void renderRotatingKineticBlock(KineticTileEntity te, BlockState renderedState, int light) {
InstancedBuffer instancedRenderer = CreateClient.kineticRenderer.renderBlockInstanced(KINETIC_TILE, renderedState);
RotatingBuffer instancedRenderer = CreateClient.kineticRenderer.renderBlockInstanced(KINETIC_TILE, renderedState);
renderRotatingBuffer(te, instancedRenderer, light);
}
public static void renderRotatingBuffer(KineticTileEntity te, InstancedBuffer instancer, int light) {
public static void renderRotatingBuffer(KineticTileEntity te, RotatingBuffer instancer, int light) {
instancer.setupInstance(data -> {
final BlockPos pos = te.getPos();
Axis axis = ((IRotate) te.getBlockState()
@ -129,7 +130,7 @@ public class KineticTileEntityRenderer extends SafeTileEntityRenderer<KineticTil
return te.getBlockState();
}
protected InstancedBuffer getRotatedModel(KineticTileEntity te) {
protected RotatingBuffer getRotatedModel(KineticTileEntity te) {
return CreateClient.kineticRenderer.renderBlockInstanced(KINETIC_TILE, getRenderedBlockState(te));
}

View file

@ -11,6 +11,7 @@ import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.MatrixStacker;
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
import com.simibubi.create.foundation.utility.render.RotatingBuffer;
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
import com.simibubi.create.foundation.utility.VecHelper;
@ -27,8 +28,8 @@ public class DrillRenderer extends KineticTileEntityRenderer {
}
@Override
protected InstancedBuffer getRotatedModel(KineticTileEntity te) {
return AllBlockPartials.DRILL_HEAD.renderOnDirectionalSouthInstanced(te.getBlockState());
protected RotatingBuffer getRotatedModel(KineticTileEntity te) {
return AllBlockPartials.DRILL_HEAD.renderOnDirectionalSouthRotating(te.getBlockState());
}
protected static SuperByteBuffer getRotatingModel(BlockState state) {

View file

@ -8,6 +8,7 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.content.contraptions.components.clock.CuckooClockTileEntity.Animation;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
import com.simibubi.create.foundation.utility.render.RotatingBuffer;
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
import net.minecraft.block.BlockState;
@ -91,14 +92,14 @@ public class CuckooClockRenderer extends KineticTileEntityRenderer {
}
@Override
protected InstancedBuffer getRotatedModel(KineticTileEntity te) {
protected RotatingBuffer getRotatedModel(KineticTileEntity te) {
return transform(AllBlockPartials.SHAFT_HALF, te);
}
private InstancedBuffer transform(AllBlockPartials partial, KineticTileEntity te) {
return partial.renderOnDirectionalSouthInstanced(te.getBlockState(), te.getBlockState()
.get(CuckooClockBlock.HORIZONTAL_FACING)
.getOpposite());
private RotatingBuffer transform(AllBlockPartials partial, KineticTileEntity te) {
return partial.renderOnDirectionalSouthRotating(te.getBlockState(), te.getBlockState()
.get(CuckooClockBlock.HORIZONTAL_FACING)
.getOpposite());
}
private SuperByteBuffer rotateHand(SuperByteBuffer buffer, float angle, Direction facing) {

View file

@ -9,6 +9,7 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
import com.simibubi.create.foundation.utility.render.RotatingBuffer;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.WorldRenderer;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
@ -31,10 +32,10 @@ public class EncasedFanRenderer extends KineticTileEntityRenderer {
int lightBehind = WorldRenderer.getLightmapCoordinates(te.getWorld(), te.getPos().offset(direction.getOpposite()));
int lightInFront = WorldRenderer.getLightmapCoordinates(te.getWorld(), te.getPos().offset(direction));
InstancedBuffer shaftHalf =
AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthInstanced(te.getBlockState(), direction.getOpposite());
InstancedBuffer fanInner =
AllBlockPartials.ENCASED_FAN_INNER.renderOnDirectionalSouthInstanced(te.getBlockState(), direction.getOpposite());
RotatingBuffer shaftHalf =
AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(te.getBlockState(), direction.getOpposite());
RotatingBuffer fanInner =
AllBlockPartials.ENCASED_FAN_INNER.renderOnDirectionalSouthRotating(te.getBlockState(), direction.getOpposite());
renderRotatingBuffer(te, shaftHalf, lightBehind);
fanInner.setupInstance(data -> {

View file

@ -10,6 +10,7 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.content.contraptions.components.flywheel.FlywheelBlock.ConnectionState;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
import com.simibubi.create.foundation.utility.render.RotatingBuffer;
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
import net.minecraft.block.BlockState;
@ -75,10 +76,10 @@ public class FlywheelRenderer extends KineticTileEntityRenderer {
}
@Override
protected InstancedBuffer getRotatedModel(KineticTileEntity te) {
return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthInstanced(te.getBlockState(), te.getBlockState()
.get(HORIZONTAL_FACING)
.getOpposite());
protected RotatingBuffer getRotatedModel(KineticTileEntity te) {
return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(te.getBlockState(), te.getBlockState()
.get(HORIZONTAL_FACING)
.getOpposite());
}
protected SuperByteBuffer transformConnector(SuperByteBuffer buffer, boolean upper, boolean rotating, float angle,

View file

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

View file

@ -5,6 +5,7 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
import com.simibubi.create.foundation.utility.render.RotatingBuffer;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
public class CreativeMotorRenderer extends KineticTileEntityRenderer {
@ -14,8 +15,8 @@ public class CreativeMotorRenderer extends KineticTileEntityRenderer {
}
@Override
protected InstancedBuffer getRotatedModel(KineticTileEntity te) {
return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthInstanced(te.getBlockState());
protected RotatingBuffer getRotatedModel(KineticTileEntity te) {
return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(te.getBlockState());
}
}

View file

@ -13,6 +13,7 @@ import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer
import com.simibubi.create.foundation.utility.*;
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
import com.simibubi.create.foundation.utility.render.RotatingBuffer;
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft;
@ -123,10 +124,10 @@ public class SawRenderer extends SafeTileEntityRenderer<SawTileEntity> {
}
}
protected InstancedBuffer getRotatedModel(KineticTileEntity te) {
protected RotatingBuffer getRotatedModel(KineticTileEntity te) {
BlockState state = te.getBlockState();
if (state.get(FACING).getAxis().isHorizontal())
return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthInstanced(state.rotate(te.getWorld(), te.getPos(), Rotation.CLOCKWISE_180));
return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(state.rotate(te.getWorld(), te.getPos(), Rotation.CLOCKWISE_180));
return CreateClient.kineticRenderer.renderBlockInstanced(KineticTileEntityRenderer.KINETIC_TILE,
getRenderedBlockState(te));
}

View file

@ -6,6 +6,7 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
import com.simibubi.create.foundation.utility.render.RotatingBuffer;
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
import net.minecraft.client.renderer.IRenderTypeBuffer;
@ -44,10 +45,10 @@ public class BearingRenderer extends KineticTileEntityRenderer {
}
@Override
protected InstancedBuffer getRotatedModel(KineticTileEntity te) {
return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthInstanced(te.getBlockState(), te.getBlockState()
.get(BearingBlock.FACING)
.getOpposite());
protected RotatingBuffer getRotatedModel(KineticTileEntity te) {
return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(te.getBlockState(), te.getBlockState()
.get(BearingBlock.FACING)
.getOpposite());
}
}

View file

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

View file

@ -6,6 +6,7 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.foundation.tileEntity.renderer.SmartTileEntityRenderer;
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
import com.simibubi.create.foundation.utility.render.RotatingBuffer;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
@ -23,7 +24,7 @@ public class SpeedControllerRenderer extends SmartTileEntityRenderer<SpeedContro
KineticTileEntityRenderer.renderRotatingBuffer(tileEntityIn, getRotatedModel(tileEntityIn), light);
}
private InstancedBuffer getRotatedModel(SpeedControllerTileEntity te) {
private RotatingBuffer getRotatedModel(SpeedControllerTileEntity te) {
return CreateClient.kineticRenderer.renderBlockInstanced(KineticTileEntityRenderer.KINETIC_TILE,
KineticTileEntityRenderer.shaft(KineticTileEntityRenderer.getRotationAxisOf(te)));
}

View file

@ -16,16 +16,14 @@ import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.MatrixStacker;
import com.simibubi.create.foundation.utility.render.BeltBuffer;
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
import com.simibubi.create.foundation.utility.render.RotatingBuffer;
import com.simibubi.create.foundation.utility.render.ShadowRenderHelper;
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.ItemRenderer;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.Vector3f;
import net.minecraft.client.renderer.*;
import net.minecraft.client.renderer.model.ItemCameraTransforms.TransformType;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
import net.minecraft.entity.Entity;
@ -96,7 +94,10 @@ public class BeltRenderer extends SafeTileEntityRenderer<BeltTileEntity> {
: start ? AllBlockPartials.BELT_START
: end ? AllBlockPartials.BELT_END : AllBlockPartials.BELT_MIDDLE;
InstancedBuffer beltBuffer = beltPartial.renderOnInstanced(blockState);
BeltBuffer beltBuffer = beltPartial.renderOnBelt(blockState);
SpriteShiftEntry spriteShift =
diagonal ? AllSpriteShifts.BELT_DIAGONAL : bottom ? AllSpriteShifts.BELT_OFFSET : AllSpriteShifts.BELT;
int cycleLength = diagonal ? 12 : 16;
int cycleOffset = bottom ? 8 : 0;
@ -108,12 +109,16 @@ public class BeltRenderer extends SafeTileEntityRenderer<BeltTileEntity> {
|| sideways && axisDirection == AxisDirection.NEGATIVE)
speed = -speed;
data.setPackedLight(light)
.setPosition(te.getPos())
.setRotationalSpeed(speed)
.setRotationAxis(0, 0, 0)
.setCycleLength(cycleLength)
.setCycleOffset(cycleOffset);
Matrix4f m = new Matrix4f();
m.loadIdentity();
m.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(AngleHelper.horizontalAngle(facing) + (upward ? 180 : 0) + (sideways ? 270 : 0)));
m.multiply(Vector3f.POSITIVE_Z.getDegreesQuaternion(sideways ? 90 : 0));
m.multiply(Vector3f.POSITIVE_X.getDegreesQuaternion(!diagonal && beltSlope != BeltSlope.HORIZONTAL ? 90 : 0));
data.setPosition(te.getPos())
.setModel(m)
.setPackedLight(light)
.setRotationalSpeed(speed);
});
// Diagonal belt do not have a separate bottom model
@ -138,7 +143,7 @@ public class BeltRenderer extends SafeTileEntityRenderer<BeltTileEntity> {
msr.rotateX(90);
msr.unCentre();
InstancedBuffer superBuffer = CreateClient.kineticRenderer
RotatingBuffer superBuffer = CreateClient.kineticRenderer
.renderDirectionalPartialInstanced(AllBlockPartials.BELT_PULLEY, blockState, dir, modelTransform);
KineticTileEntityRenderer.renderRotatingBuffer(te, superBuffer, light);
}

View file

@ -8,6 +8,7 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
import com.simibubi.create.foundation.utility.render.RotatingBuffer;
import net.minecraft.block.Block;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
@ -34,7 +35,7 @@ public class SplitShaftRenderer extends KineticTileEntityRenderer {
continue;
InstancedBuffer shaft = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthInstanced(te.getBlockState(), direction);
RotatingBuffer shaft = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(te.getBlockState(), direction);
shaft.setupInstance(data -> {
float speed = te.getSpeed();

View file

@ -7,6 +7,7 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
import com.simibubi.create.foundation.utility.render.RotatingBuffer;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
import net.minecraft.state.properties.BlockStateProperties;
@ -31,7 +32,7 @@ public class GearboxRenderer extends KineticTileEntityRenderer {
if (boxAxis == axis)
continue;
InstancedBuffer shaft = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthInstanced(te.getBlockState(), direction);
RotatingBuffer shaft = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(te.getBlockState(), direction);
shaft.setupInstance(data -> {
float speed = te.getSpeed();

View file

@ -9,6 +9,7 @@ import com.simibubi.create.content.logistics.block.mechanicalArm.ArmTileEntity.P
import com.simibubi.create.foundation.utility.*;
import com.simibubi.create.foundation.utility.render.InstancedBuffer;
import com.simibubi.create.foundation.utility.render.RotatingBuffer;
import com.simibubi.create.foundation.utility.render.SuperByteBuffer;
import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft;
@ -116,8 +117,8 @@ public class ArmRenderer extends KineticTileEntityRenderer {
}
@Override
protected InstancedBuffer getRotatedModel(KineticTileEntity te) {
return AllBlockPartials.ARM_COG.renderOnInstanced(te.getBlockState());
protected RotatingBuffer getRotatedModel(KineticTileEntity te) {
return AllBlockPartials.ARM_COG.renderOnRotating(te.getBlockState());
}
}

View file

@ -0,0 +1,121 @@
package com.simibubi.create.foundation.utility.render;
import com.mojang.blaze3d.platform.GlStateManager;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GLAllocation;
import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.Matrix4f;
import net.minecraft.client.renderer.vertex.VertexFormatElement;
import net.minecraft.util.math.BlockPos;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL40;
import java.nio.Buffer;
import java.nio.ByteBuffer;
public class BeltBuffer extends InstancedBuffer<BeltBuffer.BeltData> {
public BeltBuffer(BufferBuilder buf) {
super(buf);
}
@Override
protected BeltData newInstance() {
return new BeltData();
}
@Override
protected int numAttributes() {
return 9;
}
@Override
protected void finishBufferingInternal() {
int floatSize = VertexFormatElement.Type.FLOAT.getSize();
int intSize = VertexFormatElement.Type.INT.getSize();
int stride = floatSize * 22;
int instanceSize = instanceCount * stride;
ByteBuffer buffer = GLAllocation.createDirectByteBuffer(instanceSize);
buffer.order(template.order());
((Buffer) buffer).limit(instanceSize);
data.forEach(instanceData -> instanceData.buffer(buffer));
buffer.rewind();
GlStateManager.bindBuffers(GL15.GL_ARRAY_BUFFER, instanceVBO);
GlStateManager.bufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
// render position
GL20.glVertexAttribPointer(3, 3, GL11.GL_FLOAT, false, stride, 0);
// model matrix
for (int i = 0; i < 4; i++) {
GL20.glVertexAttribPointer(4 + i, 4, GL11.GL_FLOAT, false, stride, floatSize * (4 * i + 3));
}
// light map
GL20.glVertexAttribPointer(8, 2, GL11.GL_FLOAT, false, stride, floatSize * 16L);
// rotational speed and offset
GL20.glVertexAttribPointer(9, 1, GL11.GL_FLOAT, false, stride, floatSize * 18L);
for (int i = 3; i <= numAttributes(); i++) {
GL40.glVertexAttribDivisor(i, 1);
}
// Deselect (bind to 0) the VBO
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
}
public static class BeltData {
private float x;
private float y;
private float z;
private Matrix4f model;
private int packedLight;
private float rotationalSpeed;
public BeltData setPosition(BlockPos pos) {
this.x = pos.getX();
this.y = pos.getY();
this.z = pos.getZ();
return this;
}
public BeltData setModel(Matrix4f model) {
this.model = model;
return this;
}
public BeltData setPackedLight(int packedLight) {
this.packedLight = packedLight;
return this;
}
public BeltData setRotationalSpeed(float rotationalSpeed) {
this.rotationalSpeed = rotationalSpeed;
return this;
}
void buffer(ByteBuffer buf) {
float blockLightCoordinates = LightTexture.getBlockLightCoordinates(packedLight) / (float) 0xF;
float skyLightCoordinates = LightTexture.getSkyLightCoordinates(packedLight) / (float) 0xF;
buf.putFloat(x);
buf.putFloat(y);
buf.putFloat(z);
InstancedBuffer.MATRIX_BUF.rewind();
model.write(InstancedBuffer.MATRIX_BUF.asFloatBuffer());
InstancedBuffer.MATRIX_BUF.rewind();
buf.put(InstancedBuffer.MATRIX_BUF);
buf.putFloat(blockLightCoordinates);
buf.putFloat(skyLightCoordinates);
buf.putFloat(rotationalSpeed);
}
}
}

View file

@ -8,6 +8,7 @@ import com.mojang.blaze3d.systems.RenderSystem;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.Create;
import com.simibubi.create.foundation.utility.render.shader.Shader;
import com.simibubi.create.foundation.utility.render.shader.ShaderCallback;
import com.simibubi.create.foundation.utility.render.shader.ShaderHelper;
import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft;
@ -36,12 +37,14 @@ import static com.simibubi.create.foundation.utility.render.SuperByteBufferCache
@Mod.EventBusSubscriber(modid = Create.ID, value = Dist.CLIENT)
public class FastKineticRenderer {
Map<SuperByteBufferCache.Compartment<?>, Cache<Object, InstancedBuffer>> cache;
Map<SuperByteBufferCache.Compartment<?>, Cache<Object, RotatingBuffer>> rotating;
Map<SuperByteBufferCache.Compartment<?>, Cache<Object, BeltBuffer>> belts;
Queue<Runnable> runs;
public FastKineticRenderer() {
cache = new HashMap<>();
rotating = new HashMap<>();
belts = new HashMap<>();
runs = new ConcurrentLinkedQueue<>();
registerCompartment(SuperByteBufferCache.GENERIC_TILE);
registerCompartment(SuperByteBufferCache.PARTIAL);
@ -49,8 +52,14 @@ public class FastKineticRenderer {
}
public void tick() {
for (Cache<Object, InstancedBuffer> cache : cache.values()) {
for (InstancedBuffer renderer : cache.asMap().values()) {
for (Cache<Object, RotatingBuffer> cache : rotating.values()) {
for (RotatingBuffer renderer : cache.asMap().values()) {
renderer.clearInstanceData();
}
}
for (Cache<Object, BeltBuffer> cache : belts.values()) {
for (BeltBuffer renderer : cache.asMap().values()) {
renderer.clearInstanceData();
}
}
@ -69,7 +78,22 @@ public class FastKineticRenderer {
GameRenderer gameRenderer = Minecraft.getInstance().gameRenderer;
LightTexture lightManager = gameRenderer.getLightmapTextureManager();
ShaderHelper.useShader(Shader.ROTATING_INSTANCED, shader -> {
Texture blockAtlasTexture = Minecraft.getInstance().textureManager.getTexture(PlayerContainer.BLOCK_ATLAS_TEXTURE);
Texture lightTexture = Minecraft.getInstance().textureManager.getTexture(lightManager.resourceLocation);
GL40.glActiveTexture(GL40.GL_TEXTURE0);
GL40.glBindTexture(GL11.GL_TEXTURE_2D, blockAtlasTexture.getGlTextureId());
GL40.glActiveTexture(GL40.GL_TEXTURE0 + 1);
GL40.glBindTexture(GL11.GL_TEXTURE_2D, lightTexture.getGlTextureId());
RenderSystem.texParameter(3553, 10241, 9729);
RenderSystem.texParameter(3553, 10240, 9729);
RenderSystem.texParameter(3553, 10242, 10496);
RenderSystem.texParameter(3553, 10243, 10496);
RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
RenderSystem.enableTexture();
ShaderCallback callback = shader -> {
ShaderHelper.MATRIX_BUFFER.position(0);
event.getProjectionMatrix().write(ShaderHelper.MATRIX_BUFFER);
@ -85,32 +109,22 @@ public class FastKineticRenderer {
translate.write(ShaderHelper.MATRIX_BUFFER);
int view = GlStateManager.getUniformLocation(shader, "view");
GlStateManager.uniformMatrix4(view, false, ShaderHelper.MATRIX_BUFFER);
};
ShaderHelper.useShader(Shader.ROTATING_INSTANCED, callback);
Texture blockAtlasTexture = Minecraft.getInstance().textureManager.getTexture(PlayerContainer.BLOCK_ATLAS_TEXTURE);
Texture lightTexture = Minecraft.getInstance().textureManager.getTexture(lightManager.resourceLocation);
rotating.values()
.stream()
.flatMap(cache -> cache.asMap().values().stream())
.filter(type -> !type.isEmpty())
.forEach(InstancedBuffer::render);
GL40.glActiveTexture(GL40.GL_TEXTURE0);
GL40.glBindTexture(GL11.GL_TEXTURE_2D, blockAtlasTexture.getGlTextureId());
ShaderHelper.useShader(Shader.BELT_INSTANCED, callback);
GL40.glActiveTexture(GL40.GL_TEXTURE0 + 1);
GL40.glBindTexture(GL11.GL_TEXTURE_2D, lightTexture.getGlTextureId());
RenderSystem.texParameter(3553, 10241, 9729);
RenderSystem.texParameter(3553, 10240, 9729);
RenderSystem.texParameter(3553, 10242, 10496);
RenderSystem.texParameter(3553, 10243, 10496);
RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
RenderSystem.enableTexture();
});
cache.values()
.stream()
.flatMap(cache -> {
ConcurrentMap<Object, InstancedBuffer> map = cache.asMap();
return map.values().stream();
})
.filter(type -> !type.isEmpty())
.forEach(InstancedBuffer::render);
belts.values()
.stream()
.flatMap(cache -> cache.asMap().values().stream())
.filter(type -> !type.isEmpty())
.forEach(InstancedBuffer::render);
ShaderHelper.releaseShader();
@ -129,29 +143,45 @@ public class FastKineticRenderer {
}
public void registerCompartment(SuperByteBufferCache.Compartment<?> instance) {
cache.put(instance, CacheBuilder.newBuilder().build());
rotating.put(instance, CacheBuilder.newBuilder().build());
belts.put(instance, CacheBuilder.newBuilder().build());
}
public void registerCompartment(SuperByteBufferCache.Compartment<?> instance, long ticksUntilExpired) {
cache.put(instance, CacheBuilder.newBuilder().expireAfterAccess(ticksUntilExpired * 50, TimeUnit.MILLISECONDS).build());
rotating.put(instance, CacheBuilder.newBuilder().expireAfterAccess(ticksUntilExpired * 50, TimeUnit.MILLISECONDS).build());
belts.put(instance, CacheBuilder.newBuilder().expireAfterAccess(ticksUntilExpired * 50, TimeUnit.MILLISECONDS).build());
}
public InstancedBuffer renderPartialInstanced(AllBlockPartials partial, BlockState referenceState) {
return getInstanced(PARTIAL, partial, () -> rotatingInstancedRenderer(partial.get(), referenceState));
public RotatingBuffer renderPartialRotating(AllBlockPartials partial, BlockState referenceState) {
return getRotating(PARTIAL, partial, () -> rotatingInstancedRenderer(partial.get(), referenceState));
}
public InstancedBuffer renderDirectionalPartialInstanced(AllBlockPartials partial, BlockState referenceState, Direction dir,
public BeltBuffer renderPartialBelt(AllBlockPartials partial, BlockState referenceState) {
return getBelt(PARTIAL, partial, () -> beltInstancedRenderer(partial.get(), referenceState));
}
public RotatingBuffer renderDirectionalPartialInstanced(AllBlockPartials partial, BlockState referenceState, Direction dir,
MatrixStack modelTransform) {
return getInstanced(SuperByteBufferCache.DIRECTIONAL_PARTIAL, Pair.of(dir, partial),
() -> rotatingInstancedRenderer(partial.get(), referenceState, modelTransform));
return getRotating(SuperByteBufferCache.DIRECTIONAL_PARTIAL, Pair.of(dir, partial),
() -> rotatingInstancedRenderer(partial.get(), referenceState, modelTransform));
}
public InstancedBuffer renderBlockInstanced(SuperByteBufferCache.Compartment<BlockState> compartment, BlockState toRender) {
return getInstanced(compartment, toRender, () -> rotatingInstancedRenderer(toRender));
public RotatingBuffer renderBlockInstanced(SuperByteBufferCache.Compartment<BlockState> compartment, BlockState toRender) {
return getRotating(compartment, toRender, () -> rotatingInstancedRenderer(toRender));
}
public <T> InstancedBuffer getInstanced(SuperByteBufferCache.Compartment<T> compartment, T key, Supplier<InstancedBuffer> supplier) {
Cache<Object, InstancedBuffer> compartmentCache = this.cache.get(compartment);
public <T> RotatingBuffer getRotating(SuperByteBufferCache.Compartment<T> compartment, T key, Supplier<RotatingBuffer> supplier) {
Cache<Object, RotatingBuffer> compartmentCache = this.rotating.get(compartment);
try {
return compartmentCache.get(key, supplier::get);
} catch (ExecutionException e) {
e.printStackTrace();
return null;
}
}
public <T> BeltBuffer getBelt(SuperByteBufferCache.Compartment<T> compartment, T key, Supplier<BeltBuffer> supplier) {
Cache<Object, BeltBuffer> compartmentCache = this.belts.get(compartment);
try {
return compartmentCache.get(key, supplier::get);
} catch (ExecutionException e) {
@ -161,23 +191,33 @@ public class FastKineticRenderer {
}
private InstancedBuffer rotatingInstancedRenderer(BlockState renderedState) {
private RotatingBuffer rotatingInstancedRenderer(BlockState renderedState) {
BlockRendererDispatcher dispatcher = Minecraft.getInstance().getBlockRendererDispatcher();
return rotatingInstancedRenderer(dispatcher.getModelForState(renderedState), renderedState);
}
private InstancedBuffer rotatingInstancedRenderer(IBakedModel model, BlockState renderedState) {
private RotatingBuffer rotatingInstancedRenderer(IBakedModel model, BlockState renderedState) {
return rotatingInstancedRenderer(model, renderedState, new MatrixStack());
}
private InstancedBuffer rotatingInstancedRenderer(IBakedModel model, BlockState referenceState, MatrixStack ms) {
private BeltBuffer beltInstancedRenderer(IBakedModel model, BlockState renderedState) {
return beltInstancedRenderer(model, renderedState, new MatrixStack());
}
private RotatingBuffer rotatingInstancedRenderer(IBakedModel model, BlockState referenceState, MatrixStack ms) {
BufferBuilder builder = SuperByteBufferCache.getBufferBuilder(model, referenceState, ms);
return new InstancedBuffer(builder);
return new RotatingBuffer(builder);
}
private BeltBuffer beltInstancedRenderer(IBakedModel model, BlockState referenceState, MatrixStack ms) {
BufferBuilder builder = SuperByteBufferCache.getBufferBuilder(model, referenceState, ms);
return new BeltBuffer(builder);
}
public void invalidate() {
cache.values().forEach(cache -> {
rotating.values().forEach(cache -> {
cache.asMap().values().forEach(InstancedBuffer::invalidate);
cache.invalidateAll();
});

View file

@ -5,10 +5,7 @@ import com.mojang.blaze3d.platform.GlStateManager;
import com.simibubi.create.CreateClient;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GLAllocation;
import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.Vector3f;
import net.minecraft.client.renderer.vertex.VertexFormatElement;
import net.minecraft.util.math.BlockPos;
import org.lwjgl.opengl.*;
import java.nio.Buffer;
@ -16,12 +13,14 @@ import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.function.Consumer;
public class InstancedBuffer extends TemplateBuffer {
public abstract class InstancedBuffer<T> extends TemplateBuffer {
public int vao, ebo, invariantVBO, instanceVBO, instanceCount;
protected static ByteBuffer MATRIX_BUF = GLAllocation.createDirectByteBuffer(16 << 2);
private final ArrayList<InstanceData> data = new ArrayList<>();
private boolean shouldBuild = true;
protected int vao, ebo, invariantVBO, instanceVBO, instanceCount;
protected final ArrayList<T> data = new ArrayList<>();
protected boolean shouldBuild = true;
public InstancedBuffer(BufferBuilder buf) {
super(buf);
@ -113,166 +112,52 @@ public class InstancedBuffer extends TemplateBuffer {
});
}
public void setupInstance(Consumer<InstanceData> setup) {
protected void addData(T instance) {
data.add(instance);
instanceCount++;
}
protected abstract T newInstance();
protected abstract int numAttributes();
public void setupInstance(Consumer<T> setup) {
if (!shouldBuild) return;
InstanceData instanceData = new InstanceData();
T instanceData = newInstance();
setup.accept(instanceData);
data.add(instanceData);
instanceCount++;
addData(instanceData);
}
public void render() {
GL30.glBindVertexArray(vao);
if (finishBuffering()) {
finishBuffering();
for (int i = 0; i <= 8; i++) {
GL40.glEnableVertexAttribArray(i);
}
GlStateManager.bindBuffers(GL15.GL_ELEMENT_ARRAY_BUFFER, ebo);
GL40.glDrawElementsInstanced(GL11.GL_QUADS, count, GL11.GL_UNSIGNED_SHORT, 0, instanceCount);
for (int i = 0; i <= 8; i++) {
GL40.glDisableVertexAttribArray(i);
}
for (int i = 0; i <= 10; i++) {
GL40.glEnableVertexAttribArray(i);
}
GlStateManager.bindBuffers(GL15.GL_ELEMENT_ARRAY_BUFFER, ebo);
GL40.glDrawElementsInstanced(GL11.GL_QUADS, count, GL11.GL_UNSIGNED_SHORT, 0, instanceCount);
for (int i = 0; i <= 10; i++) {
GL40.glDisableVertexAttribArray(i);
}
GL30.glBindVertexArray(0);
}
private boolean finishBuffering() {
if (!shouldBuild) return true;
private void finishBuffering() {
if (!shouldBuild) return;
int floatSize = VertexFormatElement.Type.FLOAT.getSize();
int intSize = VertexFormatElement.Type.INT.getSize();
int stride = floatSize * 10 + intSize * 2;
int instanceSize = data.size() * stride;
if (instanceSize == 0) return false;
ByteBuffer buffer = GLAllocation.createDirectByteBuffer(instanceSize);
buffer.order(template.order());
((Buffer) buffer).limit(instanceSize);
data.forEach(instanceData -> instanceData.buffer(buffer));
buffer.rewind();
GlStateManager.bindBuffers(GL15.GL_ARRAY_BUFFER, instanceVBO);
GlStateManager.bufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
// the render position
GL20.glVertexAttribPointer(3, 3, GL11.GL_FLOAT, false, stride, 0);
// vertex lighting
GL20.glVertexAttribPointer(4, 2, GL11.GL_FLOAT, false, stride, floatSize * 3L);
// rotational speed and offset
GL20.glVertexAttribPointer(5, 1, GL11.GL_FLOAT, false, stride, floatSize * 5L);
GL20.glVertexAttribPointer(6, 1, GL11.GL_FLOAT, false, stride, floatSize * 6L);
// rotation axis
GL20.glVertexAttribPointer(7, 3, GL11.GL_FLOAT, false, stride, floatSize * 7L);
// uv scrolling
GL20.glVertexAttribPointer(8, 2, GL11.GL_INT, false, stride, floatSize * 10L);
for (int i = 3; i <= 8; i++) {
GL40.glVertexAttribDivisor(i, 1);
}
// Deselect (bind to 0) the VBO
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
finishBufferingInternal();
shouldBuild = false;
data.clear();
return true;
}
public static class InstanceData {
private float x;
private float y;
private float z;
private int packedLight = 0;
private float rotationalSpeed;
private float rotationOffset;
private float rotationAxisX;
private float rotationAxisY;
private float rotationAxisZ;
private int cycleLength;
private int cycleOffset;
public InstanceData setPackedLight(int packedLight) {
this.packedLight = packedLight;
return this;
}
public InstanceData setRotationalSpeed(float rotationalSpeed) {
this.rotationalSpeed = rotationalSpeed;
return this;
}
public InstanceData setRotationOffset(float rotationOffset) {
this.rotationOffset = rotationOffset;
return this;
}
public InstanceData setPosition(Vector3f pos) {
this.x = pos.getX();
this.y = pos.getY();
this.z = pos.getZ();
return this;
}
public InstanceData setPosition(BlockPos pos) {
this.x = pos.getX();
this.y = pos.getY();
this.z = pos.getZ();
return this;
}
public InstanceData setRotationAxis(Vector3f axis) {
this.rotationAxisX = axis.getX();
this.rotationAxisY = axis.getY();
this.rotationAxisZ = axis.getZ();
return this;
}
public InstanceData setRotationAxis(float rotationAxisX, float rotationAxisY, float rotationAxisZ) {
this.rotationAxisX = rotationAxisX;
this.rotationAxisY = rotationAxisY;
this.rotationAxisZ = rotationAxisZ;
return this;
}
public InstanceData setCycleLength(int cycleLength) {
this.cycleLength = cycleLength;
return this;
}
public InstanceData setCycleOffset(int cycleOffset) {
this.cycleOffset = cycleOffset;
return this;
}
void buffer(ByteBuffer buf) {
float blockLightCoordinates = LightTexture.getBlockLightCoordinates(packedLight) / (float) 0xF;
float skyLightCoordinates = LightTexture.getSkyLightCoordinates(packedLight) / (float) 0xF;
buf.putFloat(x);
buf.putFloat(y);
buf.putFloat(z);
buf.putFloat(blockLightCoordinates);
buf.putFloat(skyLightCoordinates);
buf.putFloat(rotationalSpeed);
buf.putFloat(rotationOffset);
buf.putFloat(rotationAxisX);
buf.putFloat(rotationAxisY);
buf.putFloat(rotationAxisZ);
buf.putInt(cycleLength);
buf.putInt(cycleOffset);
}
}
protected abstract void finishBufferingInternal();
}

View file

@ -0,0 +1,143 @@
package com.simibubi.create.foundation.utility.render;
import com.mojang.blaze3d.platform.GlStateManager;
import com.simibubi.create.foundation.block.render.SpriteShiftEntry;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GLAllocation;
import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.vertex.VertexFormatElement;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.vector.Vector3f;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL40;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.util.function.Consumer;
public class RotatingBuffer extends InstancedBuffer<RotatingBuffer.InstanceData> {
public RotatingBuffer(BufferBuilder buf) {
super(buf);
}
@Override
protected InstanceData newInstance() {
return new InstanceData();
}
@Override
protected int numAttributes() {
return 7;
}
@Override
protected void finishBufferingInternal() {
int floatSize = VertexFormatElement.Type.FLOAT.getSize();
int stride = floatSize * 10;
int instanceSize = instanceCount * stride;
ByteBuffer buffer = GLAllocation.createDirectByteBuffer(instanceSize);
buffer.order(template.order());
((Buffer) buffer).limit(instanceSize);
data.forEach(instanceData -> instanceData.buffer(buffer));
buffer.rewind();
GlStateManager.bindBuffers(GL15.GL_ARRAY_BUFFER, instanceVBO);
GlStateManager.bufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
// the render position
GL20.glVertexAttribPointer(3, 3, GL11.GL_FLOAT, false, stride, 0);
// vertex lighting
GL20.glVertexAttribPointer(4, 2, GL11.GL_FLOAT, false, stride, floatSize * 3L);
// rotational speed and offset
GL20.glVertexAttribPointer(5, 1, GL11.GL_FLOAT, false, stride, floatSize * 5L);
GL20.glVertexAttribPointer(6, 1, GL11.GL_FLOAT, false, stride, floatSize * 6L);
// rotation axis
GL20.glVertexAttribPointer(7, 3, GL11.GL_FLOAT, false, stride, floatSize * 7L);
for (int i = 3; i <= numAttributes(); i++) {
GL40.glVertexAttribDivisor(i, 1);
}
// Deselect (bind to 0) the VBO
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
}
public static class InstanceData {
private float x;
private float y;
private float z;
private int packedLight;
private float rotationalSpeed;
private float rotationOffset;
private float rotationAxisX;
private float rotationAxisY;
private float rotationAxisZ;
public InstanceData setPackedLight(int packedLight) {
this.packedLight = packedLight;
return this;
}
public InstanceData setRotationalSpeed(float rotationalSpeed) {
this.rotationalSpeed = rotationalSpeed;
return this;
}
public InstanceData setRotationOffset(float rotationOffset) {
this.rotationOffset = rotationOffset;
return this;
}
public InstanceData setPosition(Vector3f pos) {
this.x = pos.getX();
this.y = pos.getY();
this.z = pos.getZ();
return this;
}
public InstanceData setPosition(BlockPos pos) {
this.x = pos.getX();
this.y = pos.getY();
this.z = pos.getZ();
return this;
}
public InstanceData setRotationAxis(Vector3f axis) {
this.rotationAxisX = axis.getX();
this.rotationAxisY = axis.getY();
this.rotationAxisZ = axis.getZ();
return this;
}
public InstanceData setRotationAxis(float rotationAxisX, float rotationAxisY, float rotationAxisZ) {
this.rotationAxisX = rotationAxisX;
this.rotationAxisY = rotationAxisY;
this.rotationAxisZ = rotationAxisZ;
return this;
}
void buffer(ByteBuffer buf) {
float blockLightCoordinates = LightTexture.getBlockLightCoordinates(packedLight) / (float) 0xF;
float skyLightCoordinates = LightTexture.getSkyLightCoordinates(packedLight) / (float) 0xF;
buf.putFloat(x);
buf.putFloat(y);
buf.putFloat(z);
buf.putFloat(blockLightCoordinates);
buf.putFloat(skyLightCoordinates);
buf.putFloat(rotationalSpeed);
buf.putFloat(rotationOffset);
buf.putFloat(rotationAxisX);
buf.putFloat(rotationAxisY);
buf.putFloat(rotationAxisZ);
}
}
}

View file

@ -1,7 +1,8 @@
package com.simibubi.create.foundation.utility.render.shader;
public enum Shader {
ROTATING_INSTANCED("shader/instanced.vert", "shader/instanced.frag");
ROTATING_INSTANCED("shader/rotating.vert", "shader/instanced.frag"),
BELT_INSTANCED("shader/belt.vert", "shader/instanced.frag"),;
public final String vert;
public final String frag;

View file

@ -0,0 +1,35 @@
#version 330 core
#define PI 3.1415926538
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
layout (location = 2) in vec2 aTexCoords;
layout (location = 3) in vec3 instancePos;
layout (location = 4) in mat4 model;
layout (location = 8) in vec2 light;
layout (location = 9) in float speed;
out vec2 TexCoords;
out vec2 Light;
uniform float time;
uniform int ticks;
uniform mat4 projection;
uniform mat4 view;
void main() {
// float textureIndex = fract((speed * time / 36 + cycle[1]) / cycle[0]) * cycle[0];
// if (textureIndex < 0) {
// textureIndex += cycle[0];
// }
//
// vec2 scrollPos = vec2(fract(textureIndex / 4), floor(textureIndex / 16));
vec4 renderPos = model * vec4(aPos - vec3(0.5), 1f);
renderPos += vec4(instancePos + vec3(0.5), 0);
TexCoords = aTexCoords;
gl_Position = projection * view * renderPos;
}

View file

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