minecraft-src/net/minecraft/client/renderer/ScreenEffectRenderer.java
2025-09-18 12:27:44 +00:00

208 lines
8.5 KiB
Java

package net.minecraft.client.renderer;
import com.mojang.blaze3d.platform.Lighting;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.mojang.math.Axis;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.resources.model.ModelBakery;
import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.FluidTags;
import net.minecraft.util.ARGB;
import net.minecraft.util.Mth;
import net.minecraft.util.RandomSource;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemDisplayContext;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.RenderShape;
import net.minecraft.world.level.block.state.BlockState;
import org.jetbrains.annotations.Nullable;
import org.joml.Matrix4f;
@Environment(EnvType.CLIENT)
public class ScreenEffectRenderer {
private static final ResourceLocation UNDERWATER_LOCATION = ResourceLocation.withDefaultNamespace("textures/misc/underwater.png");
private final Minecraft minecraft;
private final MultiBufferSource bufferSource;
public static final int ITEM_ACTIVATION_ANIMATION_LENGTH = 40;
@Nullable
private ItemStack itemActivationItem;
private int itemActivationTicks;
private float itemActivationOffX;
private float itemActivationOffY;
public ScreenEffectRenderer(Minecraft minecraft, MultiBufferSource bufferSource) {
this.minecraft = minecraft;
this.bufferSource = bufferSource;
}
public void tick() {
if (this.itemActivationTicks > 0) {
this.itemActivationTicks--;
if (this.itemActivationTicks == 0) {
this.itemActivationItem = null;
}
}
}
public void renderScreenEffect(boolean sleeping, float partialTick) {
PoseStack poseStack = new PoseStack();
Player player = this.minecraft.player;
if (this.minecraft.options.getCameraType().isFirstPerson() && !sleeping) {
if (!player.noPhysics) {
BlockState blockState = getViewBlockingState(player);
if (blockState != null) {
renderTex(this.minecraft.getBlockRenderer().getBlockModelShaper().getParticleIcon(blockState), poseStack, this.bufferSource);
}
}
if (!this.minecraft.player.isSpectator()) {
if (this.minecraft.player.isEyeInFluid(FluidTags.WATER)) {
renderWater(this.minecraft, poseStack, this.bufferSource);
}
if (this.minecraft.player.isOnFire()) {
renderFire(poseStack, this.bufferSource);
}
}
}
if (!this.minecraft.options.hideGui) {
this.renderItemActivationAnimation(poseStack, partialTick);
}
}
private void renderItemActivationAnimation(PoseStack poseStack, float partialTick) {
if (this.itemActivationItem != null && this.itemActivationTicks > 0) {
int i = 40 - this.itemActivationTicks;
float f = (i + partialTick) / 40.0F;
float g = f * f;
float h = f * g;
float j = 10.25F * h * g - 24.95F * g * g + 25.5F * h - 13.8F * g + 4.0F * f;
float k = j * (float) Math.PI;
float l = (float)this.minecraft.getWindow().getWidth() / this.minecraft.getWindow().getHeight();
float m = this.itemActivationOffX * 0.3F * l;
float n = this.itemActivationOffY * 0.3F;
poseStack.pushPose();
poseStack.translate(m * Mth.abs(Mth.sin(k * 2.0F)), n * Mth.abs(Mth.sin(k * 2.0F)), -10.0F + 9.0F * Mth.sin(k));
float o = 0.8F;
poseStack.scale(0.8F, 0.8F, 0.8F);
poseStack.mulPose(Axis.YP.rotationDegrees(900.0F * Mth.abs(Mth.sin(k))));
poseStack.mulPose(Axis.XP.rotationDegrees(6.0F * Mth.cos(f * 8.0F)));
poseStack.mulPose(Axis.ZP.rotationDegrees(6.0F * Mth.cos(f * 8.0F)));
this.minecraft.gameRenderer.getLighting().setupFor(Lighting.Entry.ITEMS_3D);
this.minecraft
.getItemRenderer()
.renderStatic(this.itemActivationItem, ItemDisplayContext.FIXED, 15728880, OverlayTexture.NO_OVERLAY, poseStack, this.bufferSource, this.minecraft.level, 0);
poseStack.popPose();
}
}
public void resetItemActivation() {
this.itemActivationItem = null;
}
public void displayItemActivation(ItemStack item, RandomSource random) {
this.itemActivationItem = item;
this.itemActivationTicks = 40;
this.itemActivationOffX = random.nextFloat() * 2.0F - 1.0F;
this.itemActivationOffY = random.nextFloat() * 2.0F - 1.0F;
}
@Nullable
private static BlockState getViewBlockingState(Player player) {
BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos();
for (int i = 0; i < 8; i++) {
double d = player.getX() + ((i >> 0) % 2 - 0.5F) * player.getBbWidth() * 0.8F;
double e = player.getEyeY() + ((i >> 1) % 2 - 0.5F) * 0.1F * player.getScale();
double f = player.getZ() + ((i >> 2) % 2 - 0.5F) * player.getBbWidth() * 0.8F;
mutableBlockPos.set(d, e, f);
BlockState blockState = player.level().getBlockState(mutableBlockPos);
if (blockState.getRenderShape() != RenderShape.INVISIBLE && blockState.isViewBlocking(player.level(), mutableBlockPos)) {
return blockState;
}
}
return null;
}
private static void renderTex(TextureAtlasSprite texture, PoseStack poseStack, MultiBufferSource bufferSource) {
float f = 0.1F;
int i = ARGB.colorFromFloat(1.0F, 0.1F, 0.1F, 0.1F);
float g = -1.0F;
float h = 1.0F;
float j = -1.0F;
float k = 1.0F;
float l = -0.5F;
float m = texture.getU0();
float n = texture.getU1();
float o = texture.getV0();
float p = texture.getV1();
Matrix4f matrix4f = poseStack.last().pose();
VertexConsumer vertexConsumer = bufferSource.getBuffer(RenderType.blockScreenEffect(texture.atlasLocation()));
vertexConsumer.addVertex(matrix4f, -1.0F, -1.0F, -0.5F).setUv(n, p).setColor(i);
vertexConsumer.addVertex(matrix4f, 1.0F, -1.0F, -0.5F).setUv(m, p).setColor(i);
vertexConsumer.addVertex(matrix4f, 1.0F, 1.0F, -0.5F).setUv(m, o).setColor(i);
vertexConsumer.addVertex(matrix4f, -1.0F, 1.0F, -0.5F).setUv(n, o).setColor(i);
}
private static void renderWater(Minecraft minecraft, PoseStack poseStack, MultiBufferSource bufferSource) {
BlockPos blockPos = BlockPos.containing(minecraft.player.getX(), minecraft.player.getEyeY(), minecraft.player.getZ());
float f = LightTexture.getBrightness(minecraft.player.level().dimensionType(), minecraft.player.level().getMaxLocalRawBrightness(blockPos));
int i = ARGB.colorFromFloat(0.1F, f, f, f);
float g = 4.0F;
float h = -1.0F;
float j = 1.0F;
float k = -1.0F;
float l = 1.0F;
float m = -0.5F;
float n = -minecraft.player.getYRot() / 64.0F;
float o = minecraft.player.getXRot() / 64.0F;
Matrix4f matrix4f = poseStack.last().pose();
VertexConsumer vertexConsumer = bufferSource.getBuffer(RenderType.blockScreenEffect(UNDERWATER_LOCATION));
vertexConsumer.addVertex(matrix4f, -1.0F, -1.0F, -0.5F).setUv(4.0F + n, 4.0F + o).setColor(i);
vertexConsumer.addVertex(matrix4f, 1.0F, -1.0F, -0.5F).setUv(0.0F + n, 4.0F + o).setColor(i);
vertexConsumer.addVertex(matrix4f, 1.0F, 1.0F, -0.5F).setUv(0.0F + n, 0.0F + o).setColor(i);
vertexConsumer.addVertex(matrix4f, -1.0F, 1.0F, -0.5F).setUv(4.0F + n, 0.0F + o).setColor(i);
}
private static void renderFire(PoseStack poseStack, MultiBufferSource bufferSource) {
TextureAtlasSprite textureAtlasSprite = ModelBakery.FIRE_1.sprite();
VertexConsumer vertexConsumer = bufferSource.getBuffer(RenderType.fireScreenEffect(textureAtlasSprite.atlasLocation()));
float f = textureAtlasSprite.getU0();
float g = textureAtlasSprite.getU1();
float h = (f + g) / 2.0F;
float i = textureAtlasSprite.getV0();
float j = textureAtlasSprite.getV1();
float k = (i + j) / 2.0F;
float l = textureAtlasSprite.uvShrinkRatio();
float m = Mth.lerp(l, f, h);
float n = Mth.lerp(l, g, h);
float o = Mth.lerp(l, i, k);
float p = Mth.lerp(l, j, k);
float q = 1.0F;
for (int r = 0; r < 2; r++) {
poseStack.pushPose();
float s = -0.5F;
float t = 0.5F;
float u = -0.5F;
float v = 0.5F;
float w = -0.5F;
poseStack.translate(-(r * 2 - 1) * 0.24F, -0.3F, 0.0F);
poseStack.mulPose(Axis.YP.rotationDegrees((r * 2 - 1) * 10.0F));
Matrix4f matrix4f = poseStack.last().pose();
vertexConsumer.addVertex(matrix4f, -0.5F, -0.5F, -0.5F).setUv(n, p).setColor(1.0F, 1.0F, 1.0F, 0.9F);
vertexConsumer.addVertex(matrix4f, 0.5F, -0.5F, -0.5F).setUv(m, p).setColor(1.0F, 1.0F, 1.0F, 0.9F);
vertexConsumer.addVertex(matrix4f, 0.5F, 0.5F, -0.5F).setUv(m, o).setColor(1.0F, 1.0F, 1.0F, 0.9F);
vertexConsumer.addVertex(matrix4f, -0.5F, 0.5F, -0.5F).setUv(n, o).setColor(1.0F, 1.0F, 1.0F, 0.9F);
poseStack.popPose();
}
}
}