diff --git a/src/main/java/com/simibubi/create/AllBlockPartials.java b/src/main/java/com/simibubi/create/AllBlockPartials.java index 2d92ff390..84f59e743 100644 --- a/src/main/java/com/simibubi/create/AllBlockPartials.java +++ b/src/main/java/com/simibubi/create/AllBlockPartials.java @@ -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) diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntityRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntityRenderer.java index 0110b2455..2996f04d8 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntityRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntityRenderer.java @@ -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 { final BlockPos pos = te.getPos(); Axis axis = ((IRotate) te.getBlockState() @@ -129,7 +130,7 @@ public class KineticTileEntityRenderer extends SafeTileEntityRenderer { diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlywheelRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlywheelRenderer.java index 59d7f81ec..e175c5f03 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlywheelRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlywheelRenderer.java @@ -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, diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/millstone/MillstoneRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/millstone/MillstoneRenderer.java index a238a2ba1..6481a47a1 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/millstone/MillstoneRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/millstone/MillstoneRenderer.java @@ -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()); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/motor/CreativeMotorRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/motor/CreativeMotorRenderer.java index 699c59186..1bbd0e558 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/motor/CreativeMotorRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/motor/CreativeMotorRenderer.java @@ -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()); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/saw/SawRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/saw/SawRenderer.java index 4ad2d204a..2a17f0849 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/saw/SawRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/saw/SawRenderer.java @@ -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 { } } - 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)); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/BearingRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/BearingRenderer.java index fece4075f..a1ba39595 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/BearingRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/BearingRenderer.java @@ -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()); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/fluids/PumpRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/fluids/PumpRenderer.java index 372cab409..70a527779 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/fluids/PumpRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/fluids/PumpRenderer.java @@ -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()); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/SpeedControllerRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/SpeedControllerRenderer.java index dae604e77..1031e592f 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/SpeedControllerRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/SpeedControllerRenderer.java @@ -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 { : 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 { || 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 { 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); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SplitShaftRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SplitShaftRenderer.java index 3512d9572..be421d744 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SplitShaftRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SplitShaftRenderer.java @@ -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(); diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearboxRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearboxRenderer.java index b4e0c48be..52b54411f 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearboxRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearboxRenderer.java @@ -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(); diff --git a/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmRenderer.java b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmRenderer.java index bab767872..334e5317e 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmRenderer.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmRenderer.java @@ -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()); } } diff --git a/src/main/java/com/simibubi/create/foundation/utility/render/BeltBuffer.java b/src/main/java/com/simibubi/create/foundation/utility/render/BeltBuffer.java new file mode 100644 index 000000000..a13a20f4c --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/utility/render/BeltBuffer.java @@ -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 { + 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); + } + } +} diff --git a/src/main/java/com/simibubi/create/foundation/utility/render/FastKineticRenderer.java b/src/main/java/com/simibubi/create/foundation/utility/render/FastKineticRenderer.java index 998c8af87..5ea1f5203 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/render/FastKineticRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/utility/render/FastKineticRenderer.java @@ -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, Cache> cache; + Map, Cache> rotating; + Map, Cache> belts; Queue 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 cache : cache.values()) { - for (InstancedBuffer renderer : cache.asMap().values()) { + for (Cache cache : rotating.values()) { + for (RotatingBuffer renderer : cache.asMap().values()) { + renderer.clearInstanceData(); + } + } + + for (Cache 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 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 compartment, BlockState toRender) { - return getInstanced(compartment, toRender, () -> rotatingInstancedRenderer(toRender)); + public RotatingBuffer renderBlockInstanced(SuperByteBufferCache.Compartment compartment, BlockState toRender) { + return getRotating(compartment, toRender, () -> rotatingInstancedRenderer(toRender)); } - public InstancedBuffer getInstanced(SuperByteBufferCache.Compartment compartment, T key, Supplier supplier) { - Cache compartmentCache = this.cache.get(compartment); + public RotatingBuffer getRotating(SuperByteBufferCache.Compartment compartment, T key, Supplier supplier) { + Cache compartmentCache = this.rotating.get(compartment); + try { + return compartmentCache.get(key, supplier::get); + } catch (ExecutionException e) { + e.printStackTrace(); + return null; + } + } + + public BeltBuffer getBelt(SuperByteBufferCache.Compartment compartment, T key, Supplier supplier) { + Cache 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(); }); diff --git a/src/main/java/com/simibubi/create/foundation/utility/render/InstancedBuffer.java b/src/main/java/com/simibubi/create/foundation/utility/render/InstancedBuffer.java index a2c0b4e6c..e6163226e 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/render/InstancedBuffer.java +++ b/src/main/java/com/simibubi/create/foundation/utility/render/InstancedBuffer.java @@ -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 extends TemplateBuffer { - public int vao, ebo, invariantVBO, instanceVBO, instanceCount; + protected static ByteBuffer MATRIX_BUF = GLAllocation.createDirectByteBuffer(16 << 2); - private final ArrayList data = new ArrayList<>(); - private boolean shouldBuild = true; + protected int vao, ebo, invariantVBO, instanceVBO, instanceCount; + + protected final ArrayList 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 setup) { + protected void addData(T instance) { + data.add(instance); + instanceCount++; + } + + protected abstract T newInstance(); + + protected abstract int numAttributes(); + + public void setupInstance(Consumer 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(); } diff --git a/src/main/java/com/simibubi/create/foundation/utility/render/RotatingBuffer.java b/src/main/java/com/simibubi/create/foundation/utility/render/RotatingBuffer.java new file mode 100644 index 000000000..ba69f508d --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/utility/render/RotatingBuffer.java @@ -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 { + 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); + } + } +} diff --git a/src/main/java/com/simibubi/create/foundation/utility/render/shader/Shader.java b/src/main/java/com/simibubi/create/foundation/utility/render/shader/Shader.java index d0d3b34c1..e0b2d11ff 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/render/shader/Shader.java +++ b/src/main/java/com/simibubi/create/foundation/utility/render/shader/Shader.java @@ -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; diff --git a/src/main/resources/assets/create/shader/belt.vert b/src/main/resources/assets/create/shader/belt.vert new file mode 100644 index 000000000..3e814cdc4 --- /dev/null +++ b/src/main/resources/assets/create/shader/belt.vert @@ -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; +} diff --git a/src/main/resources/assets/create/shader/instanced.vert b/src/main/resources/assets/create/shader/rotating.vert similarity index 56% rename from src/main/resources/assets/create/shader/instanced.vert rename to src/main/resources/assets/create/shader/rotating.vert index c34947ac9..2643566f2 100644 --- a/src/main/resources/assets/create/shader/instanced.vert +++ b/src/main/resources/assets/create/shader/rotating.vert @@ -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;