package net.minecraft.client.renderer.entity; import com.mojang.blaze3d.vertex.PoseStack; 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.MapRenderer; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.block.BlockRenderDispatcher; import net.minecraft.client.renderer.block.ModelBlockRenderer; import net.minecraft.client.renderer.block.model.BlockStateModel; import net.minecraft.client.renderer.entity.state.ItemFrameRenderState; import net.minecraft.client.renderer.item.ItemModelResolver; import net.minecraft.client.renderer.texture.OverlayTexture; import net.minecraft.client.renderer.texture.TextureAtlas; import net.minecraft.client.resources.model.BlockStateDefinitions; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.network.chat.Component; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.decoration.ItemFrame; import net.minecraft.world.item.ItemDisplayContext; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.saveddata.maps.MapId; import net.minecraft.world.level.saveddata.maps.MapItemSavedData; import net.minecraft.world.phys.Vec3; @Environment(EnvType.CLIENT) public class ItemFrameRenderer extends EntityRenderer { public static final int GLOW_FRAME_BRIGHTNESS = 5; public static final int BRIGHT_MAP_LIGHT_ADJUSTMENT = 30; private final ItemModelResolver itemModelResolver; private final MapRenderer mapRenderer; private final BlockRenderDispatcher blockRenderer; public ItemFrameRenderer(EntityRendererProvider.Context context) { super(context); this.itemModelResolver = context.getItemModelResolver(); this.mapRenderer = context.getMapRenderer(); this.blockRenderer = context.getBlockRenderDispatcher(); } protected int getBlockLightLevel(T entity, BlockPos pos) { return entity.getType() == EntityType.GLOW_ITEM_FRAME ? Math.max(5, super.getBlockLightLevel(entity, pos)) : super.getBlockLightLevel(entity, pos); } public void render(ItemFrameRenderState renderState, PoseStack poseStack, MultiBufferSource bufferSource, int packedLight) { super.render(renderState, poseStack, bufferSource, packedLight); poseStack.pushPose(); Direction direction = renderState.direction; Vec3 vec3 = this.getRenderOffset(renderState); poseStack.translate(-vec3.x(), -vec3.y(), -vec3.z()); double d = 0.46875; poseStack.translate(direction.getStepX() * 0.46875, direction.getStepY() * 0.46875, direction.getStepZ() * 0.46875); float f; float g; if (direction.getAxis().isHorizontal()) { f = 0.0F; g = 180.0F - direction.toYRot(); } else { f = -90 * direction.getAxisDirection().getStep(); g = 180.0F; } poseStack.mulPose(Axis.XP.rotationDegrees(f)); poseStack.mulPose(Axis.YP.rotationDegrees(g)); if (!renderState.isInvisible) { BlockState blockState = BlockStateDefinitions.getItemFrameFakeState(renderState.isGlowFrame, renderState.mapId != null); BlockStateModel blockStateModel = this.blockRenderer.getBlockModel(blockState); poseStack.pushPose(); poseStack.translate(-0.5F, -0.5F, -0.5F); ModelBlockRenderer.renderModel( poseStack.last(), bufferSource.getBuffer(RenderType.entitySolidZOffsetForward(TextureAtlas.LOCATION_BLOCKS)), blockStateModel, 1.0F, 1.0F, 1.0F, packedLight, OverlayTexture.NO_OVERLAY ); poseStack.popPose(); } if (renderState.isInvisible) { poseStack.translate(0.0F, 0.0F, 0.5F); } else { poseStack.translate(0.0F, 0.0F, 0.4375F); } if (renderState.mapId != null) { int i = renderState.rotation % 4 * 2; poseStack.mulPose(Axis.ZP.rotationDegrees(i * 360.0F / 8.0F)); poseStack.mulPose(Axis.ZP.rotationDegrees(180.0F)); float h = 0.0078125F; poseStack.scale(0.0078125F, 0.0078125F, 0.0078125F); poseStack.translate(-64.0F, -64.0F, 0.0F); poseStack.translate(0.0F, 0.0F, -1.0F); int j = this.getLightCoords(renderState.isGlowFrame, 15728850, packedLight); this.mapRenderer.render(renderState.mapRenderState, poseStack, bufferSource, true, j); } else if (!renderState.item.isEmpty()) { poseStack.mulPose(Axis.ZP.rotationDegrees(renderState.rotation * 360.0F / 8.0F)); int i = this.getLightCoords(renderState.isGlowFrame, 15728880, packedLight); poseStack.scale(0.5F, 0.5F, 0.5F); renderState.item.render(poseStack, bufferSource, i, OverlayTexture.NO_OVERLAY); } poseStack.popPose(); } private int getLightCoords(boolean isGlowFrame, int glowLight, int normalLight) { return isGlowFrame ? glowLight : normalLight; } public Vec3 getRenderOffset(ItemFrameRenderState renderState) { return new Vec3(renderState.direction.getStepX() * 0.3F, -0.25, renderState.direction.getStepZ() * 0.3F); } protected boolean shouldShowName(T entity, double distanceToCameraSq) { return Minecraft.renderNames() && this.entityRenderDispatcher.crosshairPickEntity == entity && entity.getItem().getCustomName() != null; } protected Component getNameTag(T entity) { return entity.getItem().getHoverName(); } public ItemFrameRenderState createRenderState() { return new ItemFrameRenderState(); } public void extractRenderState(T entity, ItemFrameRenderState reusedState, float partialTick) { super.extractRenderState(entity, reusedState, partialTick); reusedState.direction = entity.getDirection(); ItemStack itemStack = entity.getItem(); this.itemModelResolver.updateForNonLiving(reusedState.item, itemStack, ItemDisplayContext.FIXED, entity); reusedState.rotation = entity.getRotation(); reusedState.isGlowFrame = entity.getType() == EntityType.GLOW_ITEM_FRAME; reusedState.mapId = null; if (!itemStack.isEmpty()) { MapId mapId = entity.getFramedMapId(itemStack); if (mapId != null) { MapItemSavedData mapItemSavedData = entity.level().getMapData(mapId); if (mapItemSavedData != null) { this.mapRenderer.extractRenderState(mapId, mapItemSavedData, reusedState.mapRenderState); reusedState.mapId = mapId; } } } } }