SmartRender 兼容(SmartRender Compat)
基本信息
| 属性 | 值 |
|---|---|
| 类型 | 客户端反射兼容性垫片 |
| 实现类 | roadhog360.simpleskinbackport.core.compat.SmartRenderCompat |
| 反射目标 | net.smart.render.ModelRotationRenderer.UpdateLocals() |
| 适用端 | 客户端 |
| 启用条件 | Loader.isModLoaded("SmartRender") + tryInitSmartRenderFields 成功 |
功能
SmartRender (makamys 分支的 Smart Moving 渲染器扩展) 会复制 ModelRenderer 字段的本地缓存。当本 mod 的 MixinModelBiped 重建 displayList 时,必须通知 SmartRender 同步更新它的内部缓存,否则 GL 状态错乱。
初始化流程
ClientProxy.preInit 调用 SmartRenderCompat.tryInitSmartRenderFields():
public static boolean tryInitSmartRenderFields() {
if (Loader.isModLoaded("SmartRender")) {
try {
modelRotationRendererSmartRendererClass = Class.forName("net.smart.render.ModelRotationRenderer");
updateLocalsFunc = modelRotationRendererSmartRendererClass.getDeclaredMethod("UpdateLocals");
updateLocalsFunc.setAccessible(true);
return true;
} catch (ClassNotFoundException | NoSuchMethodException e) {
SimpleSkinBackport.LOG.warn("Smart Render compatibility handler failed. Prepare for rendering errors.");
e.printStackTrace();
return false;
}
}
return false;
}
含义:仅在 SmartRender 已安装时通过反射拿到 UpdateLocals Method 句柄。失败时(异常或未安装)updateLocalsFunc == null,smartMovingCompatEnabled() 返回 false,整个同步块失效。
调用流程
Utils.createDisplaylistFor(ModelRenderer renderer) 中:
public static int createDisplaylistFor(ModelRenderer renderer) {
renderer.displayList = 0; // OptiFine for some reason checks if the display list is 0 and things get fucky
// if it isn't
renderer.compileDisplayList(0.0625F);
SmartRenderCompat.updateSmartRenderFields(renderer); // 通知 SmartRender
return renderer.displayList;
}
updateSmartRenderFields 实现:
public static void updateSmartRenderFields(ModelRenderer... renderers) {
if (smartMovingCompatEnabled()) {
for (ModelRenderer renderer : renderers) {
invokeUpdate(renderer);
}
}
}
private static void invokeUpdate(ModelRenderer renderer) {
if (modelRotationRendererSmartRendererClass.isAssignableFrom(renderer.getClass())) {
try {
updateLocalsFunc.invoke(renderer);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
}
}
}
只在 renderer 实际是 ModelRotationRenderer 子类时才调用 —— 即仅当 SmartRender 包装了它。
调用入口
SmartRenderCompat.updateSmartRenderFields 在以下场景被调用:
| 入口 | 位置 |
|---|---|
Utils.createDisplaylistFor |
ArmPair.of(...) 中 |
MixinModelBiped.ssb$setSlim |
SmartRenderCompat.updateSmartRenderFields(bipedLeftArm, bipedRightArm) |
数值
| 数值 | 值 | 来源 |
|---|---|---|
| 反射类全限定名 | net.smart.render.ModelRotationRenderer |
Class.forName(...) |
| 反射方法 | UpdateLocals(无参) |
getDeclaredMethod("UpdateLocals") |
displayList 重置值 |
0 | renderer.displayList = 0 |
compileDisplayList scale |
0.0625F(Minecraft 默认) |
compileDisplayList(0.0625F) |
| 同步是否启用 | updateLocalsFunc != null |
smartMovingCompatEnabled() |
关联机制
| 步骤 | 位置 |
|---|---|
| 1. preInit 反射初始化 | ClientProxy.preInit → SmartRenderCompat.tryInitSmartRenderFields |
| 2. Mixin 重建 arm 时调用 | MixinModelBiped.ssb$setSlim |
| 3. ArMixine.of(…) 创建 | Utils.createDisplaylistFor(left) + Utils.createDisplaylistFor(right) |
| 4. SmartRender 内部缓存同步 | updateLocalsFunc.invoke(renderer) |
第三方 mod 集成
- SmartRender (makamys)(可选):反射调用
ModelRotationRenderer.UpdateLocals。源码注释明确建议用 makamys 维护的构建,原版 Smart Moving 未做适配。
相关条目
- 1.8 皮肤模型系统 -
ssb$setSlim调用 SmartRender - Twilight Forest 巨人兼容 - ArMixine 重建链路