Update: The completed solution using Nathan Reed’s answer is posted in my answer below
A few open source programs I’ve seen that render installed fonts do something like this…
Create a texture for the font
Draw font to texture using native calls
Store the coordinates for each character
Create a vertex buffer with a quad for each character
Render the vertex buffer using the font texture
But I’m really having trouble getting this to work consistently. GetTextExtentPoint32A() for Win32 font sizes which does NOT include italic support and seems to cut off some of the stranger fonts.
Here is an example output from my code. Notice the cut off edge of the Q and a few other characters. A much more exaggerated version happens when rendering italics.
The code looks something like this…
for (uint8 c = 0; c < 127 - 32; c++)
str = c + 32;
GetTextExtentPoint32A(hDC, str, 1, &size);
if (x+size.cx+1 > m_TextureSize)
x = 0;
// 1 pixel vertical margin
y += size.cy + 1;
ExtTextOutA(hDC, x+0, y+0, ETO_OPAQUE | ETO_CLIPPED, NULL, str, 1, NULL);
m_fTexCoords[c].Left = x/m_TextureSize;
m_fTexCoords[c].Top = y/m_TextureSize;
m_fTexCoords[c].Right = x+size.cx/m_TextureSize;
m_fTexCoords[c].Bottom = y+size.cy/m_TextureSize;
// 1 pixel horizontal margin
x += size.cx;
The image above is actually just a render of the whole texture stretched from -1,-1,0 to 1,1,0 not using the stored texture coordinates to show clipping due to GetTextExtentPoint32A.
Again this works fine for some fonts but looks terrible for others and doesn’t support italics.
It is designed to work in a system like this…
g_Font = SetupFont("Arial", BOLD | ITALIC, 24pt);
g_TextObject = CreateTextObject("The quick brown fox...", g_Font, X, Y);
So in general I guess my question is what is the correct approach for this issue?
Should I just let each text object have a texture and on text object creation use the GDI to render all text to it (which would bypass the italics and font face problem)?
But then wouldn’t texture memory usage get out of hand?