fix(rendering): add warnings for silent texture fallbacks

M2 particle/ribbon/batch, terrain layer, and WMO material texture
resolution paths were silently falling back to white textures when
indices were out of range — making missing texture issues hard to
diagnose. Add LOG_WARNING at each silent failure point with model
name, index details, and array sizes.
This commit is contained in:
Kelsi 2026-04-03 16:11:45 -07:00
parent 791ea1919e
commit 81a9970c91
3 changed files with 36 additions and 0 deletions

View file

@ -1238,6 +1238,10 @@ bool M2Renderer::loadModel(const pipeline::M2Model& model, uint32_t modelId) {
uint16_t texIdx = model.particleEmitters[ei].texture;
if (texIdx < allTextures.size() && allTextures[texIdx] != nullptr) {
gpuModel.particleTextures[ei] = allTextures[texIdx];
} else {
LOG_WARNING("M2 '", model.name, "' particle emitter[", ei,
"] texture index ", texIdx, " out of range (", allTextures.size(),
" textures) — using white fallback");
}
}
@ -1279,6 +1283,11 @@ bool M2Renderer::loadModel(const pipeline::M2Model& model, uint32_t modelId) {
? model.textureLookup[texLookupIdx] : UINT32_MAX;
if (texIdx < allTextures.size() && allTextures[texIdx] != nullptr) {
gpuModel.ribbonTextures[ri] = allTextures[texIdx];
} else {
LOG_WARNING("M2 '", model.name, "' ribbon emitter[", ri,
"] texLookup=", texLookupIdx, " resolved texIdx=", texIdx,
" out of range (", allTextures.size(),
" textures) — using white fallback");
}
// Allocate descriptor set (reuse particleTexLayout_ = single sampler)
if (particleTexLayout_ && materialDescPool_) {
@ -1348,6 +1357,9 @@ bool M2Renderer::loadModel(const pipeline::M2Model& model, uint32_t modelId) {
bgpu.texFlags = static_cast<uint8_t>(model.textures[texIdx].flags & 0x3);
}
} else if (!allTextures.empty()) {
LOG_WARNING("M2 '", model.name, "' batch textureIndex ", batch.textureIndex,
" out of range (textureLookup size=", model.textureLookup.size(),
") — falling back to texture[0]");
tex = allTextures[0];
texFailed = !textureLoadFailed.empty() && textureLoadFailed[0];
if (!textureKeysLower.empty()) {

View file

@ -344,6 +344,9 @@ bool TerrainRenderer::loadTerrain(const pipeline::TerrainMesh& mesh,
if (baseTexId < texturePaths.size()) {
gpuChunk.baseTexture = loadTexture(texturePaths[baseTexId]);
} else {
LOG_WARNING("Terrain[", tileX, ",", tileY, "] chunk[", x, ",", y,
"] base textureId ", baseTexId, " >= texturePaths size ",
texturePaths.size(), " — white fallback");
gpuChunk.baseTexture = whiteTexture.get();
}
@ -354,6 +357,11 @@ bool TerrainRenderer::loadTerrain(const pipeline::TerrainMesh& mesh,
VkTexture* layerTex = whiteTexture.get();
if (layer.textureId < texturePaths.size()) {
layerTex = loadTexture(texturePaths[layer.textureId]);
} else {
LOG_WARNING("Terrain[", tileX, ",", tileY, "] chunk[", x, ",", y,
"] layer[", i, "] textureId ", layer.textureId,
" >= texturePaths size ", texturePaths.size(),
" — white fallback");
}
gpuChunk.layerTextures[li] = layerTex;
@ -445,6 +453,9 @@ bool TerrainRenderer::loadTerrainIncremental(const pipeline::TerrainMesh& mesh,
if (baseTexId < texturePaths.size()) {
gpuChunk.baseTexture = loadTexture(texturePaths[baseTexId]);
} else {
LOG_WARNING("Terrain[", tileX, ",", tileY, "] chunk[", cx, ",", cy,
"] base textureId ", baseTexId, " >= texturePaths size ",
texturePaths.size(), " — white fallback");
gpuChunk.baseTexture = whiteTexture.get();
}
@ -455,6 +466,11 @@ bool TerrainRenderer::loadTerrainIncremental(const pipeline::TerrainMesh& mesh,
VkTexture* layerTex = whiteTexture.get();
if (layer.textureId < texturePaths.size()) {
layerTex = loadTexture(texturePaths[layer.textureId]);
} else {
LOG_WARNING("Terrain[", tileX, ",", tileY, "] chunk[", cx, ",", cy,
"] layer[", i, "] textureId ", layer.textureId,
" >= texturePaths size ", texturePaths.size(),
" — white fallback");
}
gpuChunk.layerTextures[li] = layerTex;

View file

@ -575,7 +575,15 @@ bool WMORenderer::loadModel(const pipeline::WMOModel& model, uint32_t id) {
tex = modelData.textures[texIndex];
hasTexture = (tex != nullptr && tex != whiteTexture_.get());
if (!tex) tex = whiteTexture_.get();
} else {
LOG_WARNING("WMO ", id, " batch materialId=", batch.materialId,
" texIndex=", texIndex, " >= textures size ",
modelData.textures.size(), " — white fallback");
}
} else {
LOG_WARNING("WMO ", id, " batch materialId=", batch.materialId,
" >= materialTextureIndices size ",
modelData.materialTextureIndices.size(), " — white fallback");
}
bool alphaTest = false;