Fixing Blurry Text Rendering Caused by FreeType Scaling

Most online OpenGL and FreeType text rendering tutorials adjust character quad vertex scale via a scale parameter in the RenderText function. Testing this approach shows it has limited usability: it works correctly only when using integer scale values, but floating-point scale values result in heavily blurry text, making this approach unnecessary.

Instead, use the FreeType built-in API FT_Set_Pixel_Sizes(FT_Face face, FT_Uint width, FT_Uint height), which controls the size of the loaded font glyph textures directly. To create 12-pixel tall text, call it as:

FT_Set_Pixel_Sizes(target_face, 12, 12);

This configures FreeType to load glyphs at the exact pixel size specified, so no additional vertex scaling is needed for character quad dimensions.

However, using odd pixel sizes with FT_Set_Pixel_Sizes can also cause rendering blur. For example, setting a 13-pixel font size will produce blurry text. Fix this by adjusting the vertical glyph psoition:

if (font_size % 2 == 1) {
    y_position = (float)((int)y_position + 0.5f);
} else {
    y_position = roundf(y_position);
}

For odd font sizes, the vertical position must end in .5, and for even sizes, the position must be an integer. Adhering to this rule eliminates blurriness regardless of the chosen font size.

The final vertex data setup uses adjusted y positions, with the required offset of half the font size to properly align glyphs:

for (size_t char_idx = 0; char_idx < utf8_str.length(); char_idx++) {
    GlyphData glyph = loaded_glyphs[(unsigned char)utf8_str[char_idx]];
    float draw_x = x_offset + glyph.bearing_x;
    float draw_y = y_offset - (glyph.size_y - glyph.bearing_y) + ((float)font_size / 2.0f);
    float glyph_width = (float)glyph.size_x;
    float glyph_height = (float)glyph.size_y;

    float quad_vertices[24] = {
        draw_x,         draw_y + glyph_height, 0.0f, 0.0f,
        draw_x,         draw_y,               0.0f, 1.0f,
        draw_x + glyph_width, draw_y,        1.0f, 1.0f,

        draw_x,         draw_y + glyph_height, 0.0f, 0.0f,
        draw_x + glyph_width, draw_y,        1.0f, 1.0f,
        draw_x + glyph_width, draw_y + glyph_height, 1.0f, 0.0f
    };

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, glyph.texture_id);
    glUniform1i(glGetUniformLocation(shader_program, "text_sampler"), 0);

    vbo.update_data(quad_vertices, sizeof(quad_vertices));
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glDrawArrays(GL_TRIANGLES, 0, 6);
    x_offset += (glyph.advance >> 6);
}

Tags: FreeType OpenGL Font Rendering c programming Blurry Text Fix

Posted on Tue, 09 Jun 2026 17:07:44 +0000 by LAMP