C++ 使用FreeType和SDL2渲染文本会生成白色正方形而不是字符
我正在尝试使用SDL2和FreeType创建一个基本项目来渲染文本,但它所渲染的只是白色方块,而不是每个字符。我正在使用C++ 使用FreeType和SDL2渲染文本会生成白色正方形而不是字符,c++,sdl,freetype,C++,Sdl,Freetype,我正在尝试使用SDL2和FreeType创建一个基本项目来渲染文本,但它所渲染的只是白色方块,而不是每个字符。我正在使用SDL\u CreateRGBSurfaceFrom()渲染每个glygh并将像素数据转换为SDL\u曲面。我试着弄乱rgb组件的位掩码、像素的深度,甚至是曲面的混合模式,但到目前为止,所有这些都不起作用 下面是相关的代码位。字体在文件的前面正确加载,加载后我正在设置字体的大小。是什么导致字符显示为空白方块 #include <sdl.h> #include <
SDL\u CreateRGBSurfaceFrom()
渲染每个glygh并将像素数据转换为SDL\u曲面。我试着弄乱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);
}
#包括
#包括
#包括FT_FREETYPE_H
#包括FT_位图_H
#包括FT_大纲
#包括
///远期申报
void Init();
无效脱硝();
无效输入();
无效更新();
无效抽取();
///记忆
SDL_窗口*窗口;
SDL_表面*目标;
自由贸易联盟图书馆自由贸易图书馆;
FT_位图ftTarget;
面部表情;
bool running=true;
int x=0;
int y=32;
///功能
void DrawBitmap(FT_位图bm,int x,int y);
int main(int argc,char*argv[]){
Init();
(跑步时){
输入();
更新();
Draw();
}
脱硝();
返回0;
}
void Init(){
//初始化
SDL_Init(SDL_Init_EVERYTHING);
window=SDL_CreateWindow(“自由式测试”,1920/2-600/21080/2-400/2600400,0);
FT_Init_FreeType(&ftLib);
新字体(ftLib,“C:\\Windows\\font\\Arial.ttf”,0,&ftFace);
设置字符大小(ftFace,12字形->位图,x+ftFace->字形->左侧位图,y-ftFace->字形->顶部位图);
x+=ftFace->glyph->advance.x>>6;
y+=ftFace->glyph->advance.y>>6;
}
x=0;
y=32;
SDL_更新内表面(窗口);
SDL_延迟(10);
}
无效绘制位图(FT_位图bm、int x、int y){
SDL_Surface*glyph=SDL_CreateRGBSurfaceFrom(bm.buffer、bm.width、bm.rows、8、bm.pitch、0、0、0xFF);
SDL_设置曲面BlendMode(图示符,SDL_BlendMode::SDL_BlendMode_NONE);
SDL_Rect dest={x,y,0,0};
SDL_BlitSurface(字形、空PTR、目标和目标);
SDL_自由曲面(字形);
}
您可以设置调色板:
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);
}
void DrawBitmap(FT_位图bm,int x,int y)
{
SDL_Surface*glyph=SDL_CreateRGBSurfaceFrom(bm.buffer、bm.width、bm.rows、8、bm.pitch、0、0、0xFF);
SDL_颜色[256];
对于(int i=0;i<256;i++)
{
颜色[i].r=colors[i].g=colors[i].b=i;
}
SDL_SetPaletteColors(字形->格式->调色板,颜色,0,256);
SDL_设置曲面BlendMode(图示符,SDL_BlendMode::SDL_BlendMode_NONE);
SDL_Rect dest={x,y,0,0};
SDL_BlitSurface(字形、空PTR、目标和目标);
SDL_自由曲面(字形);
}
或者自己进行RGBA转换:
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);
}
void DrawBitmap(FT_位图bm,int x,int y)
{
如果(bm.width==0 | | bm.rows==0)
{
返回;
}
std::vectorrgba(bm.width*bm.rows*4);
for(无符号整数y=0;y
a中编辑。我编辑了我的答案以提供这样一个示例。