纹理加载与拼接 Mixin
基本信息
| 属性 | 值 |
|---|---|
| Mixins 条目 | 4(STB_TEXTURE_LOADING、STB_TEXTURE_STITCHING、STB_TEXTURE_STITCHING_FORCE、STB_TEXTURE_STITCHING_FOR_FASCRAFT) |
| 阶段 | 全部 EARLY |
| 包含的 mixin 类 | 4 |
| 共同目标 | net.minecraft.client.renderer.texture.Stitcher(3 个条目) |
| 注册位置 | Mixins.java:20-23、:65-80 |
LWJGL3ify 用 LWJGL3 的 lwjgl-spng(dependencies.gradle:28-29)替换 Minecraft 1.7.10 原生的 PNG 解码路径,并用 stb_rectpack 替换原版 Stitcher 的图集拼接算法。
功能
STB_TEXTURE_LOADING(Mixins.java:20-23)
2 个 mixin,条件受 Config.MIXIN_STBI_TEXTURE_LOADING 控制:
game.MixinTextureAtlasSprite目标TextureAtlasSprite,在loadSprite的TAIL注入(MixinTextureAtlasSprite.java)。文件内有一个catch (Exception e)。game.MixinTextureMap目标TextureMap,用@Redirect替换。文件内有一个catch (IOException ex)。
由 lwjgl-spng 承担实际解码(dependencies.gradle:28-29 引入 org.lwjgl:lwjgl-spng 及对应 natives)。
STB_TEXTURE_STITCHING 及其 2 个变体(Mixins.java:65-80)
这 3 个条目共用同一个 mixin 类 game.MixinStitcher(目标 Stitcher),靠互斥的目标模组条件区分。源码注释(Mixins.java:61-64)给出的应用规则是:没有 FastCraft 时用;或装了 FastCraft 且开了强制开关时用;或装了 FastCraft 1.25 + OptiFine 时用。
| 条目 | 目标模组条件 | 配置条件 |
|---|---|---|
STB_TEXTURE_STITCHING |
addExcludedMod(FASTCRAFT_ANY) |
Config.MIXIN_STBI_TEXTURE_STITCHING |
STB_TEXTURE_STITCHING_FORCE |
addRequiredMod(FASTCRAFT_ANY) |
MIXIN_STBI_TEXTURE_STITCHING && MIXIN_STBI_IGNORE_FASTCRAFT |
STB_TEXTURE_STITCHING_FOR_FASCRAFT |
addRequiredMod(FASTCRAFT_1_25) + addRequiredMod(OPTIFINE) |
MIXIN_STBI_TEXTURE_STITCHING && !MIXIN_STBI_IGNORE_FASTCRAFT |
Mixins.java:20-23 与 :65-80 处的 // spotless:off / // spotless:on 注释包裹整个枚举常量列表,说明该区段刻意排除格式化工具重排。
STB 拼接的危险性
Lwjgl3ifyCoremod.getMixins 中有一条专门的 error 级告警(Lwjgl3ifyCoremod.java:76-82):客户端下若 MIXIN_STBI_TEXTURE_STITCHING 为真但结果里没有 game.MixinStitcher,会打印"Disabled STB stitching mixins to prevent rapidly flashing screen",并建议移除 FastCraft 或升级到 FastCraft 1.25 再加 OptiFine。
这与配置项 stbiIgnoreFastcraft 的描述一致——该键的说明文字直接写明"Force-enable the STB mixins even if FastCraft is present, may lead to a rapidly flashing screen and other visual artifacts"(Config.java:98-102)。
配套实现位于 src/main/java/me/eigenraven/lwjgl3ify/textures/:StbStitcher.java、NativeBackedImage.java、FastByteChannel.java。
数值
| 数值 | 值 | 来源 |
|---|---|---|
| 相关条目数 | 4 | Mixins.java:20,65,70,75 |
| 唯一 mixin 类数 | 4 | 同上 |
目标 Stitcher 的条目数 |
3 | Mixins.java:67,72,77 均写 "game.MixinStitcher" |
FASTCRAFT_1_25 判定方式 |
在 fastcraft.a 字节码中查找连续 "fcVersion" + "1.25" 常量 |
TargetedMod.java:13-26 |
受 stbiTextureLoading 控制 |
是 | Mixins.java:23 |
受 stbiTextureStitching 控制 |
是(3 个条目全部) | Mixins.java:69,74,80 |
受 stbiIgnoreFastcraft 控制 |
1 个条目(_FORCE) |
Mixins.java:74 |
已知静默失败点
textures/NativeBackedImage.java:175-177 有一个字面空 catch:
int sizeGuess = 4096;
try {
sizeGuess = Math.max(4096, inputStream.available());
} catch (IOException ignored) {}
available() 抛 IOException 时静默保留 4096 的猜测值,不记日志也不抛出。后果是缓冲区尺寸可能偏小,表现为该纹理回退到猜测大小而非明确失败。
交互
| 触发 | 行为 |
|---|---|
| 加载贴图 | MixinTextureAtlasSprite 的 loadSprite 尾部改走 spng 解码 |
| 拼接图集 | MixinStitcher 用 stb_rectpack 替换原版算法 |
装了 FastCraft(任意版本)且未开 stbiIgnoreFastcraft |
MixinStitcher 不生效,回退原版拼接 |
| 装了 FastCraft 1.25 + OptiFine | MixinStitcher 生效 |
开了 stbiIgnoreFastcraft 但有 FastCraft |
MixinStitcher 强制生效,可能屏幕快速闪烁 |
相关条目
- lwjgl3ify.cfg 配置 - 三个
stbi*开关的定义与默认值 - Mixin 注册机制总览 - 条目与目标模组条件的匹配方式
- 第三方兼容钩子 -
TargetedMod枚举的完整定义