我试图获得一个基本项目来渲染SDL2和FreeType的文本,但它的所有渲染都是白色方块而不是每个角色。我渲染每个glygh并将像素数据转换为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);
}
答案 0 :(得分:1)
您可以设置调色板:
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,
32,
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);
}
或者自己进行RGBA转换:
public IConfiguration Configuration { get; }