mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 23:30:14 +00:00
Fix Stormwind bridge lamp glow: detect glow textures by pixel content,
force additive blending for colorKeyBlack batches Two key changes: 1. Detect glow-like textures by analyzing pixel content during loading: textures that are >60% near-black with some bright pixels are flagged as colorKeyBlack regardless of filename. This catches glow textures like Stormwind street lamps whose paths don't contain keywords like "lamp" or "lantern". 2. Force additive blending (mode 3) for batches with colorKeyBlack textures that have blendMode 1 or 2. These textures are designed for additive blending where black = transparent, but some M2 files specify Alpha or AlphaKey blend modes which cause black areas to render as solid dark disks instead of being invisible.
This commit is contained in:
parent
32cc13d1b2
commit
b2d43f702f
1 changed files with 32 additions and 12 deletions
|
|
@ -2064,9 +2064,15 @@ void M2Renderer::render(const Camera& camera, const glm::mat4& view, const glm::
|
|||
|
||||
// Apply per-batch blend mode from M2 material (only if changed)
|
||||
// 0=Opaque, 1=AlphaKey, 2=Alpha, 3=Add, 4=Mod, 5=Mod2x, 6=BlendAdd, 7=Screen
|
||||
// Glow textures (colorKeyBlack) are designed for additive blending;
|
||||
// override non-additive modes to prevent black backgrounds.
|
||||
uint16_t effectiveBlend = batch.blendMode;
|
||||
if (batch.colorKeyBlack && effectiveBlend >= 1 && effectiveBlend <= 2) {
|
||||
effectiveBlend = 3; // Force additive for glow textures
|
||||
}
|
||||
bool batchTransparent = false;
|
||||
if (batch.blendMode != lastBlendMode) {
|
||||
switch (batch.blendMode) {
|
||||
if (effectiveBlend != lastBlendMode) {
|
||||
switch (effectiveBlend) {
|
||||
case 0: // Opaque
|
||||
glBlendFunc(GL_ONE, GL_ZERO);
|
||||
break;
|
||||
|
|
@ -2097,11 +2103,11 @@ void M2Renderer::render(const Camera& camera, const glm::mat4& view, const glm::
|
|||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
break;
|
||||
}
|
||||
lastBlendMode = batch.blendMode;
|
||||
shader->setUniform("uBlendMode", static_cast<int>(batch.blendMode));
|
||||
lastBlendMode = effectiveBlend;
|
||||
shader->setUniform("uBlendMode", static_cast<int>(effectiveBlend));
|
||||
} else {
|
||||
// Still need to know if batch is transparent for depth mask logic
|
||||
batchTransparent = (batch.blendMode >= 2);
|
||||
batchTransparent = (effectiveBlend >= 2);
|
||||
}
|
||||
|
||||
// Disable depth writes for transparent/additive batches
|
||||
|
|
@ -2940,12 +2946,26 @@ GLuint M2Renderer::loadTexture(const std::string& path, uint32_t texFlags) {
|
|||
|
||||
// Track whether the texture actually uses alpha (any pixel with alpha < 255).
|
||||
bool hasAlpha = false;
|
||||
for (size_t i = 3; i < blp.data.size(); i += 4) {
|
||||
if (blp.data[i] != 255) {
|
||||
hasAlpha = true;
|
||||
break;
|
||||
}
|
||||
// Detect glow-like textures by pixel content: mostly dark with some bright pixels.
|
||||
// These are flame/glow cards where black = transparent (designed for additive blend).
|
||||
uint32_t totalPixels = 0;
|
||||
uint32_t darkPixels = 0;
|
||||
uint32_t brightPixels = 0;
|
||||
for (size_t i = 0; i + 3 < blp.data.size(); i += 4) {
|
||||
uint8_t r = blp.data[i], g = blp.data[i+1], b = blp.data[i+2];
|
||||
if (blp.data[i+3] != 255) hasAlpha = true;
|
||||
uint8_t mx = std::max({r, g, b});
|
||||
totalPixels++;
|
||||
if (mx < 26) darkPixels++; // near-black (<~0.1)
|
||||
else if (mx > 180) brightPixels++; // bright (>~0.7)
|
||||
}
|
||||
bool glowByContent = false;
|
||||
if (totalPixels > 0) {
|
||||
float darkRatio = static_cast<float>(darkPixels) / totalPixels;
|
||||
// Glow texture: >60% dark pixels with some bright pixels present
|
||||
glowByContent = (darkRatio > 0.60f && brightPixels > 0);
|
||||
}
|
||||
bool colorKeyBlack = colorKeyBlackHint || glowByContent;
|
||||
|
||||
GLuint textureID;
|
||||
glGenTextures(1, &textureID);
|
||||
|
|
@ -2970,12 +2990,12 @@ GLuint M2Renderer::loadTexture(const std::string& path, uint32_t texFlags) {
|
|||
size_t base = static_cast<size_t>(blp.width) * static_cast<size_t>(blp.height) * 4ull;
|
||||
e.approxBytes = base + (base / 3);
|
||||
e.hasAlpha = hasAlpha;
|
||||
e.colorKeyBlack = colorKeyBlackHint;
|
||||
e.colorKeyBlack = colorKeyBlack;
|
||||
e.lastUse = ++textureCacheCounter_;
|
||||
textureCacheBytes_ += e.approxBytes;
|
||||
textureCache[key] = e;
|
||||
textureHasAlphaById_[textureID] = hasAlpha;
|
||||
textureColorKeyBlackById_[textureID] = colorKeyBlackHint;
|
||||
textureColorKeyBlackById_[textureID] = colorKeyBlack;
|
||||
LOG_DEBUG("M2: Loaded texture: ", path, " (", blp.width, "x", blp.height, ")");
|
||||
|
||||
return textureID;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue