Skip to content

Character-select nameplate text (name / level / class) renders greyed-out instead of white — regression from FFP retirement (#544) #567

Description

@nolt

Character-select nameplate text (name / level / class) renders greyed-out instead of white — regression from FFP retirement (#544)

Summary

On the character selection screen, the info plate above each saved character (name, guild, class) used to render at full brightness (white name/guild, orange class). After the fixed-function-GL retirement (PR #544, commit 0702144c), the plate's text is dimmed/greyed-out. The frame box itself is fine; only the text is wrong. Reproducible on both the native Linux OpenGL build and the Wine build, because the cause is in platform-independent client rendering code.

This is the same regression wave as #549/#555 (BlendMesh fade), #556/#557 (tile resolution) — a rendering side effect of retiring fixed-function GL that wasn't caught. This specific one is still unfixed on current main.

Affected version

Where it renders

  • Plate: CCharInfoBalloon::Render()src/source/Character/CharInfoBalloon.cpp (frame box via CSprite::Render(), then name/guild/class via g_pRenderText->RenderText(...)).
  • Text path: RenderText → UploadText → RenderBitmap(BITMAP_FONT, ...) at src/source/UI/Legacy/UIControls.cpp:2830.
  • Glyph color is baked into the font atlas (white / orange), then modulated by the global g_CurrentColor inside RenderBitmap (src/source/Render/Textures/ZzzOpenglUtil.cpp).

Root cause

PR #544 broke an implicit invariant that had kept the plate text white. Two changes combine:

  1. src/source/Render/Sprites/Sprite.cppCSprite::Render() switched from real GL to the immediate renderer:

    -    ::glColor4ub(m_byRed, m_byGreen, m_byBlue, m_byAlpha);   // old: 255,255,255,255 → set GL current color WHITE
    +    IR::Color4ub(m_byRed, m_byGreen, m_byBlue, m_byAlpha);   // new: feeds IR only, leaves g_CurrentColor untouched

    The frame box used to set the GL current color to white immediately before the text draw, as a side effect.

  2. src/source/Render/Textures/ZzzOpenglUtil.cppRenderBitmap() (default param Alpha = 0.f; the BITMAP_FONT call passes no alpha, so it takes the else branch):

    float currColor[4] = { 1.f, 1.f, 1.f, 1.f };
    if (Alpha > 0.f) { currColor[0]=currColor[1]=currColor[2]=1.f; currColor[3]=Alpha; }
    else             { memcpy(currColor, g_CurrentColor, sizeof(currColor)); }   // reads the stale global color

CCharInfoBalloon::Render() never calls glColor itself, and BeginBitmap() does not reset the color. So the baked-white text atlas is now modulated by whatever value g_CurrentColor was left at by an earlier UI element (e.g. the dimmed-control greys, or a 1,1,1,0.3 dim-alpha draw). White atlas × grey modulator = greyed nameplate.

The balloon is uniquely hit because it was the one text site relying on the frame sprite's glColor to set white for it; ordinary UI text sites set their own glColor4f(1,1,1,1) first. Any other text site that inherited white purely from a preceding sprite has the same latent bug.

Suggested fix

Targeted (safe, restores exact pre-#544 behavior for this plate): in CCharInfoBalloon::Render(), right after CSprite::Render();:

CSprite::Render();
glColor4f(1.f, 1.f, 1.f, 1.f);   // restore the white current-color the frame's glColor4ub used to set, for the baked text atlas

Systemic (broader, but a design call): force white right before the baked-atlas glyph draw in UIControls.cpp (at the EnableAlphaTest(); on line 2829, before RenderBitmap(BITMAP_FONT, ...)):

EnableAlphaTest();
glColor4f(1.f, 1.f, 1.f, 1.f);
RenderBitmap(BITMAP_FONT, ...);

This fixes every text site that inherited white from a preceding sprite, but would override any text intentionally dimmed via a preceding glColor (text alpha would then have to be passed explicitly). The maintainer knows best whether any site relies on that; if not, the systemic fix is the cleaner root-cause fix.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions