MixinRenderBlockConnectedTexturesEthereal

基本信息

属性 值
类名 com.gtnewhorizons.angelicacompat.mixins.late.client.extrautils.MixinRenderBlockConnectedTexturesEthereal
目标类 com.rwtema.extrautils.block.render.RenderBlockConnectedTexturesEthereal
父类(继承目标) com.rwtema.extrautils.block.render.RenderBlockConnectedTextures
Mixin 阶段 LATE
Mixin 启用条件 PatchesConfig.patchExtraUtils == true
Mixin 注入方法 renderWorldBlock(IBlockAccess, int, int, int, Block, int, RenderBlocks)(@Overwrite)
启用版本 Minecraft 1.7.10(仅客户端)

功能

RenderBlockConnectedTexturesEthereal 是 MixinRenderBlockConnectedTextures 的子类。它的 renderWorldBlock 在父类基础上还要再绘制一层 FakeRenderEtherealBlocks(更厚的"以太"边框),这层对象也是静态共享的,同样存在多线程覆盖。

由于父类的 fakeRender 已被 Mixin 改为实例字段,而子类额外引入的 fakeRenderEthereal 仍是静态字段,父 Mixin 无法覆盖到子类的额外字段——必须在本 Mixin 单独覆写 renderWorldBlock:

@Unique
private FakeRenderEtherealBlocks newFakeRenderEthereal = new FakeRenderEtherealBlocks();

@Overwrite(remap = false)
public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId,
    RenderBlocks renderer) {
    if (renderer.hasOverrideBlockTexture()) return renderer.renderStandardBlock(block, x, y, z);

    // 第一阶段:基色 connected textures 渲染(用父类 newFakeRender,已是实例字段)
    getFakeRender().setWorld(renderer.blockAccess);
    getFakeRender().curBlock = world.getBlock(x, y, z);
    getFakeRender().curMeta = world.getBlockMetadata(x, y, z);
    block.setBlockBoundsBasedOnState(getFakeRender().blockAccess, x, y, z);
    getFakeRender().setRenderBoundsFromBlock(block);
    boolean render = getFakeRender().renderStandardBlock(block, x, y, z);

    // 第二阶段:ethereal 边框渲染(用本 Mixin 注入的实例字段 newFakeRenderEthereal)
    newFakeRenderEthereal.setWorld(renderer.blockAccess);
    newFakeRenderEthereal.curBlock = fakeRender.curBlock;        // 复用父类结果
    newFakeRenderEthereal.curMeta = fakeRender.curMeta;
    double h = 0.05D;
    newFakeRenderEthereal.setRenderBounds(h, h, h, 1.0D - h, 1.0D - h, 1.0D - h);
    render &= newFakeRenderEthereal.renderStandardBlock(block, x, y, z);

    return render;
}

fakeRender 在父类仍是静态字段(因为本 Mixin 没改父类的 fakeRender)——但因为 MixingRenderBlockConnectedTextures 已经让 getFakeRender() 返回实例 newFakeRender,这里的 getFakeRender().curBlock/curMeta 实际是父类的实例字段。fakeRender.curBlock/curMeta 单独访问会被 javac 优化为对静态字段的访问(因父类继承关系复杂),是已知的潜在边角缺陷。

实现要点

  • @Overwrite(remap = false):整个 renderWorldBlock 整体替换。
  • @author Cleptomania,@reason Thread safety fixes for ethereal connected textures ...。
  • 与 ExtraUtilsCompatHandler 配合:声明 perThread=true,Angelica 为每个 worker thread 提供独立实例。

第三方 mod 集成

仅针对 com.rwtema.extrautils.block.render.RenderBlockConnectedTexturesEthereal (Extra Utilities)。

相关条目