我正在制作c ++游戏引擎,现在我正在执行一项使用ttf字体输出特定字母的任务。字母如é,à,è等。这是为了本地化。 当然这些字符有字形,但如果我试过这个,那么只有那些已经破了。我的意思是,它打印不正确。 我找到了一些信息,他们说这可能是unicode,ascii,unsigned chars,locale ......的问题但是我试过的每一个镜头都失败了。
所以我想得到你的帮助。这是我的代码,我认为它与此问题有关。 我引用了NEHE的论坛。
void Text::font_data::SetFont(const char* font_name, unsigned int size)
{
textures = new Texture[128];
this->size = (float)size;
FT_Library library;
if (FT_Init_FreeType(&library))
throw std::runtime_error("FT_Init_FreeType failed");
FT_Face face = 0;
if (FT_New_Face(library, font_name, 0, &face))
throw std::runtime_error("FT_New_Face failed (there is probably a problem with your font file)");
FT_Set_Char_Size(face, size << 6, size << 6, 96, 96);
list_base = glGenLists(128);
glGenTextures(128, &(GLuint)textures->texID);
for (unsigned char i = 0; i < 128; ++i)
Make_dlist(face, i, list_base, (GLuint*)&textures->texID);
FT_Done_Face(face);
FT_Done_FreeType(library);
}
void Text::font_data::Clean(void)
{
glDeleteLists(list_base, 128);
glDeleteTextures(128, (GLuint*)&textures->texID);
delete[] textures;
}
void Text::font_data::Make_dlist(FT_Face face, unsigned char ch, GLuint list_base, GLuint* tex_base)
{
if (FT_Load_Glyph(face, FT_Get_Char_Index(face, ch), FT_LOAD_DEFAULT))
throw std::runtime_error("FT_Load_Glyph failed");
FT_Glyph glyph;
if (FT_Get_Glyph(face->glyph, &glyph))
throw std::runtime_error("FT_Load_Glyph failed");
FT_Glyph_To_Bitmap(&glyph, ft_render_mode_normal, 0, 1);
FT_BitmapGlyph bitmap_glyph = (FT_BitmapGlyph)glyph;
FT_Bitmap& bitmap = bitmap_glyph->bitmap;
int width = Next_p2(bitmap.width);
int height = Next_p2(bitmap.rows);
GLubyte* expanded_data = new GLubyte[2 * width * height];
for (int j = 0; j < height; ++j)
{
for (int i = 0; i < width; ++i)
{
expanded_data[2 * (i + j*width)] = expanded_data[2 * (i + j*width) + 1]
= (i >= bitmap.width || j >= bitmap.rows) ?
0 : bitmap.buffer[i + bitmap.width*j];
}
}
glBindTexture(GL_TEXTURE_2D, tex_base[ch]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, expanded_data);
delete [] expanded_data;
glNewList(list_base + ch, GL_COMPILE);
glBindTexture(GL_TEXTURE_2D, tex_base[ch]);
glPushMatrix();
glTranslatef(float(bitmap_glyph->left), 0, 0);
glTranslatef(0.f, float(bitmap_glyph->top - bitmap.rows), 0.f);
float x = float(bitmap.width) / float(width);
float y = float(bitmap.rows) / float(height);
glBegin(GL_QUADS);
glTexCoord2d(0.f, 0.f); glVertex2f(0.f, float(bitmap.rows));
glTexCoord2d(0.f, y); glVertex2f(0.f, 0.f);
glTexCoord2d(x, y); glVertex2f(float(bitmap.width), 0.f);
glTexCoord2d(x, 0.f); glVertex2f(float(bitmap.width), float(bitmap.rows));
glEnd();
glPopMatrix();
glTranslatef(float(face->glyph->advance.x >> 6), 0.f, 0.f);
glEndList();
}
void Text::SetInput(const char *fmt, ...)
{
//const Text::font_data &ft_font
m_font = m_fontInfo.list_base;
m_fontSize = m_fontInfo.size / .63f;
va_list ap;
if (fmt == NULL)
*m_text = 0;
else {
va_start(ap, fmt);
vsprintf_s(m_text, fmt, ap);
va_end(ap);
}
}
void Text::Draw(float dt)
{
UNREFERENCED_PARAMETER(dt);
m_color = GetSprite()->GetColor();
m_scale = GetSprite()->GetTransform()->GetScale();
m_position = GetSprite()->GetTransform()->GetPosition();
glLoadIdentity();
glColor4f(m_color.R, m_color.G, m_color.B, m_color.A);
glScalef(m_scale.x, m_scale.y, m_scale.z);
//PushScreenCoordMatrix();
const char* start_line = m_text;
vector<string> lines;
const char* c = m_text;
for (; *c; c++)
{
if (*c == '\n'){
string line;
for (const char* n = start_line; n < c; ++n)
line.append(1, *n);
lines.push_back(line);
start_line = c + 1;
}
}
if (start_line) {
string line;
for (const char* n = start_line; n < c; ++n)
line.append(1, *n);
lines.push_back(line);
}
glPushAttrib(GL_LIST_BIT | GL_CURRENT_BIT | GL_ENABLE_BIT | GL_TRANSFORM_BIT);
glMatrixMode(GL_MODELVIEW);
glDisable(GL_LIGHTING);
glEnable(GL_TEXTURE_2D);
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glListBase(m_font);
float modelview_matrix[16];
glGetFloatv(GL_MODELVIEW_MATRIX, modelview_matrix);
for (unsigned int i = 0; i < lines.size(); ++i) {
glPushMatrix();
glLoadIdentity();
glTranslatef(m_position.x, m_position.y - m_fontSize*i, m_position.z);
glMultMatrixf(modelview_matrix);
glCallLists(lines[i].length(), GL_UNSIGNED_BYTE, lines[i].c_str());
glPopMatrix();
}
glPopAttrib();
//Pop_projection_matrix();
}