ADDED: `isGpuReady` flag, allow font loading with no GPU acceleration

This commit is contained in:
Ray 2024-08-24 18:59:24 +02:00
parent 78e86b6ea5
commit 4c9282b090
2 changed files with 46 additions and 34 deletions

View File

@ -360,10 +360,15 @@ typedef struct CoreData {
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
RLAPI const char *raylib_version = RAYLIB_VERSION; // raylib version exported symbol, required for some bindings RLAPI const char *raylib_version = RAYLIB_VERSION; // raylib version exported symbol, required for some bindings
CoreData CORE = { 0 }; // Global CORE state context CoreData CORE = { 0 }; // Global CORE state context
// Flag to note GPU acceleration is available,
// referenced from other modules to support GPU data loading
// NOTE: Useful to allow Texture, RenderTexture, Font.texture, Mesh.vaoId/vboId, Shader loading
bool isGpuReady = false;
#if defined(SUPPORT_SCREEN_CAPTURE) #if defined(SUPPORT_SCREEN_CAPTURE)
static int screenshotCounter = 0; // Screenshots counter static int screenshotCounter = 0; // Screenshots counter
#endif #endif
#if defined(SUPPORT_GIF_RECORDING) #if defined(SUPPORT_GIF_RECORDING)
@ -637,28 +642,31 @@ void InitWindow(int width, int height, const char *title)
// Initialize rlgl default data (buffers and shaders) // Initialize rlgl default data (buffers and shaders)
// NOTE: CORE.Window.currentFbo.width and CORE.Window.currentFbo.height not used, just stored as globals in rlgl // NOTE: CORE.Window.currentFbo.width and CORE.Window.currentFbo.height not used, just stored as globals in rlgl
rlglInit(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height); rlglInit(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
isGpuReady = true; // Flag to note GPU has been initialized successfully
// Setup default viewport // Setup default viewport
SetupViewport(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height); SetupViewport(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT) #if defined(SUPPORT_MODULE_RTEXT)
// Load default font #if defined(SUPPORT_DEFAULT_FONT)
// WARNING: External function: Module required: rtext // Load default font
LoadFontDefault(); // WARNING: External function: Module required: rtext
#if defined(SUPPORT_MODULE_RSHAPES) LoadFontDefault();
// Set font white rectangle for shapes drawing, so shapes and text can be batched together #if defined(SUPPORT_MODULE_RSHAPES)
// WARNING: rshapes module is required, if not available, default internal white rectangle is used // Set font white rectangle for shapes drawing, so shapes and text can be batched together
Rectangle rec = GetFontDefault().recs[95]; // WARNING: rshapes module is required, if not available, default internal white rectangle is used
if (CORE.Window.flags & FLAG_MSAA_4X_HINT) Rectangle rec = GetFontDefault().recs[95];
{ if (CORE.Window.flags & FLAG_MSAA_4X_HINT)
// NOTE: We try to maxime rec padding to avoid pixel bleeding on MSAA filtering {
SetShapesTexture(GetFontDefault().texture, (Rectangle){ rec.x + 2, rec.y + 2, 1, 1 }); // NOTE: We try to maxime rec padding to avoid pixel bleeding on MSAA filtering
} SetShapesTexture(GetFontDefault().texture, (Rectangle){ rec.x + 2, rec.y + 2, 1, 1 });
else }
{ else
// NOTE: We set up a 1px padding on char rectangle to avoid pixel bleeding {
SetShapesTexture(GetFontDefault().texture, (Rectangle){ rec.x + 1, rec.y + 1, rec.width - 2, rec.height - 2 }); // NOTE: We set up a 1px padding on char rectangle to avoid pixel bleeding
} SetShapesTexture(GetFontDefault().texture, (Rectangle){ rec.x + 1, rec.y + 1, rec.width - 2, rec.height - 2 });
}
#endif
#endif #endif
#else #else
#if defined(SUPPORT_MODULE_RSHAPES) #if defined(SUPPORT_MODULE_RSHAPES)

View File

@ -124,6 +124,7 @@
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Global variables // Global variables
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
extern bool isGpuReady;
#if defined(SUPPORT_DEFAULT_FONT) #if defined(SUPPORT_DEFAULT_FONT)
// Default font provided by raylib // Default font provided by raylib
// NOTE: Default font is loaded on InitWindow() and disposed on CloseWindow() [module: core] // NOTE: Default font is loaded on InitWindow() and disposed on CloseWindow() [module: core]
@ -252,7 +253,7 @@ extern void LoadFontDefault(void)
counter++; counter++;
} }
defaultFont.texture = LoadTextureFromImage(imFont); if (isGpuReady) defaultFont.texture = LoadTextureFromImage(imFont);
// Reconstruct charSet using charsWidth[], charsHeight, charsDivisor, glyphCount // Reconstruct charSet using charsWidth[], charsHeight, charsDivisor, glyphCount
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -308,7 +309,7 @@ extern void LoadFontDefault(void)
extern void UnloadFontDefault(void) extern void UnloadFontDefault(void)
{ {
for (int i = 0; i < defaultFont.glyphCount; i++) UnloadImage(defaultFont.glyphs[i].image); for (int i = 0; i < defaultFont.glyphCount; i++) UnloadImage(defaultFont.glyphs[i].image);
UnloadTexture(defaultFont.texture); if (isGpuReady) UnloadTexture(defaultFont.texture);
RL_FREE(defaultFont.glyphs); RL_FREE(defaultFont.glyphs);
RL_FREE(defaultFont.recs); RL_FREE(defaultFont.recs);
} }
@ -362,11 +363,14 @@ Font LoadFont(const char *fileName)
UnloadImage(image); UnloadImage(image);
} }
if (font.texture.id == 0) TRACELOG(LOG_WARNING, "FONT: [%s] Failed to load font texture -> Using default font", fileName); if (isGpuReady)
else
{ {
SetTextureFilter(font.texture, TEXTURE_FILTER_POINT); // By default, we set point filter (the best performance) if (font.texture.id == 0) TRACELOG(LOG_WARNING, "FONT: [%s] Failed to load font texture -> Using default font", fileName);
TRACELOG(LOG_INFO, "FONT: Data loaded successfully (%i pixel size | %i glyphs)", FONT_TTF_DEFAULT_SIZE, FONT_TTF_DEFAULT_NUMCHARS); else
{
SetTextureFilter(font.texture, TEXTURE_FILTER_POINT); // By default, we set point filter (the best performance)
TRACELOG(LOG_INFO, "FONT: Data loaded successfully (%i pixel size | %i glyphs)", FONT_TTF_DEFAULT_SIZE, FONT_TTF_DEFAULT_NUMCHARS);
}
} }
return font; return font;
@ -487,7 +491,7 @@ Font LoadFontFromImage(Image image, Color key, int firstChar)
}; };
// Set font with all data parsed from image // Set font with all data parsed from image
font.texture = LoadTextureFromImage(fontClear); // Convert processed image to OpenGL texture if (isGpuReady) font.texture = LoadTextureFromImage(fontClear); // Convert processed image to OpenGL texture
font.glyphCount = index; font.glyphCount = index;
font.glyphPadding = 0; font.glyphPadding = 0;
@ -556,7 +560,7 @@ Font LoadFontFromMemory(const char *fileType, const unsigned char *fileData, int
font.glyphPadding = FONT_TTF_DEFAULT_CHARS_PADDING; font.glyphPadding = FONT_TTF_DEFAULT_CHARS_PADDING;
Image atlas = GenImageFontAtlas(font.glyphs, &font.recs, font.glyphCount, font.baseSize, font.glyphPadding, 0); Image atlas = GenImageFontAtlas(font.glyphs, &font.recs, font.glyphCount, font.baseSize, font.glyphPadding, 0);
font.texture = LoadTextureFromImage(atlas); if (isGpuReady) font.texture = LoadTextureFromImage(atlas);
// Update glyphs[i].image to use alpha, required to be used on ImageDrawText() // Update glyphs[i].image to use alpha, required to be used on ImageDrawText()
for (int i = 0; i < font.glyphCount; i++) for (int i = 0; i < font.glyphCount; i++)
@ -580,7 +584,7 @@ Font LoadFontFromMemory(const char *fileType, const unsigned char *fileData, int
// Check if a font is ready // Check if a font is ready
bool IsFontReady(Font font) bool IsFontReady(Font font)
{ {
return ((font.texture.id > 0) && // Validate OpenGL id fot font texture atlas return ((font.texture.id > 0) && // Validate OpenGL id for font texture atlas
(font.baseSize > 0) && // Validate font size (font.baseSize > 0) && // Validate font size
(font.glyphCount > 0) && // Validate font contains some glyph (font.glyphCount > 0) && // Validate font contains some glyph
(font.recs != NULL) && // Validate font recs defining glyphs on texture atlas (font.recs != NULL) && // Validate font recs defining glyphs on texture atlas
@ -946,7 +950,7 @@ void UnloadFont(Font font)
if (font.texture.id != GetFontDefault().texture.id) if (font.texture.id != GetFontDefault().texture.id)
{ {
UnloadFontData(font.glyphs, font.glyphCount); UnloadFontData(font.glyphs, font.glyphCount);
UnloadTexture(font.texture); if (isGpuReady) UnloadTexture(font.texture);
RL_FREE(font.recs); RL_FREE(font.recs);
TRACELOGD("FONT: Unloaded font data from RAM and VRAM"); TRACELOGD("FONT: Unloaded font data from RAM and VRAM");
@ -1066,7 +1070,7 @@ bool ExportFontAsCode(Font font, const char *fileName)
byteCount += sprintf(txtData + byteCount, " Image imFont = { fontImageData_%s, %i, %i, 1, %i };\n\n", styleName, image.width, image.height, image.format); byteCount += sprintf(txtData + byteCount, " Image imFont = { fontImageData_%s, %i, %i, 1, %i };\n\n", styleName, image.width, image.height, image.format);
#endif #endif
byteCount += sprintf(txtData + byteCount, " // Load texture from image\n"); byteCount += sprintf(txtData + byteCount, " // Load texture from image\n");
byteCount += sprintf(txtData + byteCount, " font.texture = LoadTextureFromImage(imFont);\n"); byteCount += sprintf(txtData + byteCount, " if (isGpuReady) font.texture = LoadTextureFromImage(imFont);\n");
#if defined(SUPPORT_COMPRESSED_FONT_ATLAS) #if defined(SUPPORT_COMPRESSED_FONT_ATLAS)
byteCount += sprintf(txtData + byteCount, " UnloadImage(imFont); // Uncompressed data can be unloaded from memory\n\n"); byteCount += sprintf(txtData + byteCount, " UnloadImage(imFont); // Uncompressed data can be unloaded from memory\n\n");
#endif #endif
@ -1277,7 +1281,7 @@ Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing
{ {
Vector2 textSize = { 0 }; Vector2 textSize = { 0 };
if ((font.texture.id == 0) || (text == NULL)) return textSize; // Security check if ((isGpuReady && (font.texture.id == 0)) || (text == NULL)) return textSize; // Security check
int size = TextLength(text); // Get size in bytes of text int size = TextLength(text); // Get size in bytes of text
int tempByteCounter = 0; // Used to count longer text line num chars int tempByteCounter = 0; // Used to count longer text line num chars
@ -2257,7 +2261,7 @@ static Font LoadBMFont(const char *fileName)
RL_FREE(imFonts); RL_FREE(imFonts);
font.texture = LoadTextureFromImage(fullFont); if (isGpuReady) font.texture = LoadTextureFromImage(fullFont);
// Fill font characters info data // Fill font characters info data
font.baseSize = fontSize; font.baseSize = fontSize;
@ -2299,7 +2303,7 @@ static Font LoadBMFont(const char *fileName)
UnloadImage(fullFont); UnloadImage(fullFont);
UnloadFileText(fileText); UnloadFileText(fileText);
if (font.texture.id == 0) if (isGpuReady && (font.texture.id == 0))
{ {
UnloadFont(font); UnloadFont(font);
font = GetFontDefault(); font = GetFontDefault();