minecraft-src/net/minecraft/client/renderer/blockentity/BlockEntityRenderDispatcher.java
2025-07-04 01:41:11 +03:00

137 lines
5.1 KiB
Java

package net.minecraft.client.renderer.blockentity;
import com.google.common.collect.ImmutableMap;
import com.mojang.blaze3d.vertex.PoseStack;
import java.util.Map;
import java.util.function.Supplier;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.CrashReport;
import net.minecraft.CrashReportCategory;
import net.minecraft.ReportedException;
import net.minecraft.client.Camera;
import net.minecraft.client.gui.Font;
import net.minecraft.client.model.geom.EntityModelSet;
import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.block.BlockRenderDispatcher;
import net.minecraft.client.renderer.entity.EntityRenderDispatcher;
import net.minecraft.client.renderer.entity.ItemRenderer;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.server.packs.resources.ResourceManager;
import net.minecraft.server.packs.resources.ResourceManagerReloadListener;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.phys.HitResult;
import org.jetbrains.annotations.Nullable;
@Environment(EnvType.CLIENT)
public class BlockEntityRenderDispatcher implements ResourceManagerReloadListener {
private Map<BlockEntityType<?>, BlockEntityRenderer<?>> renderers = ImmutableMap.of();
private final Font font;
private final EntityModelSet entityModelSet;
public Level level;
public Camera camera;
public HitResult cameraHitResult;
private final Supplier<BlockRenderDispatcher> blockRenderDispatcher;
private final Supplier<ItemRenderer> itemRenderer;
private final Supplier<EntityRenderDispatcher> entityRenderer;
public BlockEntityRenderDispatcher(
Font font,
EntityModelSet entityModelSet,
Supplier<BlockRenderDispatcher> blockRenderDispatcher,
Supplier<ItemRenderer> itemRenderer,
Supplier<EntityRenderDispatcher> entityRenderer
) {
this.itemRenderer = itemRenderer;
this.entityRenderer = entityRenderer;
this.font = font;
this.entityModelSet = entityModelSet;
this.blockRenderDispatcher = blockRenderDispatcher;
}
@Nullable
public <E extends BlockEntity> BlockEntityRenderer<E> getRenderer(E blockEntity) {
return (BlockEntityRenderer<E>)this.renderers.get(blockEntity.getType());
}
public void prepare(Level level, Camera camera, HitResult cameraHitResult) {
if (this.level != level) {
this.setLevel(level);
}
this.camera = camera;
this.cameraHitResult = cameraHitResult;
}
public <E extends BlockEntity> void render(E blockEntity, float partialTick, PoseStack poseStack, MultiBufferSource bufferSource) {
BlockEntityRenderer<E> blockEntityRenderer = this.getRenderer(blockEntity);
if (blockEntityRenderer != null) {
if (blockEntity.hasLevel() && blockEntity.getType().isValid(blockEntity.getBlockState())) {
if (blockEntityRenderer.shouldRender(blockEntity, this.camera.getPosition())) {
tryRender(blockEntity, () -> setupAndRender(blockEntityRenderer, blockEntity, partialTick, poseStack, bufferSource));
}
}
}
}
private static <T extends BlockEntity> void setupAndRender(
BlockEntityRenderer<T> renderer, T blockEntity, float partialTick, PoseStack poseStack, MultiBufferSource bufferSource
) {
Level level = blockEntity.getLevel();
int i;
if (level != null) {
i = LevelRenderer.getLightColor(level, blockEntity.getBlockPos());
} else {
i = 15728880;
}
renderer.render(blockEntity, partialTick, poseStack, bufferSource, i, OverlayTexture.NO_OVERLAY);
}
/**
* @return {@code true} if no renderer was found; otherwise {@code false} if render completed
*/
public <E extends BlockEntity> boolean renderItem(E blockEntity, PoseStack poseStack, MultiBufferSource bufferSource, int packedLight, int packedOverlay) {
BlockEntityRenderer<E> blockEntityRenderer = this.getRenderer(blockEntity);
if (blockEntityRenderer == null) {
return true;
} else {
tryRender(blockEntity, () -> blockEntityRenderer.render(blockEntity, 0.0F, poseStack, bufferSource, packedLight, packedOverlay));
return false;
}
}
private static void tryRender(BlockEntity blockEntity, Runnable renderer) {
try {
renderer.run();
} catch (Throwable var5) {
CrashReport crashReport = CrashReport.forThrowable(var5, "Rendering Block Entity");
CrashReportCategory crashReportCategory = crashReport.addCategory("Block Entity Details");
blockEntity.fillCrashReportCategory(crashReportCategory);
throw new ReportedException(crashReport);
}
}
public void setLevel(@Nullable Level level) {
this.level = level;
if (level == null) {
this.camera = null;
}
}
@Override
public void onResourceManagerReload(ResourceManager resourceManager) {
BlockEntityRendererProvider.Context context = new BlockEntityRendererProvider.Context(
this,
(BlockRenderDispatcher)this.blockRenderDispatcher.get(),
(ItemRenderer)this.itemRenderer.get(),
(EntityRenderDispatcher)this.entityRenderer.get(),
this.entityModelSet,
this.font
);
this.renderers = BlockEntityRenderers.createEntityRenderers(context);
}
}