There is a curious bug in the Text class. When drawing a Text string, certain letters (glyphs) do not appear. They do however appear if I append a new letter that is not in the string already (the new letter does not appear however until I add yet a new letter that does not appear).
I discovered that letters only appear properly once SFML properly generates or caches the glyphs. So my guess is that there is a problem with generating or caching the letters first time they appear.
The following workaround (code snippet placed in the beginning of the program) solves the problem:
//loop through all letters we need to cache
for(Uint32 letter = 0x0020; letter < 0x00FF; letter++)
{
//cache various font sizes
for(int size = 12; size < 32; size++)
{
Font::getDefaultFont().getGlyph(letter, size, false);
Font::getDefaultFont().getGlyph(letter, size, true);
}
}
The code to reproduce this problem is trivial. Use default font (or any other kind of font) of any size and draw it. Certain letters have always problem drawing the first time (until I draw another problem letter, in which case only the new problem letter is not drawn properly).
Windows 7 (64-bit). Compiled SFML in x86 Debug mode using GCC and Code::Blocks. Graphics card is an Nvidia GTX460M.
I have also encountered the bug. The bug does not occur under all situations; however, I have gotten it to consistently occur with a simple framerate counter.
Here is the code for SFML.NET:
using System;
using SFML.Window;
using SFML.Graphics;
using System.Timers;
namespace MissingGlyphs
{
class Program
{
static Text text = new Text();
static Random r = new Random();
static int frames = 0;
static RenderWindow app;
static void Main()
{
app = new RenderWindow(new VideoMode(800, 600), "Missing Glyphs");
app.Closed += new EventHandler(app_Closed);
text.CharacterSize = 18; //The larger the font, the more issues it has. Nothing displays at 72.
text.Position = new Vector2f(4, 4);
text.Color = Color.White;
Timer fpsTimer = new Timer();
fpsTimer.Elapsed += new ElapsedEventHandler(fpsTimer_Elapsed);
fpsTimer.Interval = 1000;
fpsTimer.Start();
while (app.IsOpen())
{
frames++;
app.DispatchEvents();
app.Clear(Color.Black);
app.Draw(text);
app.Display();
}
}
static void fpsTimer_Elapsed(object sender, ElapsedEventArgs e)
{
text.DisplayedString = frames.ToString() + " FPS";
app.SetTitle("Missing Glyphs - " + frames.ToString() + " FPS");
frames = 0;
}
static void app_Closed(object sender, EventArgs e)
{
app.Close();
}
}
}
I hope this helps the problem.