How to steal Glyphs from a ImFontAtlas?

I am currently working on an application that will export charts, which are first generated in an OpenGL texture and then drawn over an ImWindow. What I want to do is use the same font textures that ImGui is using to draw the labels instead of drawing the labels after (that way I can just output the texture to an image later on). I looked into the OpenGL 3 implementation and found code to generate the texture from the font atlas:

// Build font texture
ImGuiIO & io = ImGui::GetIO();
unsigned char * pixels;
int width, height;
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);

// Upload texture to graphics system
glGenTextures(1, &fontTexture);
glBindTexture(GL_TEXTURE_2D, fontTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);

Then, I try to write characters using the glyphs in this function:

ImFont * font = ImGui::GetFont();
std::string x_axis_title = "ABCD";
float x = 30.0f;
float y = 100.0f;
for (char c : x_axis_title) {
	auto glyph = font->FindGlyph(c);
	// Triangle 1
	for (auto v : std::vector<float>{x + glyph->X0, y + glyph->Y0, 0, x + glyph->X1, y + glyph->Y0, 0,
	                                 x + glyph->X0, y + glyph->Y1, 0})
	for (auto u : std::vector<float>{glyph->U0, glyph->V0, glyph->U1, glyph->V0, glyph->U0, glyph->V1})

	// Triangle 2
	for (auto v : std::vector<float>{x + glyph->X0, y + glyph->Y1, 0, x + glyph->X1, y + glyph->Y0, 0,
	                                 x + glyph->X1, y + glyph->Y1, 0})
	for (auto u : std::vector<float>{glyph->U0, glyph->V1, glyph->U1, glyph->V0, glyph->U1, glyph->V1})

	for (uint i = 0; i < 18; ++i)

	x += glyph->AdvanceX;

Unfortunately, this results in mostly whitespace with a couple of random lines through where the textures should be. Am I getting the font wrong? Or creating the texture incorrectly?

Whoops, can close this thread. I was accidentally generating the texture before my ttf font was added to the font atlas.

This look right-ish to me.

Note that you can use the ImDrawList API to draw arbitrary text using the same imgui renderer.
There are also GetBackgroundDrawList() GetForegroundDrawList() functions you can use to use a draw list below/above all regular dear imgui windows.

1 Like