DisplayRenderer.java

net.minecraft.client.renderer.entity.DisplayRenderer

信息

  • 全限定名:net.minecraft.client.renderer.entity.DisplayRenderer
  • 类型:public abstract class
  • 包:net.minecraft.client.renderer.entity
  • 源码路径:src/main/java/net/minecraft/client/renderer/entity/DisplayRenderer.java
  • 起始行号:L35
  • 继承:EntityRenderer<T,ST>
  • 职责:

    TODO

字段/常量

  • BLOCK_DISPLAY_CONTEXT

    • 类型: BlockDisplayContext
    • 修饰符: public static final
    • 源码定位: L36
    • 说明:

      TODO

  • entityRenderDispatcher

    • 类型: EntityRenderDispatcher
    • 修饰符: private final
    • 源码定位: L37
    • 说明:

      TODO

  • blockModelResolver

    • 类型: BlockModelResolver
    • 修饰符: protected final
    • 源码定位: L38
    • 说明:

      TODO

内部类/嵌套类型

  • net.minecraft.client.renderer.entity.DisplayRenderer.BlockDisplayRenderer

    • 类型: class
    • 修饰符: public static
    • 源码定位: L140
    • 说明:

      TODO

  • net.minecraft.client.renderer.entity.DisplayRenderer.ItemDisplayRenderer

    • 类型: class
    • 修饰符: public static
    • 源码定位: L168
    • 说明:

      TODO

  • net.minecraft.client.renderer.entity.DisplayRenderer.TextDisplayRenderer

    • 类型: class
    • 修饰符: public static
    • 源码定位: L201
    • 说明:

      TODO

构造器

protected DisplayRenderer(EntityRendererProvider.Context context) @ L40

  • 构造器名:DisplayRenderer
  • 源码定位:L40
  • 修饰符:protected

参数:

  • context: EntityRendererProvider.Context

说明:

TODO

方法

下面的方法块按源码顺序生成。

protected AABB getBoundingBoxForCulling(T entity) @ L46

  • 方法名:getBoundingBoxForCulling
  • 源码定位:L46
  • 返回类型:AABB
  • 修饰符:protected

参数:

  • entity: T

说明:

TODO

protected boolean affectedByCulling(T entity) @ L50

  • 方法名:affectedByCulling
  • 源码定位:L50
  • 返回类型:boolean
  • 修饰符:protected

参数:

  • entity: T

说明:

TODO

private static int getBrightnessOverride(Display entity) @ L54

  • 方法名:getBrightnessOverride
  • 源码定位:L54
  • 返回类型:int
  • 修饰符:private static

参数:

  • entity: Display

说明:

TODO

protected int getSkyLightLevel(T entity, BlockPos blockPos) @ L59

  • 方法名:getSkyLightLevel
  • 源码定位:L59
  • 返回类型:int
  • 修饰符:protected

参数:

  • entity: T
  • blockPos: BlockPos

说明:

TODO

protected int getBlockLightLevel(T entity, BlockPos blockPos) @ L64

  • 方法名:getBlockLightLevel
  • 源码定位:L64
  • 返回类型:int
  • 修饰符:protected

参数:

  • entity: T
  • blockPos: BlockPos

说明:

TODO

protected float getShadowRadius(ST state) @ L69

  • 方法名:getShadowRadius
  • 源码定位:L69
  • 返回类型:float
  • 修饰符:protected

参数:

  • state: ST

说明:

TODO

protected float getShadowStrength(ST state) @ L74

  • 方法名:getShadowStrength
  • 源码定位:L74
  • 返回类型:float
  • 修饰符:protected

参数:

  • state: ST

说明:

TODO

public void submit(ST state, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, CameraRenderState camera) @ L79

  • 方法名:submit
  • 源码定位:L79
  • 返回类型:void
  • 修饰符:public

参数:

  • state: ST
  • poseStack: PoseStack
  • submitNodeCollector: SubmitNodeCollector
  • camera: CameraRenderState

说明:

TODO

private Quaternionf calculateOrientation(Display.RenderState renderState, ST state, Quaternionf output) @ L93

  • 方法名:calculateOrientation
  • 源码定位:L93
  • 返回类型:Quaternionf
  • 修饰符:private

参数:

  • renderState: Display.RenderState
  • state: ST
  • output: Quaternionf

说明:

TODO

private static float transformYRot(float cameraYRot) @ L108

  • 方法名:transformYRot
  • 源码定位:L108
  • 返回类型:float
  • 修饰符:private static

参数:

  • cameraYRot: float

说明:

TODO

private static float transformXRot(float cameraXRot) @ L112

  • 方法名:transformXRot
  • 源码定位:L112
  • 返回类型:float
  • 修饰符:private static

参数:

  • cameraXRot: float

说明:

TODO

private static <T extends Display> float entityYRot(T entity, float partialTicks) @ L116

  • 方法名:entityYRot
  • 源码定位:L116
  • 返回类型: float
  • 修饰符:private static

参数:

  • entity: T
  • partialTicks: float

说明:

TODO

private static <T extends Display> float entityXRot(T entity, float partialTicks) @ L120

  • 方法名:entityXRot
  • 源码定位:L120
  • 返回类型: float
  • 修饰符:private static

参数:

  • entity: T
  • partialTicks: float

说明:

TODO

protected abstract void submitInner(ST state, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, int lightCoords, float interpolationProgress) @ L124

  • 方法名:submitInner
  • 源码定位:L124
  • 返回类型:void
  • 修饰符:protected abstract

参数:

  • state: ST
  • poseStack: PoseStack
  • submitNodeCollector: SubmitNodeCollector
  • lightCoords: int
  • interpolationProgress: float

说明:

TODO

public void extractRenderState(T entity, ST state, float partialTicks) @ L128

  • 方法名:extractRenderState
  • 源码定位:L128
  • 返回类型:void
  • 修饰符:public

参数:

  • entity: T
  • state: ST
  • partialTicks: float

说明:

TODO

代码

@OnlyIn(Dist.CLIENT)
public abstract class DisplayRenderer<T extends Display, S, ST extends DisplayEntityRenderState> extends EntityRenderer<T, ST> {
    public static final BlockDisplayContext BLOCK_DISPLAY_CONTEXT = BlockDisplayContext.create();
    private final EntityRenderDispatcher entityRenderDispatcher;
    protected final BlockModelResolver blockModelResolver;
 
    protected DisplayRenderer(EntityRendererProvider.Context context) {
        super(context);
        this.entityRenderDispatcher = context.getEntityRenderDispatcher();
        this.blockModelResolver = context.getBlockModelResolver();
    }
 
    protected AABB getBoundingBoxForCulling(T entity) {
        return entity.getBoundingBoxForCulling();
    }
 
    protected boolean affectedByCulling(T entity) {
        return entity.affectedByCulling();
    }
 
    private static int getBrightnessOverride(Display entity) {
        Display.RenderState renderState = entity.renderState();
        return renderState != null ? renderState.brightnessOverride() : -1;
    }
 
    protected int getSkyLightLevel(T entity, BlockPos blockPos) {
        int packedBrightnessOverride = getBrightnessOverride(entity);
        return packedBrightnessOverride != -1 ? LightCoordsUtil.sky(packedBrightnessOverride) : super.getSkyLightLevel(entity, blockPos);
    }
 
    protected int getBlockLightLevel(T entity, BlockPos blockPos) {
        int packedBrightnessOverride = getBrightnessOverride(entity);
        return packedBrightnessOverride != -1 ? LightCoordsUtil.block(packedBrightnessOverride) : super.getBlockLightLevel(entity, blockPos);
    }
 
    protected float getShadowRadius(ST state) {
        Display.RenderState renderState = state.renderState;
        return renderState == null ? 0.0F : renderState.shadowRadius().get(state.interpolationProgress);
    }
 
    protected float getShadowStrength(ST state) {
        Display.RenderState renderState = state.renderState;
        return renderState == null ? 0.0F : renderState.shadowStrength().get(state.interpolationProgress);
    }
 
    public void submit(ST state, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, CameraRenderState camera) {
        Display.RenderState renderState = state.renderState;
        if (renderState != null && state.hasSubState()) {
            float interpolationProgress = state.interpolationProgress;
            super.submit(state, poseStack, submitNodeCollector, camera);
            poseStack.pushPose();
            poseStack.mulPose(this.calculateOrientation(renderState, state, new Quaternionf()));
            Transformation transformation = renderState.transformation().get(interpolationProgress);
            poseStack.mulPose(transformation);
            this.submitInner(state, poseStack, submitNodeCollector, state.lightCoords, interpolationProgress);
            poseStack.popPose();
        }
    }
 
    private Quaternionf calculateOrientation(Display.RenderState renderState, ST state, Quaternionf output) {
        return switch (renderState.billboardConstraints()) {
            case FIXED -> output.rotationYXZ((float) (-Math.PI / 180.0) * state.entityYRot, (float) (Math.PI / 180.0) * state.entityXRot, 0.0F);
            case HORIZONTAL -> output.rotationYXZ(
                (float) (-Math.PI / 180.0) * state.entityYRot, (float) (Math.PI / 180.0) * transformXRot(state.cameraXRot), 0.0F
            );
            case VERTICAL -> output.rotationYXZ(
                (float) (-Math.PI / 180.0) * transformYRot(state.cameraYRot), (float) (Math.PI / 180.0) * state.entityXRot, 0.0F
            );
            case CENTER -> output.rotationYXZ(
                (float) (-Math.PI / 180.0) * transformYRot(state.cameraYRot), (float) (Math.PI / 180.0) * transformXRot(state.cameraXRot), 0.0F
            );
        };
    }
 
    private static float transformYRot(float cameraYRot) {
        return cameraYRot - 180.0F;
    }
 
    private static float transformXRot(float cameraXRot) {
        return -cameraXRot;
    }
 
    private static <T extends Display> float entityYRot(T entity, float partialTicks) {
        return entity.getYRot(partialTicks);
    }
 
    private static <T extends Display> float entityXRot(T entity, float partialTicks) {
        return entity.getXRot(partialTicks);
    }
 
    protected abstract void submitInner(
        final ST state, final PoseStack poseStack, final SubmitNodeCollector submitNodeCollector, final int lightCoords, final float interpolationProgress
    );
 
    public void extractRenderState(T entity, ST state, float partialTicks) {
        super.extractRenderState(entity, state, partialTicks);
        state.renderState = entity.renderState();
        state.interpolationProgress = entity.calculateInterpolationProgress(partialTicks);
        state.entityYRot = entityYRot(entity, partialTicks);
        state.entityXRot = entityXRot(entity, partialTicks);
        Camera camera = this.entityRenderDispatcher.camera;
        state.cameraXRot = camera.xRot();
        state.cameraYRot = camera.yRot();
    }
 
    @OnlyIn(Dist.CLIENT)
    public static class BlockDisplayRenderer
        extends DisplayRenderer<Display.BlockDisplay, Display.BlockDisplay.BlockRenderState, BlockDisplayEntityRenderState> {
        protected BlockDisplayRenderer(EntityRendererProvider.Context context) {
            super(context);
        }
 
        public BlockDisplayEntityRenderState createRenderState() {
            return new BlockDisplayEntityRenderState();
        }
 
        public void extractRenderState(Display.BlockDisplay entity, BlockDisplayEntityRenderState state, float partialTicks) {
            super.extractRenderState(entity, state, partialTicks);
            Display.BlockDisplay.BlockRenderState blockRenderState = entity.blockRenderState();
            if (blockRenderState != null) {
                this.blockModelResolver.update(state.blockModel, blockRenderState.blockState(), BLOCK_DISPLAY_CONTEXT);
            } else {
                state.blockModel.clear();
            }
        }
 
        public void submitInner(
            BlockDisplayEntityRenderState state, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, int lightCoords, float interpolationProgress
        ) {
            state.blockModel.submit(poseStack, submitNodeCollector, lightCoords, OverlayTexture.NO_OVERLAY, state.outlineColor);
        }
    }
 
    @OnlyIn(Dist.CLIENT)
    public static class ItemDisplayRenderer extends DisplayRenderer<Display.ItemDisplay, Display.ItemDisplay.ItemRenderState, ItemDisplayEntityRenderState> {
        private final ItemModelResolver itemModelResolver;
 
        protected ItemDisplayRenderer(EntityRendererProvider.Context context) {
            super(context);
            this.itemModelResolver = context.getItemModelResolver();
        }
 
        public ItemDisplayEntityRenderState createRenderState() {
            return new ItemDisplayEntityRenderState();
        }
 
        public void extractRenderState(Display.ItemDisplay entity, ItemDisplayEntityRenderState state, float partialTicks) {
            super.extractRenderState(entity, state, partialTicks);
            Display.ItemDisplay.ItemRenderState itemRenderState = entity.itemRenderState();
            if (itemRenderState != null) {
                this.itemModelResolver.updateForNonLiving(state.item, itemRenderState.itemStack(), itemRenderState.itemTransform(), entity);
            } else {
                state.item.clear();
            }
        }
 
        public void submitInner(
            ItemDisplayEntityRenderState state, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, int lightCoords, float interpolationProgress
        ) {
            if (!state.item.isEmpty()) {
                poseStack.mulPose(Axis.YP.rotation((float) Math.PI));
                state.item.submit(poseStack, submitNodeCollector, lightCoords, OverlayTexture.NO_OVERLAY, state.outlineColor);
            }
        }
    }
 
    @OnlyIn(Dist.CLIENT)
    public static class TextDisplayRenderer extends DisplayRenderer<Display.TextDisplay, Display.TextDisplay.TextRenderState, TextDisplayEntityRenderState> {
        private final Font font;
 
        protected TextDisplayRenderer(EntityRendererProvider.Context context) {
            super(context);
            this.font = context.getFont();
        }
 
        public TextDisplayEntityRenderState createRenderState() {
            return new TextDisplayEntityRenderState();
        }
 
        public void extractRenderState(Display.TextDisplay entity, TextDisplayEntityRenderState state, float partialTicks) {
            super.extractRenderState(entity, state, partialTicks);
            state.textRenderState = entity.textRenderState();
            state.cachedInfo = entity.cacheDisplay(this::splitLines);
        }
 
        private Display.TextDisplay.CachedInfo splitLines(Component input, int width) {
            List<FormattedCharSequence> lines = this.font.split(input, width);
            List<Display.TextDisplay.CachedLine> result = new ArrayList<>(lines.size());
            int maxLineWidth = 0;
 
            for (FormattedCharSequence line : lines) {
                int lineWidth = this.font.width(line);
                maxLineWidth = Math.max(maxLineWidth, lineWidth);
                result.add(new Display.TextDisplay.CachedLine(line, lineWidth));
            }
 
            return new Display.TextDisplay.CachedInfo(result, maxLineWidth);
        }
 
        public void submitInner(
            TextDisplayEntityRenderState state, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, int lightCoords, float interpolationProgress
        ) {
            Display.TextDisplay.TextRenderState renderState = state.textRenderState;
            byte flags = renderState.flags();
            boolean seeThrough = (flags & 2) != 0;
            boolean useDefaultBackground = (flags & 4) != 0;
            boolean shadow = (flags & 1) != 0;
            Display.TextDisplay.Align alignment = Display.TextDisplay.getAlign(flags);
            byte textOpacity = (byte)renderState.textOpacity().get(interpolationProgress);
            int backgroundColor;
            if (useDefaultBackground) {
                float backgroundAlpha = Minecraft.getInstance().gameRenderer.getGameRenderState().optionsRenderState.getBackgroundOpacity(0.25F);
                backgroundColor = (int)(backgroundAlpha * 255.0F) << 24;
            } else {
                backgroundColor = renderState.backgroundColor().get(interpolationProgress);
            }
 
            float y = 0.0F;
            Matrix4f pose = poseStack.last().pose();
            pose.rotate((float) Math.PI, 0.0F, 1.0F, 0.0F);
            pose.scale(-0.025F, -0.025F, -0.025F);
            Display.TextDisplay.CachedInfo cachedInfo = state.cachedInfo;
            int lineSpacing = 1;
            int lineHeight = 9 + 1;
            int width = cachedInfo.width();
            int height = cachedInfo.lines().size() * lineHeight - 1;
            pose.translate(1.0F - width / 2.0F, -height, 0.0F);
            if (backgroundColor != 0) {
                submitNodeCollector.submitCustomGeometry(
                    poseStack, seeThrough ? RenderTypes.textBackgroundSeeThrough() : RenderTypes.textBackground(), (lambdaPose, buffer) -> {
                        buffer.addVertex(lambdaPose, -1.0F, -1.0F, 0.0F).setColor(backgroundColor).setLight(lightCoords);
                        buffer.addVertex(lambdaPose, -1.0F, (float)height, 0.0F).setColor(backgroundColor).setLight(lightCoords);
                        buffer.addVertex(lambdaPose, (float)width, (float)height, 0.0F).setColor(backgroundColor).setLight(lightCoords);
                        buffer.addVertex(lambdaPose, (float)width, -1.0F, 0.0F).setColor(backgroundColor).setLight(lightCoords);
                    }
                );
            }
 
            OrderedSubmitNodeCollector textCollector = submitNodeCollector.order(backgroundColor != 0 ? 1 : 0);
 
            for (Display.TextDisplay.CachedLine line : cachedInfo.lines()) {
                float offset = switch (alignment) {
                    case LEFT -> 0.0F;
                    case RIGHT -> width - line.width();
                    case CENTER -> width / 2.0F - line.width() / 2.0F;
                };
                textCollector.submitText(
                    poseStack,
                    offset,
                    y,
                    line.contents(),
                    shadow,
                    seeThrough ? Font.DisplayMode.SEE_THROUGH : Font.DisplayMode.POLYGON_OFFSET,
                    lightCoords,
                    textOpacity << 24 | 16777215,
                    0,
                    0
                );
                y += lineHeight;
            }
        }
    }
}

引用的其他类