添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
朝气蓬勃的茶叶  ·  jQuery ...·  2 年前    · 
苦闷的鞭炮  ·  mysql ...·  2 年前    · 
沉稳的烈马  ·  Python ...·  2 年前    · 
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I'm trying to get a basic project to render text with SDL2 and FreeType, but all it's rendering is white squares instead of each character. I'm rendering each glygh and converting the pixel data to an SDL_Surface with SDL_CreateRGBSurfaceFrom() . I tried messing with the bit masks of the rgb components, the depth of the pixel, and even the blend mode of the surface, but none of that worked so far.

Here is the relevant bits of code. The font is loading correctly earlier in the file, and I'm setting the size of the font after loading it. What could cause the characters to appear as blank squares?

#include <sdl.h>
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_BITMAP_H
#include FT_OUTLINE_H
#include <iostream>
/// Forward declaration
void Init();
void DeInit();
void Input();
void Update();
void Draw();
/// Memory
SDL_Window* window;
SDL_Surface* target;
FT_Library ftLib;
FT_Bitmap ftTarget;
FT_Face ftFace;
bool running = true;
int x = 0;
int y = 32;
/// Functions
void DrawBitmap(FT_Bitmap bm, int x, int y);
int main(int argc, char* argv[]) {
    Init();
    while (running) {
        Input();
        Update();
        Draw();
    DeInit();
    return 0;
void Init() {
    // Init
    SDL_Init(SDL_INIT_EVERYTHING);
    window = SDL_CreateWindow("FreeType Test", 1920/2-600/2, 1080/2-400/2, 600, 400, 0);
    FT_Init_FreeType(&ftLib);
    FT_New_Face(ftLib, "C:\\Windows\\Fonts\\Arial.ttf", 0, &ftFace);
    FT_Set_Char_Size(ftFace, 12 << 6, 12 << 6, 72, 72);
    // Setup
    target = SDL_GetWindowSurface(window);
void DeInit() {
    // DeInit
    FT_Done_Face(ftFace);
    FT_Done_FreeType(ftLib);
    SDL_DestroyWindow(window);
    SDL_Quit();
void Input() {
    SDL_Event e;
    while (SDL_PollEvent(&e)) {
        switch (e.type) {
        case SDL_QUIT:
            running = false;
            break;
void Update() {
    // nothing for now
void Draw() {
    SDL_FillRect(target, nullptr, SDL_MapRGBA(target->format, 128, 128, 0, 255));
    // Draw text
    constexpr char text[] = "This is cool B)";
    for (int n = 0; n < sizeof(text); n++)
        FT_Load_Char(ftFace, text[n], FT_LOAD_RENDER);
        DrawBitmap(ftFace->glyph->bitmap, x + ftFace->glyph->bitmap_left, y - ftFace->glyph->bitmap_top);
        x += ftFace->glyph->advance.x >> 6;
        y += ftFace->glyph->advance.y >> 6;
    x = 0;
    y = 32;
    SDL_UpdateWindowSurface(window);
    SDL_Delay(10);
void DrawBitmap(FT_Bitmap bm, int x, int y) {
    SDL_Surface* glyph = SDL_CreateRGBSurfaceFrom(bm.buffer, bm.width, bm.rows, 8, bm.pitch, 0, 0, 0, 0xFF);
    SDL_SetSurfaceBlendMode(glyph, SDL_BlendMode::SDL_BLENDMODE_NONE);
    SDL_Rect dest = { x, y, 0, 0 };
    SDL_BlitSurface(glyph, nullptr, target, &dest);
    SDL_FreeSurface(glyph);
void DrawBitmap(FT_Bitmap bm, int x, int y)
    SDL_Surface* glyph = SDL_CreateRGBSurfaceFrom(bm.buffer, bm.width, bm.rows, 8, bm.pitch, 0, 0, 0, 0xFF);
    SDL_Color colors[256];
    for( int i = 0; i < 256; i++)
        colors[i].r = colors[i].g = colors[i].b = i;
    SDL_SetPaletteColors(glyph->format->palette, colors, 0, 256);
    SDL_SetSurfaceBlendMode(glyph, SDL_BlendMode::SDL_BLENDMODE_NONE);
    SDL_Rect dest = { x, y, 0, 0 };
    SDL_BlitSurface(glyph, nullptr, target, &dest);
    SDL_FreeSurface(glyph);

Or do the RGBA conversion yourself:

void DrawBitmap(FT_Bitmap bm, int x, int y)
    if( bm.width == 0 || bm.rows == 0 )
        return;
    std::vector< unsigned char > rgba( bm.width * bm.rows * 4 );
    for( unsigned int y = 0; y < bm.rows; ++y )
        for( unsigned int x = 0; x < bm.width; ++x )
            unsigned char val = bm.buffer[ ( bm.pitch * y ) + x ];
            size_t base = ( ( bm.width * y ) + x ) * 4;
            rgba[ base + 0 ] = 0xFF;
            rgba[ base + 1 ] = 0xFF;
            rgba[ base + 2 ] = 0xFF;
            rgba[ base + 3 ] = val;
    SDL_Surface* glyph = SDL_CreateRGBSurfaceFrom
        &rgba[0],
        bm.width,
        bm.rows,
        bm.width*4,
        0x000000ff,
        0x0000ff00,
        0x00ff0000,
        0xff000000
    SDL_SetSurfaceBlendMode(glyph, SDL_BlendMode::SDL_BLENDMODE_BLEND);
    SDL_Rect dest = { x, y, 0, 0 };
    SDL_BlitSurface(glyph, nullptr, target, &dest);
    SDL_FreeSurface(glyph);
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.