Я пытаюсь получить базовый проект для рендеринга текста с SDL2 и FreeType, но все, что он рендерит, это белые квадраты вместо каждого символа. Я рендеринг каждого глиха и преобразование данных пикселей в SDL_Surface
с SDL_CreateRGBSurfaceFrom()
. Я пытался связываться с битовыми масками компонентов rgb, глубиной пикселя и даже с режимом наложения поверхности, но пока ничего из этого не сработало.
Вот соответствующие биты кода. Шрифт загружается корректно ранее в файл, и я устанавливаю размер шрифта после загрузки. Что может привести к появлению символов в виде пустых квадратов?
#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);
}