diff --git a/src/main/java/com/simibubi/create/AllSpriteShifts.java b/src/main/java/com/simibubi/create/AllSpriteShifts.java index 9d8fee9b0..8d805664f 100644 --- a/src/main/java/com/simibubi/create/AllSpriteShifts.java +++ b/src/main/java/com/simibubi/create/AllSpriteShifts.java @@ -55,9 +55,9 @@ public class AllSpriteShifts { CREATIVE_FLUID_TANK = getCT(CTType.CROSS, "creative_fluid_tank"); public static final SpriteShiftEntry - BELT = SpriteShifter.get("block/belt", "block/belt_animated"), - BELT_OFFSET = SpriteShifter.get("block/belt_offset", "block/belt_animated"), - BELT_DIAGONAL = SpriteShifter.get("block/belt_diagonal", "block/belt_diagonal_animated"), + BELT = SpriteShifter.get("block/belt", "block/belt_scroll"), + BELT_OFFSET = SpriteShifter.get("block/belt_offset", "block/belt_offset_scroll"), + BELT_DIAGONAL = SpriteShifter.get("block/belt_diagonal", "block/belt_diagonal_scroll"), ANDESIDE_BELT_CASING = SpriteShifter.get("block/brass_casing_belt", "block/andesite_casing_belt"), CRAFTER_THINGIES = SpriteShifter.get("block/crafter_thingies", "block/crafter_thingies"); diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltRenderer.java index 9d9d7952f..b0839ffc8 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltRenderer.java @@ -66,17 +66,6 @@ public class BeltRenderer extends SafeTileEntityRenderer { boolean sideways = beltSlope == BeltSlope.SIDEWAYS; boolean alongX = facing.getAxis() == Axis.X; - MatrixStacker msr = MatrixStacker.of(ms); - IVertexBuilder vb = buffer.getBuffer(RenderType.getSolid()); - float renderTick = AnimationTickHolder.getRenderTick(); - - ms.push(); - msr.centre(); - msr.rotateY(AngleHelper.horizontalAngle(facing) + (upward ? 180 : 0) + (sideways ? 270 : 0)); - msr.rotateZ(sideways ? 90 : 0); - msr.rotateX(!diagonal && beltSlope != BeltSlope.HORIZONTAL ? 90 : 0); - msr.unCentre(); - if (downward || beltSlope == BeltSlope.VERTICAL && axisDirection == AxisDirection.POSITIVE) { boolean b = start; start = end; @@ -98,34 +87,29 @@ public class BeltRenderer extends SafeTileEntityRenderer { SpriteShiftEntry spriteShift = diagonal ? AllSpriteShifts.BELT_DIAGONAL : bottom ? AllSpriteShifts.BELT_OFFSET : AllSpriteShifts.BELT; - int cycleLength = diagonal ? 12 : 16; - int cycleOffset = bottom ? 8 : 0; - - // UV shift - beltBuffer.setupInstance(data -> { float speed = te.getSpeed(); if (diagonal && (downward ^ alongX) || !sideways && !diagonal && alongX || sideways && axisDirection == AxisDirection.NEGATIVE) speed = -speed; - 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)); - + float horizontalAngle = facing.getHorizontalAngle(); data.setPosition(te.getPos()) - .setModel(m) + .setRotation( + !diagonal && beltSlope != BeltSlope.HORIZONTAL ? 90 : 0, + horizontalAngle + (upward ? 180 : 0) + (sideways ? 270 : 0), + sideways ? 90 : 0 + ) .setPackedLight(light) - .setRotationalSpeed(speed); + .setRotationalSpeed(speed) + .setScrollTexture(spriteShift) + .setScrollMult(diagonal ? 3f / 8f : 0.5f); }); // Diagonal belt do not have a separate bottom model if (diagonal) break; } - ms.pop(); if (te.hasPulley()) { // TODO 1.15 find a way to cache this model matrix computation @@ -134,7 +118,7 @@ public class BeltRenderer extends SafeTileEntityRenderer { .rotateY(); if (sideways) dir = Direction.UP; - msr = MatrixStacker.of(modelTransform); + MatrixStacker msr = MatrixStacker.of(modelTransform); msr.centre(); if (dir.getAxis() == Axis.X) msr.rotateY(90); @@ -143,9 +127,9 @@ public class BeltRenderer extends SafeTileEntityRenderer { msr.rotateX(90); msr.unCentre(); - RotatingBuffer superBuffer = CreateClient.kineticRenderer + RotatingBuffer rotatingBuffer = CreateClient.kineticRenderer .renderDirectionalPartialInstanced(AllBlockPartials.BELT_PULLEY, blockState, dir, modelTransform); - KineticTileEntityRenderer.renderRotatingBuffer(te, superBuffer, light); + KineticTileEntityRenderer.renderRotatingBuffer(te, rotatingBuffer, light); } renderItems(te, partialTicks, ms, buffer, light, overlay); 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 index a13a20f4c..f28797586 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/render/BeltBuffer.java +++ b/src/main/java/com/simibubi/create/foundation/utility/render/BeltBuffer.java @@ -1,10 +1,11 @@ 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.Matrix4f; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.vertex.VertexFormatElement; import net.minecraft.util.math.BlockPos; import org.lwjgl.opengl.GL11; @@ -34,7 +35,7 @@ public class BeltBuffer extends InstancedBuffer { protected void finishBufferingInternal() { int floatSize = VertexFormatElement.Type.FLOAT.getSize(); int intSize = VertexFormatElement.Type.INT.getSize(); - int stride = floatSize * 22; + int stride = floatSize * 16; int instanceSize = instanceCount * stride; @@ -51,16 +52,21 @@ public class BeltBuffer extends InstancedBuffer { // 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)); - } + // render rotation + GL20.glVertexAttribPointer(4, 3, GL11.GL_FLOAT, false, stride, floatSize * 3L); // light map - GL20.glVertexAttribPointer(8, 2, GL11.GL_FLOAT, false, stride, floatSize * 16L); + GL20.glVertexAttribPointer(5, 2, GL11.GL_FLOAT, false, stride, floatSize * 6L); - // rotational speed and offset - GL20.glVertexAttribPointer(9, 1, GL11.GL_FLOAT, false, stride, floatSize * 18L); + // speed + GL20.glVertexAttribPointer(6, 1, GL11.GL_FLOAT, false, stride, floatSize * 8L); + + // uv data + GL20.glVertexAttribPointer(7, 2, GL11.GL_FLOAT, false, stride, floatSize * 9L); + + GL20.glVertexAttribPointer(8, 4, GL11.GL_FLOAT, false, stride, floatSize * 11L); + + GL20.glVertexAttribPointer(9, 1, GL11.GL_FLOAT, false, stride, floatSize * 15L); for (int i = 3; i <= numAttributes(); i++) { GL40.glVertexAttribDivisor(i, 1); @@ -74,9 +80,18 @@ public class BeltBuffer extends InstancedBuffer { private float x; private float y; private float z; - private Matrix4f model; + private float rotX; + private float rotY; + private float rotZ; private int packedLight; private float rotationalSpeed; + private float sourceU; + private float sourceV; + private float minU; + private float minV; + private float maxU; + private float maxV; + private float scrollMult; public BeltData setPosition(BlockPos pos) { this.x = pos.getX(); @@ -85,8 +100,10 @@ public class BeltBuffer extends InstancedBuffer { return this; } - public BeltData setModel(Matrix4f model) { - this.model = model; + public BeltData setRotation(float rotX, float rotY, float rotZ) { + this.rotX = rotX; + this.rotY = rotY; + this.rotZ = rotZ; return this; } @@ -100,6 +117,25 @@ public class BeltBuffer extends InstancedBuffer { return this; } + public BeltData setScrollTexture(SpriteShiftEntry spriteShift) { + TextureAtlasSprite source = spriteShift.getOriginal(); + TextureAtlasSprite target = spriteShift.getTarget(); + + this.sourceU = source.getMinU(); + this.sourceV = source.getMinV(); + this.minU = target.getMinU(); + this.minV = target.getMinV(); + this.maxU = target.getMaxU(); + this.maxV = target.getMaxV(); + + return this; + } + + public BeltData setScrollMult(float scrollMult) { + this.scrollMult = scrollMult; + return this; + } + void buffer(ByteBuffer buf) { float blockLightCoordinates = LightTexture.getBlockLightCoordinates(packedLight) / (float) 0xF; float skyLightCoordinates = LightTexture.getSkyLightCoordinates(packedLight) / (float) 0xF; @@ -108,14 +144,22 @@ public class BeltBuffer extends InstancedBuffer { buf.putFloat(y); buf.putFloat(z); - InstancedBuffer.MATRIX_BUF.rewind(); - model.write(InstancedBuffer.MATRIX_BUF.asFloatBuffer()); - InstancedBuffer.MATRIX_BUF.rewind(); + buf.putFloat(rotX); + buf.putFloat(rotY); + buf.putFloat(rotZ); - buf.put(InstancedBuffer.MATRIX_BUF); buf.putFloat(blockLightCoordinates); buf.putFloat(skyLightCoordinates); buf.putFloat(rotationalSpeed); + + buf.putFloat(sourceU); + buf.putFloat(sourceV); + buf.putFloat(minU); + buf.putFloat(minV); + buf.putFloat(maxU); + buf.putFloat(maxV); + + buf.putFloat(scrollMult); } } } 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 ebe501896..dfe350cb5 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 @@ -50,17 +50,17 @@ public class FastKineticRenderer { } public void tick() { - 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(); - } - } +// 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(); +// } +// } } public void enqueue(Runnable run) { @@ -219,5 +219,10 @@ public class FastKineticRenderer { cache.asMap().values().forEach(InstancedBuffer::invalidate); cache.invalidateAll(); }); + + belts.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 e6163226e..ad77c60a7 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 @@ -15,8 +15,6 @@ import java.util.function.Consumer; public abstract class InstancedBuffer extends TemplateBuffer { - protected static ByteBuffer MATRIX_BUF = GLAllocation.createDirectByteBuffer(16 << 2); - protected int vao, ebo, invariantVBO, instanceVBO, instanceCount; protected final ArrayList data = new ArrayList<>(); @@ -112,11 +110,6 @@ public abstract class InstancedBuffer extends TemplateBuffer { }); } - protected void addData(T instance) { - data.add(instance); - instanceCount++; - } - protected abstract T newInstance(); protected abstract int numAttributes(); @@ -127,7 +120,8 @@ public abstract class InstancedBuffer extends TemplateBuffer { T instanceData = newInstance(); setup.accept(instanceData); - addData(instanceData); + data.add(instanceData); + instanceCount++; } public void render() { diff --git a/src/main/resources/assets/create/shader/belt.vert b/src/main/resources/assets/create/shader/belt.vert index 3e814cdc4..7e1a30b8f 100644 --- a/src/main/resources/assets/create/shader/belt.vert +++ b/src/main/resources/assets/create/shader/belt.vert @@ -6,9 +6,12 @@ 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; +layout (location = 4) in vec3 rotationDegrees; +layout (location = 5) in vec2 light; +layout (location = 6) in float speed; +layout (location = 7) in vec2 sourceUV; +layout (location = 8) in vec4 scrollTexture; +layout (location = 9) in float scrollMult; out vec2 TexCoords; out vec2 Light; @@ -18,18 +21,30 @@ uniform int ticks; uniform mat4 projection; uniform mat4 view; +mat4 rotate(vec3 axis, float angle) +{ + float s = sin(angle); + float c = cos(angle); + float oc = 1.0 - c; -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)); + return mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0., + oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0., + oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0., + 0., 0., 0., 1.); +} - vec4 renderPos = model * vec4(aPos - vec3(0.5), 1f); +void main() +{ + vec3 rot = fract(rotationDegrees / 360.) * PI * 2.; + + vec4 renderPos = rotate(vec3(1, 0, 0), rot.x) * rotate(vec3(0, 0, 1), rot.z) * rotate(vec3(0, 1, 0), rot.y) * vec4(aPos - vec3(0.5), 1f); renderPos += vec4(instancePos + vec3(0.5), 0); - TexCoords = aTexCoords; + float scrollSize = scrollTexture.w - scrollTexture.y; + + float scroll = fract(speed * time / (36. * 16.)) * scrollSize * scrollMult; + + Light = light; + TexCoords = aTexCoords - sourceUV + scrollTexture.xy + vec2(0., scroll); gl_Position = projection * view * renderPos; } diff --git a/src/main/resources/assets/create/textures/block/belt_diagonal_scroll.png b/src/main/resources/assets/create/textures/block/belt_diagonal_scroll.png new file mode 100644 index 000000000..e8cdb900e Binary files /dev/null and b/src/main/resources/assets/create/textures/block/belt_diagonal_scroll.png differ diff --git a/src/main/resources/assets/create/textures/block/belt_scroll.png b/src/main/resources/assets/create/textures/block/belt_scroll.png new file mode 100644 index 000000000..b5081c7d7 Binary files /dev/null and b/src/main/resources/assets/create/textures/block/belt_scroll.png differ