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.cpp — CSprite::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.cpp — RenderBitmap() (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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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