Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Is there any way to have sf::Text not cache the new font texture into memory whe  (Read 227 times)

0 Members and 1 Guest are viewing this topic.

dsfsf

  • Newbie
  • *
  • Posts: 3
    • View Profile
    • Email
I am making a program using SFML on an old laptop, and its task is to print all Unicode characters, just like in this video:

However, after running for a while, the program will show the error:
"Failed to add a new character to the font: the maximum texture size has been reached."
I noticed that Text::setString() caches the textures of the characters rendered in the text into memory to speed up the next use of those textures, but my program clearly does not need this feature.

My current solution is:

Text::setString(character);
if (character % 500 == 0) {
    mainFont.loadFromFile(currentFont);
}

This is clumsy and wastes performance and memory.

Is there a solution?
One idea I had was to use FreeType to render the characters directly, but I feel like this would waste SFML's potential.


kimci86

  • Full Member
  • ***
  • Posts: 128
    • View Profile
Instead of completely reloading the font from file, you could make a copy of the sf::Font instance before rendering characters, and use it to reset your working sf::Font instance from time to time by assigning to it. This will reuse the same underlying FreeType objects under the hood but start with new empty textures.
« Last Edit: November 22, 2024, 08:34:26 am by kimci86 »

dsfsf

  • Newbie
  • *
  • Posts: 3
    • View Profile
    • Email
"Failed to add a new character to the font: the maximum texture size has been reached."
This error is not entirely due to the low video memory of my laptop. I tested it on my other pc with 8gb vram. This problem still occurs without manually clearing the cache at certain intervals.Apparently, this is caused by keep adding large character texture caches to the vram. I am very frustrated by this problem. It would be great if sfml had an API to turn off the default behavior of automatically caching character textures in video memory.
« Last Edit: Today at 08:55:49 am by dsfsf »

dsfsf

  • Newbie
  • *
  • Posts: 3
    • View Profile
    • Email
Instead of completely reloading the font from file, you could make a copy of the sf::Font instance before rendering characters, and use it to reset your working sf::Font instance from time to time by assigning to it. This will reuse the same underlying FreeType objects under the hood but start with new empty textures.
thanks for it. 👍 but this is not much different from what I wrote, and does not change the underlying problem. I compared the two by the time it takes to iterate over a CJK Unicode block without limiting the fps, and the difference is about 200 milliseconds.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11032
    • View Profile
    • development blog
    • Email
You need to understand that your use case of printing all the characters in existence is very niche/unusual one, which SFML ends up not being optimized for or offering any easy option to deal with.

Yes, it's not (just) about VRAM, but the texture size.
This limitation is of course on its own not very niche and there has been some attempts to add support for multiple textures, to work around it.

Currently, there isn't really a way around this beyond resetting the font.
You could see if it helps to load the font into memory and use openFromMemory, that way you at least wouldn't need to go to the disk, at the cost of a few MB of memory.

Also, make sure you're measuring the changes in release mode. Especially around construction/destruction you can get way worse performance in debug mode.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/