Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/renderer/Image.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,11 @@ class idImage {
textureUsage_t GetUsage() const { return usage; }
bool IsDefaulted() const { return defaulted; }
bool IsScratchImage() const { return scratchImage; }
bool IsFontAtlas() const {
return idStr::Icmpn( imgName, "_ttfatlas", 9 ) == 0 ||
idStr::Icmpn( imgName, "_ttfconsole", 11 ) == 0 ||
idStr::Icmp( imgName, "_consoleFont" ) == 0;
}

void SetReferencedOutsideLevelLoad() { referencedOutsideLevelLoad = true; }
void SetReferencedInsideLevelLoad() { levelLoadReferenced = true; }
Expand Down
6 changes: 5 additions & 1 deletion src/renderer/ImageManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -997,7 +997,11 @@ void idImageManager::ReloadImages( bool all ) {
R_SetDDSProbeCacheActive( false );

for ( int i = 0 ; i < globalImages->images.Num() ; i++ ) {
globalImages->images[ i ]->Reload( all );
idImage *image = globalImages->images[ i ];
if ( image == NULL || image->IsFontAtlas() ) {
continue;
}
image->Reload( all );
}
}

Expand Down
8 changes: 8 additions & 0 deletions src/renderer/Image_load.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1750,6 +1750,14 @@ void idImage::Reload( bool force ) {
return;
}

// Procedural font atlases are CPU-generated FreeType pages rather than
// disk files or render targets. Never purge or reallocate them with NULL
// data during texture reload, or UI text will be destroyed when texture
// reduction/quality cvars change.
if ( IsFontAtlas() ) {
return;
}

// persistent images are runtime render targets, not file-backed
if ( opts.isPersistant ) {
common->DPrintf( "reallocating persistent %s.\n", GetName() );
Expand Down
22 changes: 14 additions & 8 deletions src/renderer/OpenGL/gl_ContextSDL3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,17 @@ static void SDL3_WindowParmsFromGlimpParms(const glimpParms_t &src, renderWindow
dst.multiSamples = src.multiSamples;
}

static void SDL3_SyncGLConfigWindowDimensions( const renderModuleWindowInfo_t &windowInfo ) {
if ( windowInfo.pixelWidth > 0 && windowInfo.pixelHeight > 0 ) {
glConfig.vidWidth = windowInfo.pixelWidth;
glConfig.vidHeight = windowInfo.pixelHeight;
}
glConfig.uiViewportX = windowInfo.uiViewportX;
glConfig.uiViewportY = windowInfo.uiViewportY;
glConfig.uiViewportWidth = windowInfo.uiViewportWidth;
glConfig.uiViewportHeight = windowInfo.uiViewportHeight;
}

static bool SDL3_EnsureGLContextCurrent(const char *operation) {
if (!s_glWindow || !s_glContext) {
return false;
Expand Down Expand Up @@ -487,6 +498,7 @@ bool GLimp_Init(glimpParms_t parms) {

s_glWindowServices->RefreshNativeWindowHandles(&windowInfo);
s_glHDC = windowInfo.nativeDisplayHandle;
SDL3_SyncGLConfigWindowDimensions(windowInfo);
SDL3_LoadWGLExtensions();
if (r_swapInterval.IsModified()) {
r_swapInterval.ClearModified();
Expand Down Expand Up @@ -523,6 +535,7 @@ bool GLimp_SetScreenParms(glimpParms_t parms) {
renderModuleWindowInfo_t windowInfo;
windowServices->RefreshNativeWindowHandles(&windowInfo);
s_glHDC = windowInfo.nativeDisplayHandle;
SDL3_SyncGLConfigWindowDimensions(windowInfo);
r_swapInterval.SetModified();
if (r_swapInterval.IsModified()) {
r_swapInterval.ClearModified();
Expand Down Expand Up @@ -572,14 +585,7 @@ void GLimp_SwapBuffers(void) {
if (s_glWindow && s_glWindowServices != NULL && s_glWindowServices->RefreshNativeWindowHandles != NULL) {
renderModuleWindowInfo_t windowInfo;
s_glWindowServices->RefreshNativeWindowHandles(&windowInfo);
if (windowInfo.pixelWidth > 0 && windowInfo.pixelHeight > 0) {
glConfig.vidWidth = windowInfo.pixelWidth;
glConfig.vidHeight = windowInfo.pixelHeight;
}
glConfig.uiViewportX = windowInfo.uiViewportX;
glConfig.uiViewportY = windowInfo.uiViewportY;
glConfig.uiViewportWidth = windowInfo.uiViewportWidth;
glConfig.uiViewportHeight = windowInfo.uiViewportHeight;
SDL3_SyncGLConfigWindowDimensions(windowInfo);
}

if (SDL3_EnsureGLContextCurrent("swap buffers") && !s_glWindowServices->SwapGLWindow()) {
Expand Down
1 change: 1 addition & 0 deletions src/renderer/RenderSystem_init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4944,6 +4944,7 @@ static void R_PerformFullVidRestart( bool forceWindow ) {

R_InitFreeType();
R_RefreshConsoleFontAtlas();
R_TTFRestoreAtlasMaterials();
}

static GLenum R_ClearPendingGLErrors( void ) {
Expand Down
21 changes: 20 additions & 1 deletion src/renderer/tr_fontTTF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1213,6 +1213,24 @@ bool R_RegisterTrueTypeFont( const char *fontName, fontInfoEx_t &font ) {
}

if ( built != 3 ) {
if ( built > 0 ) {
if ( font.fontInfoSmall.pointSize <= 0.0f && font.fontInfoMedium.pointSize > 0.0f ) {
font.fontInfoSmall = font.fontInfoMedium;
font.maxWidthSmall = font.maxWidthMedium;
font.maxHeightSmall = font.maxHeightMedium;
}
if ( font.fontInfoLarge.pointSize <= 0.0f && font.fontInfoMedium.pointSize > 0.0f ) {
font.fontInfoLarge = font.fontInfoMedium;
font.maxWidthLarge = font.maxWidthMedium;
font.maxHeightLarge = font.maxHeightMedium;
} else if ( font.fontInfoLarge.pointSize <= 0.0f && font.fontInfoSmall.pointSize > 0.0f ) {
font.fontInfoLarge = font.fontInfoSmall;
font.maxWidthLarge = font.maxWidthSmall;
font.maxHeightLarge = font.maxHeightSmall;
}
common->Warning( "TTF font: '%s' only produced %i of 3 sizes; propagated missing sizes", fontName, built );
return true;
}
common->Warning( "TTF font: '%s' only produced %i of 3 sizes; using the bitmap font", fontName, built );
return false;
}
Expand Down Expand Up @@ -1400,7 +1418,8 @@ void R_ShutdownTrueTypeFonts( void ) {
}
ttfConsoleMaterial = NULL;
ttfConsoleOriginalImage = NULL;
ttfAtlasMaterials.DeleteContents( true );
// Procedural atlas definitions persist across context recreate so they can be reasserted.
// ttfAtlasMaterials.DeleteContents( true );
// Nothing may still be drawing by this point: every fontInfo_t that shares a
// page set is dead with the renderer, and idDeviceContext re-registers its
// fonts from scratch after a restart.
Expand Down
30 changes: 28 additions & 2 deletions src/ui/DeviceContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1218,7 +1218,7 @@ bool idDeviceContext::ReloadFonts() {
} else if ( useFontSlot == 2 ) {
useFont = &activeFont->fontInfoLarge;
} else {
useFont = NULL;
useFont = ( activeFont != NULL ) ? &activeFont->fontInfoSmall : NULL;
}

return allFontsReloaded;
Expand All @@ -1245,6 +1245,7 @@ void idDeviceContext::EnsureFontsCurrent() {
fontsCodePageGeneration = currentCodePageGeneration;
if ( !ReloadFonts() ) {
common->Warning( "could not rebuild every GUI font" );
fontsVideoRestartCount = -1;
}
}

Expand All @@ -1253,13 +1254,17 @@ void idDeviceContext::SetFont( int num ) {

if ( fonts.Num() == 0 ) {
activeFont = NULL;
useFont = NULL;
return;
}
if ( num >= 0 && num < fonts.Num() ) {
activeFont = &fonts[num];
} else {
activeFont = &fonts[0];
}
if ( activeFont != NULL && ( useFont == NULL || ( useFont != &activeFont->fontInfoSmall && useFont != &activeFont->fontInfoMedium && useFont != &activeFont->fontInfoLarge ) ) ) {
useFont = &activeFont->fontInfoSmall;
}
}

void idDeviceContext::SizeIcon( embeddedIcon_t &icon ) {
Expand Down Expand Up @@ -2285,6 +2290,17 @@ int idDeviceContext::DrawText(float x, float y, float scale, idVec4 color, const
scaledFont.renderScale = openQ4_FontRenderScale( useFont, scale );
scaledFont.maxWidth = activeFont != NULL ? activeFont->maxWidth : 0.0f;
scaledFont.maxHeight = activeFont != NULL ? activeFont->maxHeight : 0.0f;
if ( !openQ4_HasRenderableFont( scaledFont ) && activeFont != NULL ) {
if ( activeFont->fontInfoSmall.pointSize > 0.0f ) {
useFont = &activeFont->fontInfoSmall;
} else if ( activeFont->fontInfoMedium.pointSize > 0.0f ) {
useFont = &activeFont->fontInfoMedium;
} else if ( activeFont->fontInfoLarge.pointSize > 0.0f ) {
useFont = &activeFont->fontInfoLarge;
}
scaledFont.font = useFont;
scaledFont.renderScale = openQ4_FontRenderScale( useFont, scale );
}

if ( !openQ4_HasRenderableFont( scaledFont ) || text == NULL || color.w == 0.0f ) {
return 0;
Expand Down Expand Up @@ -2904,7 +2920,17 @@ int idDeviceContext::DrawText( const char *text, float textScale, int textAlign,
const int visibleCellCount = charSkip > 0.0f ? idMath::FtoiFast( rectDraw.w / charSkip ) : 0;

SetFontByScale( textScale );
const float useScale = openQ4_FontRenderScale( useFont, textScale );
float useScale = openQ4_FontRenderScale( useFont, textScale );
if ( ( useFont == NULL || useScale == 0.0f ) && activeFont != NULL ) {
if ( activeFont->fontInfoSmall.pointSize > 0.0f ) {
useFont = &activeFont->fontInfoSmall;
} else if ( activeFont->fontInfoMedium.pointSize > 0.0f ) {
useFont = &activeFont->fontInfoMedium;
} else if ( activeFont->fontInfoLarge.pointSize > 0.0f ) {
useFont = &activeFont->fontInfoLarge;
}
useScale = openQ4_FontRenderScale( useFont, textScale );
}
if ( useFont == NULL || useScale == 0.0f ) {
return visibleCellCount;
}
Expand Down