-
Notifications
You must be signed in to change notification settings - Fork 203
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add fancy effect for fusion reactor (#1497)
- Loading branch information
1 parent
5ef9d8e
commit 0a2f28a
Showing
8 changed files
with
252 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
29 changes: 29 additions & 0 deletions
29
src/main/java/com/gregtechceu/gtceu/client/renderer/GTRenderTypes.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package com.gregtechceu.gtceu.client.renderer; | ||
|
||
import net.minecraft.client.renderer.RenderStateShard; | ||
import net.minecraft.client.renderer.RenderType; | ||
import net.minecraftforge.api.distmarker.Dist; | ||
import net.minecraftforge.api.distmarker.OnlyIn; | ||
|
||
import com.mojang.blaze3d.vertex.DefaultVertexFormat; | ||
import com.mojang.blaze3d.vertex.VertexFormat; | ||
|
||
@OnlyIn(Dist.CLIENT) | ||
public class GTRenderTypes extends RenderType { | ||
|
||
private static final RenderType LIGHT_RING = RenderType.create("light_ring", | ||
DefaultVertexFormat.POSITION_COLOR, VertexFormat.Mode.TRIANGLE_STRIP, 256, false, false, | ||
RenderType.CompositeState.builder() | ||
.setCullState(NO_CULL) | ||
.setShaderState(RenderStateShard.POSITION_COLOR_SHADER) | ||
.createCompositeState(false)); | ||
|
||
private GTRenderTypes(String name, VertexFormat format, VertexFormat.Mode mode, int bufferSize, | ||
boolean affectsCrumbling, boolean sortOnUpload, Runnable setupState, Runnable clearState) { | ||
super(name, format, mode, bufferSize, affectsCrumbling, sortOnUpload, setupState, clearState); | ||
} | ||
|
||
public static RenderType getLightRing() { | ||
return LIGHT_RING; | ||
} | ||
} |
80 changes: 80 additions & 0 deletions
80
src/main/java/com/gregtechceu/gtceu/client/renderer/machine/FusionReactorRenderer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
package com.gregtechceu.gtceu.client.renderer.machine; | ||
|
||
import com.gregtechceu.gtceu.GTCEu; | ||
import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; | ||
import com.gregtechceu.gtceu.api.pattern.util.RelativeDirection; | ||
import com.gregtechceu.gtceu.client.renderer.GTRenderTypes; | ||
import com.gregtechceu.gtceu.client.util.BloomUtils; | ||
import com.gregtechceu.gtceu.client.util.RenderBufferHelper; | ||
import com.gregtechceu.gtceu.common.machine.multiblock.electric.FusionReactorMachine; | ||
|
||
import com.lowdragmc.lowdraglib.utils.ColorUtils; | ||
import com.lowdragmc.lowdraglib.utils.interpolate.Eases; | ||
import com.lowdragmc.shimmer.client.shader.RenderUtils; | ||
|
||
import net.minecraft.client.renderer.MultiBufferSource; | ||
import net.minecraft.core.Direction; | ||
import net.minecraft.resources.ResourceLocation; | ||
import net.minecraft.world.level.block.entity.BlockEntity; | ||
import net.minecraftforge.api.distmarker.Dist; | ||
import net.minecraftforge.api.distmarker.OnlyIn; | ||
|
||
import com.mojang.blaze3d.vertex.PoseStack; | ||
|
||
public class FusionReactorRenderer extends WorkableCasingMachineRenderer { | ||
|
||
public FusionReactorRenderer(ResourceLocation baseCasing, ResourceLocation workableModel, boolean tint) { | ||
super(baseCasing, workableModel, tint); | ||
} | ||
|
||
@Override | ||
@OnlyIn(Dist.CLIENT) | ||
public void render(BlockEntity blockEntity, float partialTicks, PoseStack stack, MultiBufferSource buffer, | ||
int combinedLight, int combinedOverlay) { | ||
if (blockEntity instanceof IMachineBlockEntity machineBlockEntity && | ||
machineBlockEntity.getMetaMachine() instanceof FusionReactorMachine machine) { | ||
if (GTCEu.isShimmerLoaded()) { | ||
PoseStack finalStack = RenderUtils.copyPoseStack(stack); | ||
BloomUtils.entityBloom(source -> renderLightRing(machine, partialTicks, finalStack, source)); | ||
} else { | ||
renderLightRing(machine, partialTicks, stack, buffer); | ||
} | ||
} | ||
} | ||
|
||
@OnlyIn(Dist.CLIENT) | ||
private void renderLightRing(FusionReactorMachine machine, float partialTicks, PoseStack stack, | ||
MultiBufferSource buffer) { | ||
var color = machine.getColor(); | ||
if (color == -1) return; | ||
int ringColor = ColorUtils.blendColor(color, -1, Eases.EaseQuadIn.getInterpolation( | ||
Math.abs((Math.abs(machine.getOffsetTimer() % 50) + partialTicks) - 25) / 25)); | ||
var front = machine.getFrontFacing(); | ||
var upwards = machine.getUpwardsFacing(); | ||
var flipped = machine.isFlipped(); | ||
Direction relativeBack = RelativeDirection.BACK.getRelativeFacing(front, upwards, flipped); | ||
Direction.Axis axis = RelativeDirection.UP.getRelativeFacing(front, upwards, flipped).getAxis(); | ||
float a = ColorUtils.alpha(ringColor); | ||
float r = ColorUtils.red(ringColor); | ||
float g = ColorUtils.green(ringColor); | ||
float b = ColorUtils.blue(ringColor); | ||
RenderBufferHelper.renderRing(stack, buffer.getBuffer(GTRenderTypes.getLightRing()), | ||
relativeBack.getStepX() * 7 + 0.5F, | ||
relativeBack.getStepY() * 7 + 0.5F, | ||
relativeBack.getStepZ() * 7 + 0.5F, | ||
6, 0.2F, 10, 20, | ||
r, g, b, a, axis); | ||
} | ||
|
||
@Override | ||
@OnlyIn(Dist.CLIENT) | ||
public boolean hasTESR(BlockEntity blockEntity) { | ||
return true; | ||
} | ||
|
||
@Override | ||
@OnlyIn(Dist.CLIENT) | ||
public boolean isGlobalRenderer(BlockEntity blockEntity) { | ||
return true; | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
src/main/java/com/gregtechceu/gtceu/client/util/BloomUtils.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package com.gregtechceu.gtceu.client.util; | ||
|
||
import com.lowdragmc.shimmer.client.postprocessing.PostProcessing; | ||
|
||
import net.minecraft.client.renderer.MultiBufferSource; | ||
import net.minecraftforge.api.distmarker.Dist; | ||
import net.minecraftforge.api.distmarker.OnlyIn; | ||
|
||
import java.util.function.Consumer; | ||
|
||
@OnlyIn(Dist.CLIENT) | ||
public class BloomUtils { | ||
|
||
public static void entityBloom(Consumer<MultiBufferSource> sourceConsumer) { | ||
// Shimmer will call PostProcessing.BLOOM_UNREAL.renderEntityPost in LevelRenderer#renderLevel | ||
// We probably don't need to call it ourselves | ||
PostProcessing.BLOOM_UNREAL.postEntity(sourceConsumer); | ||
} | ||
} |
91 changes: 91 additions & 0 deletions
91
src/main/java/com/gregtechceu/gtceu/client/util/RenderBufferHelper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
package com.gregtechceu.gtceu.client.util; | ||
|
||
import net.minecraft.core.Direction; | ||
import net.minecraft.util.Mth; | ||
import net.minecraftforge.api.distmarker.Dist; | ||
import net.minecraftforge.api.distmarker.OnlyIn; | ||
|
||
import com.mojang.blaze3d.vertex.PoseStack; | ||
import com.mojang.blaze3d.vertex.VertexConsumer; | ||
import org.joml.Matrix4f; | ||
|
||
@OnlyIn(Dist.CLIENT) | ||
public class RenderBufferHelper { | ||
|
||
/** | ||
* | ||
* Draw a ring torus | ||
* | ||
* @param poseStack The stack used to store the transformation matrix. | ||
* @param buffer Vertex consumer, which is used to cache vertex data. | ||
* @param x The coordinates of the center | ||
* @param y The coordinates of the center | ||
* @param z The coordinates of the center | ||
* @param r The large radius of the torus, that is, the distance from the center of the torus to center of | ||
* the "pipe". | ||
* @param tubeRadius The small radius of the "pipe", i.e. the thickness of the "pipe". | ||
* @param sides The number of subdivisions of the "pipe". | ||
* @param segments The number of subdivisions for the ring. | ||
* @param red color | ||
* @param green color | ||
* @param blue color | ||
* @param alpha transparency | ||
* @param axis The axial direction of the "ring pipe" determines which axis the "ring pipe" rotates around. | ||
*/ | ||
public static void renderRing(PoseStack poseStack, VertexConsumer buffer, float x, float y, float z, float r, | ||
float tubeRadius, | ||
int sides, int segments, float red, float green, float blue, float alpha, | ||
Direction.Axis axis) { | ||
Matrix4f mat = poseStack.last().pose(); | ||
float sideDelta = (float) (2.0 * Math.PI / sides); // Subdivision angle of the "pipe" | ||
float ringDelta = (float) (2.0 * Math.PI / segments); // Subdivision angle of the ring | ||
float theta = 0; // θ, sin(θ), cos(θ) Main angle | ||
float cosTheta = 1.0F; | ||
float sinTheta = 0.0F; | ||
|
||
float phi, sinPhi, cosPhi; // φ, sin(φ), cos(φ) Side angle | ||
float dist; // The distance from the point to the center of the ring pipe | ||
|
||
// Iterate through each subdivision of the ring | ||
for (int i = 0; i < segments; i++) { | ||
float theta1 = theta + ringDelta; | ||
float cosTheta1 = Mth.cos(theta1); | ||
float sinTheta1 = Mth.sin(theta1); | ||
|
||
// Iterate through each subdivision of the "pipe" | ||
phi = 0; | ||
for (int j = 0; j <= sides; j++) { | ||
phi = phi + sideDelta; | ||
cosPhi = Mth.cos(phi); | ||
sinPhi = Mth.sin(phi); | ||
dist = r + (tubeRadius * cosPhi); | ||
|
||
switch (axis) { | ||
case Y: | ||
buffer.vertex(mat, x + sinTheta * dist, y + tubeRadius * sinPhi, z + cosTheta * dist) | ||
.color(red, green, blue, alpha).endVertex(); | ||
buffer.vertex(mat, x + sinTheta1 * dist, y + tubeRadius * sinPhi, z + cosTheta1 * dist) | ||
.color(red, green, blue, alpha).endVertex(); | ||
break; | ||
case X: | ||
buffer.vertex(mat, x + tubeRadius * sinPhi, y + sinTheta * dist, z + cosTheta * dist) | ||
.color(red, green, blue, alpha).endVertex(); | ||
buffer.vertex(mat, x + tubeRadius * sinPhi, y + sinTheta1 * dist, z + cosTheta1 * dist) | ||
.color(red, green, blue, alpha).endVertex(); | ||
break; | ||
case Z: | ||
buffer.vertex(mat, x + cosTheta * dist, y + sinTheta * dist, z + tubeRadius * sinPhi) | ||
.color(red, green, blue, alpha).endVertex(); | ||
buffer.vertex(mat, x + cosTheta1 * dist, y + sinTheta1 * dist, z + tubeRadius * sinPhi) | ||
.color(red, green, blue, alpha).endVertex(); | ||
break; | ||
} | ||
|
||
} | ||
theta = theta1; | ||
cosTheta = cosTheta1; | ||
sinTheta = sinTheta1; | ||
|
||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters