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);        
}

Ответы (0 шт):