Issue with Freetype and OpenGL

I'm not familiar with FreeType, but from the picture, it looks like the width of the characters is not directly related to the size of the buffers (ie. glyph->buffer does not point to an array of glyph->width*glyth->height bytes).

As a guess, I'd say that all the chars have a single width in memory (as opposed to the size they use on screen), probably the biggest of all the widths of the glyphs, but you load them with a per-char width instead of the correct one. So, only the glyphs that use the full width are correct.


Use:

glPixelStorei(GL_PACK_ALIGNMENT, 1);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

This annoyed the heck out of me too, but you need to tell OpenGL to use the spacing you give it, not the normal 32-bit boundaries it expects. The pitch of the images changes, but OpenGL doesn't know to use smaller packing alignments without these calls before your texture creation.

I do it like this:

// Convert the glyph to a bitmap.
FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, NULL, true);
FT_BitmapGlyph bitmap_glyph = (FT_BitmapGlyph)glyph;

// This reference will make accessing the bitmap easier
FT_Bitmap& bitmap = bitmap_glyph->bitmap;

int _Left = abs(bitmap_glyph->left);
int _Top = abs(bitmap_glyph->top);
int _Height = abs(bitmap.rows);
int _Width = _Left+abs(bitmap.width);

// If it's not a glyph or spacing, go to the next one
if ((_Width == 0 || _Height == 0) && !isspace(i))
    return;

advances[i] = max(_Width, face->glyph->advance.x >> 6);

vector<unsigned char> Data(_Height*_Width*2, 0);
for (int32 h=0; h < abs(bitmap.rows); ++h)
    for (int32 w=0; w < abs(bitmap.width); ++w)
    {
        int32 luminance = bitmap.buffer[h*bitmap.pitch + w];
        Data[(h*_Width + w + _Left)*2 + 0] = 255;
        Data[(h*_Width + w + _Left)*2 + 1] = luminance;
    }

I could probably move the 255 (White) into the String initialization function then just use the values in FreeType for my alpha values, but this way seems more descriptive and speed isn't an issue in my usage.

The Address &Data[0] now contains a GL_LUMINANCE_ALPHA external format, with type GL_UNSIGNED_CHAR and size _Width*_Height. This should make anyone who does this stuff's life easier.