FreeType: сохранение битмапов в список для дальнейшей работы
Я пишу генератор текстурного атласа для шрифтов, в котором приходится использовать предварительную сортировку символов по высоте, дабы уместить всё максимально компактно
Получается, нужно получить эту самую высоту, но вызывать два раза FT_Load_Char(args) для одного и того же символа не хочется, ибо повторная растеризация векторного рисунка может сказаться на производительности.
Решил сохранить высоту и битмапы в список, затем отсортировать его, пробежаться от первого элемента к последнему и отрисовать в атлас. Проблема в том, что битмап из face->glyph копируется либо пустым, либо кривым
Font(string path)
{
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
FontLoader::init();
FT_Face face;
int error = FT_New_Face(*FontLoader::lib, path.c_str(), 0, &face);
if (error == FT_Err_Unknown_File_Format)
{
cerr << "Failed to load font: unknown format!\n";
return;
}
else if (error != 0)
{
cerr << "Failed to load font\n";
return;
}
//Создание текстурного атласа
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_2D, textureID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, FONT_ATLAS_SIZE, FONT_ATLAS_SIZE, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, nullptr);
FT_Set_Pixel_Sizes(face, 0, FT_PIXEL_SIZE);
struct _char
{
wchar_t code;
FT_GlyphSlot slot;
};
list<_char> characters;
wchar_t character = 0;
unsigned int index = 0;
character = FT_Get_First_Char(face, &index);
do
{
FT_Load_Char(face, character, FT_LOAD_RENDER); //создание face->glyph
FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL); //донастройка face->glyph
_char _character;
_character.code = character;
_character.slot = face->glyph;
if (characters.size() > 0)
{
}
else
{
characters.push_back(_character);
}
} while (index && false); //убрать false, оно нужно для теста
for (auto it = characters.begin(); it != characters.end(); it++)
{
int width = it->slot->bitmap.width;
int height = it->slot->bitmap.rows;
cout << width << " " << height << endl;
//Выводится, что ширина и высота равны 0
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
GLubyte c = it->slot->bitmap.buffer[y * width + x];
GLubyte pixels[2] = { c,c };
glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, 1, 1, GL_LUMINANCE_ALPHA,
GL_UNSIGNED_BYTE, pixels);
}
}
}
glBindTexture(GL_TEXTURE_2D, 0);
}