diff --git a/src/main/java/com/minelittlepony/unicopia/client/particle/AbstractGeometryBasedParticle.java b/src/main/java/com/minelittlepony/unicopia/client/particle/AbstractGeometryBasedParticle.java index 34a4debe..9a0971d5 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/particle/AbstractGeometryBasedParticle.java +++ b/src/main/java/com/minelittlepony/unicopia/client/particle/AbstractGeometryBasedParticle.java @@ -3,11 +3,13 @@ package com.minelittlepony.unicopia.client.particle; import org.joml.Vector3f; import com.minelittlepony.unicopia.client.render.RenderUtil; +import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.client.particle.Particle; import net.minecraft.client.particle.ParticleTextureSheet; import net.minecraft.client.render.BufferBuilder; import net.minecraft.client.render.BufferRenderer; +import net.minecraft.client.render.GameRenderer; import net.minecraft.client.render.Tessellator; import net.minecraft.client.render.VertexConsumer; import net.minecraft.client.render.VertexFormat; @@ -42,6 +44,7 @@ public abstract class AbstractGeometryBasedParticle extends Particle { protected final void renderQuad(MatrixStack matrices, Tessellator te, RenderUtil.Vertex[] corners, float alpha, float tickDelta) { int light = getBrightness(tickDelta); + RenderSystem.setShader(GameRenderer::getPositionTexColorProgram); BufferBuilder buffer = te.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR_LIGHT); for (RenderUtil.Vertex corner : corners) { var position = corner.position(matrices.peek().getPositionMatrix()); @@ -52,11 +55,16 @@ public abstract class AbstractGeometryBasedParticle extends Particle { protected final void renderQuad(Tessellator te, RenderUtil.Vertex[] corners, float alpha, float tickDelta) { int light = getBrightness(tickDelta); + RenderSystem.setShader(GameRenderer::getPositionTexColorProgram); BufferBuilder buffer = te.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR_LIGHT); + quad(buffer, corners, alpha, tickDelta, light); + BufferRenderer.drawWithGlobalProgram(buffer.end()); + } + + protected final void quad(BufferBuilder buffer, RenderUtil.Vertex[] corners, float alpha, float tickDelta, int light) { for (RenderUtil.Vertex corner : corners) { buffer.vertex(corner.position().x, corner.position().y, corner.position().z).texture(corner.texture().x, corner.texture().y).color(red, green, blue, alpha).light(light); } - BufferRenderer.drawWithGlobalProgram(buffer.end()); } protected final void renderQuad(VertexConsumer buffer, Vector3f[] corners, float alpha, float tickDelta) { diff --git a/src/main/java/com/minelittlepony/unicopia/client/particle/RainbowTrailParticle.java b/src/main/java/com/minelittlepony/unicopia/client/particle/RainbowTrailParticle.java index 7551e1e4..43bcd5fc 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/particle/RainbowTrailParticle.java +++ b/src/main/java/com/minelittlepony/unicopia/client/particle/RainbowTrailParticle.java @@ -9,8 +9,14 @@ import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType; import com.minelittlepony.unicopia.client.render.bezier.BezierSegment; import com.minelittlepony.unicopia.client.render.bezier.Trail; import com.minelittlepony.unicopia.particle.TargetBoundParticleEffect; +import com.mojang.blaze3d.systems.RenderSystem; +import net.minecraft.client.render.BufferBuilder; +import net.minecraft.client.render.BufferRenderer; +import net.minecraft.client.render.GameRenderer; import net.minecraft.client.render.Tessellator; +import net.minecraft.client.render.VertexFormat; +import net.minecraft.client.render.VertexFormats; import net.minecraft.client.world.ClientWorld; import net.minecraft.entity.Entity; import net.minecraft.util.Identifier; @@ -20,6 +26,8 @@ import net.minecraft.util.math.Vec3d; public class RainbowTrailParticle extends AbstractBillboardParticle { private static final Identifier TEXTURE = Unicopia.id("textures/particles/rainboom_trail.png"); + private final BezierSegment bezier = new BezierSegment(); + private final Trail trail; @Nullable @@ -55,18 +63,31 @@ public class RainbowTrailParticle extends AbstractBillboardParticle { @Override protected void renderQuads(Tessellator te, float x, float y, float z, float tickDelta) { float alpha = this.alpha * (1 - (float)age / maxAge); + int light = getBrightness(tickDelta); + float scale = getScale(tickDelta); List segments = trail.getSegments(); + @Nullable + BufferBuilder buffer = null; + for (int i = 0; i < segments.size() - 1; i++) { - BezierSegment corners = segments.get(i).getPlane(segments.get(i + 1)); - float scale = getScale(tickDelta); + segments.get(i).getPlane(segments.get(i + 1), bezier); - corners.forEachCorner(corner -> { + for (var corner : bezier.corners()) { corner.position().mul(scale).add(x, y, z); - }); + } - renderQuad(te, corners.corners(), segments.get(i).getAlpha() * alpha, tickDelta); + if (buffer == null) { + RenderSystem.setShader(GameRenderer::getPositionTexColorProgram); + buffer = te.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR_LIGHT); + } + + quad(buffer, bezier.corners(), segments.get(i).getAlpha() * alpha, tickDelta, light); + } + + if (buffer != null) { + BufferRenderer.drawWithGlobalProgram(buffer.end()); } } diff --git a/src/main/java/com/minelittlepony/unicopia/client/particle/WindParticle.java b/src/main/java/com/minelittlepony/unicopia/client/particle/WindParticle.java index 2cd9119b..a8c03846 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/particle/WindParticle.java +++ b/src/main/java/com/minelittlepony/unicopia/client/particle/WindParticle.java @@ -7,9 +7,15 @@ import com.minelittlepony.unicopia.Unicopia; import com.minelittlepony.unicopia.client.render.bezier.BezierSegment; import com.minelittlepony.unicopia.client.render.bezier.Trail; import com.minelittlepony.unicopia.particle.TargetBoundParticleEffect; +import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.client.MinecraftClient; +import net.minecraft.client.render.BufferBuilder; +import net.minecraft.client.render.BufferRenderer; +import net.minecraft.client.render.GameRenderer; import net.minecraft.client.render.Tessellator; +import net.minecraft.client.render.VertexFormat; +import net.minecraft.client.render.VertexFormats; import net.minecraft.client.world.ClientWorld; import net.minecraft.entity.Entity; import net.minecraft.util.Identifier; @@ -19,6 +25,8 @@ import net.minecraft.util.math.Vec3d; public class WindParticle extends AbstractBillboardParticle { private static final Identifier TEXTURE = Unicopia.id("textures/particle/wind.png"); + private final BezierSegment bezier = new BezierSegment(); + private final Trail trail; @Nullable @@ -60,18 +68,31 @@ public class WindParticle extends AbstractBillboardParticle { @Override protected void renderQuads(Tessellator te, float x, float y, float z, float tickDelta) { float alpha = this.alpha * (1 - (float)age / maxAge); + int light = getBrightness(tickDelta); + float scale = getScale(tickDelta); List segments = trail.getSegments(); + @Nullable + BufferBuilder buffer = null; + for (int i = 0; i < segments.size() - 1; i++) { - BezierSegment corners = segments.get(i).getPlane(segments.get(i + 1)); - float scale = getScale(tickDelta); + segments.get(i).getPlane(segments.get(i + 1), bezier); - corners.forEachCorner(corner -> { + for (var corner : bezier.corners()) { corner.position().mul(scale).add(x, y, z); - }); + } - renderQuad(te, corners.corners(), segments.get(i).getAlpha() * alpha, tickDelta); + if (buffer == null) { + RenderSystem.setShader(GameRenderer::getPositionTexColorProgram); + buffer = te.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR_LIGHT); + } + + quad(buffer, bezier.corners(), segments.get(i).getAlpha() * alpha, tickDelta, light); + } + + if (buffer != null) { + BufferRenderer.drawWithGlobalProgram(buffer.end()); } } diff --git a/src/main/java/com/minelittlepony/unicopia/client/render/RenderUtil.java b/src/main/java/com/minelittlepony/unicopia/client/render/RenderUtil.java index a74b7d20..a42de311 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/render/RenderUtil.java +++ b/src/main/java/com/minelittlepony/unicopia/client/render/RenderUtil.java @@ -47,6 +47,15 @@ public class RenderUtil { this(new Vector3f(x, y, z), new Vector3f(u, v, 1)); } + public Vertex() { + this(new Vector3f(), new Vector3f()); + } + + public void set(float x, float y, float z, float u, float v) { + position.set(x, y, z); + texture.set(u, v, 1); + } + public Vector4f position(Matrix4f mat) { return mat.transform(TEMP_VECTOR.set(position, 1)); } diff --git a/src/main/java/com/minelittlepony/unicopia/client/render/bezier/BezierSegment.java b/src/main/java/com/minelittlepony/unicopia/client/render/bezier/BezierSegment.java index bb30b1f5..8e9808e4 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/render/bezier/BezierSegment.java +++ b/src/main/java/com/minelittlepony/unicopia/client/render/bezier/BezierSegment.java @@ -9,16 +9,20 @@ import com.minelittlepony.unicopia.client.render.RenderUtil; public record BezierSegment( RenderUtil.Vertex[] corners ) { - - public BezierSegment(Vector3f from, Vector3f to, float height) { + public BezierSegment() { this(new RenderUtil.Vertex[] { - new RenderUtil.Vertex(from.x, from.y - height/2F, from.z, 0, 0), // bottom left - new RenderUtil.Vertex(from.x, from.y + height/2F, from.z, 1, 0), // top left - new RenderUtil.Vertex(to.x, to.y + height/2F, to.z, 1, 1), // top right - new RenderUtil.Vertex(to.x, to.y - height/2F, to.z, 0, 1) // bottom right + new RenderUtil.Vertex(), new RenderUtil.Vertex(), + new RenderUtil.Vertex(), new RenderUtil.Vertex() }); } + public void set(Vector3f from, Vector3f to, float height) { + corners[0].set(from.x, from.y - height/2F, from.z, 0, 0); // bottom left + corners[1].set(from.x, from.y + height/2F, from.z, 1, 0); // top left + corners[2].set(to.x, to.y + height/2F, to.z, 1, 1); // top right + corners[3].set(to.x, to.y - height/2F, to.z, 0, 1); // bottom right + } + public void forEachCorner(Consumer transformer) { for (var corner : corners) { transformer.accept(corner); diff --git a/src/main/java/com/minelittlepony/unicopia/client/render/bezier/Trail.java b/src/main/java/com/minelittlepony/unicopia/client/render/bezier/Trail.java index 8bfd4c5d..f94d2ab3 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/render/bezier/Trail.java +++ b/src/main/java/com/minelittlepony/unicopia/client/render/bezier/Trail.java @@ -63,8 +63,8 @@ public class Trail { return segments.indexOf(this) < segments.size() - 1 && age++ >= maxAge; } - public BezierSegment getPlane(Segment to) { - return new BezierSegment(offset, to.offset, height); + public void getPlane(Segment to, BezierSegment segment) { + segment.set(offset, to.offset, height); } } }