纹理懒加载 + 缓存持久化
3 小时前综合
为什么第一次进入地图是"一片一片"加载的?
核心流程是这样的:
TerrainRegistry.lua 中的纹理加载采用了**懒加载(Lazy Loading)**模式:
渲染循环遍历可视范围内的每个瓦片
对每个瓦片调用 TerrainRegistry.GetTexture(id)
如果该地形纹理没有缓存,就调用 nvgCreateImage() 从磁盘加载图片
nvgCreateImage() 是同步阻塞的 —— 读文件、解码、上传 GPU
每帧能处理的瓦片数量有限,导致地图视觉上是逐片填充的
简单说:第一次进入时,每种地形纹理都要从磁盘读取,这个 I/O 过程分散在多帧完成。
为什么第二次进入是瞬间加载的?
关键在 TerrainRegistry.lua 中的缓存设计:
local texCache_ = {} -- 模块级变量,生命周期跟随整个程序
第一次加载后,所有纹理 handle 都存在 texCache_ 里
退回主菜单时,这个缓存没有被清除(因为 NVG 上下文没有改变)
第二次进入时,GetTexture() 直接命中缓存,返回已有的 GPU handle
零磁盘 I/O,整张地图在一帧内渲染完毕
缓存只在 NVG 上下文发生变化时才会清空(TerrainRegistry.lua 的 SetNVG() 函数),而从菜单返回游戏并不会改变 NVG 上下文。
一句话总结
情况 纹理来源 速度
第一次进入 磁盘 → 解码 → GPU(nvgCreateImage) 逐片加载
第二次进入 内存缓存(texCache_) 瞬间完成
这是一个典型的冷启动 vs 热启动问题。如果你希望第一次进入也能瞬间加载,可以在显示加载界面时预加载所有地形纹理,而不是等渲染时才懒加载。


