显示 “正在加载地形纹理… ” 和进度条

3 小时前综合
继续诊断 loading 界面被跳过的问题。根据之前的分析,最可能的原因是 nvgCreateImage() 立即返回有效 handle,导致 PreloadAll() 在第一帧就返回 (15, 15),loading 界面只显示了 1 帧就被替换。
让我先验证这个假设,读取当前代码。
现在我确认了问题。PreloadOne 和 GetTexture 都只检查 handle > 0,但 nvgCreateImage 在本地文件情况下会立即返回有效 handle,而纹理数据的 GPU 上传是异步的。这导致 PreloadAll() 在第一帧就返回 (15, 15),loading 界面瞬间完成。
关键证据:nvgImageSize 返回 w or 0, h or 0 — 如果纹理数据还没就绪,nvgImageSize 可能返回 (0, 0)。但代码把 w=0, h=0 的条目也缓存为"成功"了。
让我验证一下 nvgImageSize 在纹理未就绪时的行为,同时检查 MapCanvas 中的 safety-net 预加载是否提前加载了纹理。
发现了另一个问题:MapCanvas 的 Render 方法里还有一个 safety-net PreloadAll() 调用。但这不是当前的主因——主因是 PreloadOne 把 w=0,h=0 的纹理也当成"已缓存"。
现在实施修复方案。核心思路:
修改 PreloadOne:要求 handle > 0 且 w > 0 AND h > 0 才算成功。如果 handle 有效但尺寸为 0,删除 handle 不缓存,下一帧重试。
修改 GetTexture:同样要求缓存条目的 w > 0。
在 preloadState_ 中添加 frameCount:确保 loading 界面至少显示几帧。
Bot Avatar
根因确认:PreloadOne 中 nvgCreateImage 返回有效 handle 后,即使 nvgImageSize 返回 (0, 0)(纹理数据未就绪),也被缓存为"成功"。这导致第一帧 PreloadAll 返回 (15, 15),loading 界面瞬间跳过。
修复 TerrainRegistry.lua — 要求纹理 handle 和尺寸都有效才算加载成功
构建成功。这次修复做了三个关键改动:
根因:nvgCreateImage() 在本地文件时立即返回有效 handle(>0),但纹理数据的 GPU 上传是异步的。之前的代码只检查 handle > 0 就认为纹理"已就绪",导致 PreloadAll() 第一帧就返回 (15, 15),loading 界面瞬间跳过。
修复内容:
TerrainRegistry.PreloadOne — 现在要求 handle > 0 且 nvgImageSize 返回 w > 0, h > 0 才算就绪。handle 有效但尺寸为 0 的纹理会被缓存(避免重复创建 handle),但每帧重新查询尺寸直到 GPU 上传完成。
beginPreloading 添加 InvalidateCache() — 进入 loading 前清空旧缓存,强制所有纹理走完整的"创建 handle → 等待尺寸就绪"流程。
HandleUpdate 添加最低帧数保护 — frameCount >= 2 确保 loading 界面至少可见 2 帧,即使纹理秒就绪也能让用户看到进度条。同时添加了每帧 debug 日志 [Preload] frame=N cached=X/Y,方便观察实际的加载进度。
请进入玩家入口测试,观察是否能看到 loading 进度条从 0/15 逐步更新到 15/15。日志中的 [Preload] 信息也可以帮助诊断。
Loading 界面出现了但进度还是太快跳过。这说明 nvgImageSize 也是立即返回有效尺寸的——文件头信息是同步读取的,但 GPU 纹理上传是后台进行的。
需要换策略:每帧只加载一个纹理,让进度自然分布在多帧上。
Bot Avatar
在 TerrainRegistry 中添加 PreloadStep() — 每次调用只创建一个新 handle,避免一帧内全部加载完
这次的核心改动:
新策略:每帧只创建一个纹理 handle
之前 PreloadAll 在一帧内对 15 个纹理全部调用 nvgCreateImage,导致所有 handle 瞬间创建完毕,loading 界面 1-2 帧就跳过。
新增的 PreloadStep() 函数:
每次调用最多创建 一个 新的 nvgCreateImage handle
已有 handle 的纹理只做轻量的尺寸复查(几乎零开销)
15 个纹理 → 至少需要 15 帧才能全部创建完毕
在 60fps 下约 0.25 秒,进度条会从 1/15 → 2/15 → … → 15/15 逐步更新
1