FreeType的教程代码. 使用GLUT.
在Nehe的代码基础上改的:
以下是基础代码: struct xCharTexture { GLuint m_texID; wchar_t m_chaID; int m_Width; int m_Height;
int m_adv_x; int m_adv_y; int m_delta_x; int m_delta_y; public: xCharTexture() { m_texID = 0; m_chaID = 0; m_Width = 0; m_Height = 0; } }g_TexID[65536]; class xFreeTypeLib { FT_Library m_FT2Lib; FT_Face m_FT_Face;
int m_w; int m_h; public: xFreeTypeLib() { if (FT_Init_FreeType( &m_FT2Lib) ) exit(0); }
void load(const char* font_file , int _w , int _h) { //加载一个字体,取默认的Face,一般为Regualer if (FT_New_Face( m_FT2Lib, font_file, 0, &m_FT_Face )) exit(0); FT_Select_Charmap(m_FT_Face, FT_ENCODING_UNICODE); m_w = _w ; m_h = _h; m_FT_Face->num_fixed_sizes; //大小要乘64.这是规定。照做就可以了。 //FT_Set_Char_Size( m_FT_Face , 0 , m_w << 6, 96, 96); FT_Set_Pixel_Sizes(m_FT_Face,m_w, m_h); }
GLuint loadChar(wchar_t ch) { if(g_TexID[ch].m_texID) return g_TexID[ch].m_texID;
if(FT_Load_Char(m_FT_Face, ch,FT_LOAD_RENDER|FT_LOAD_FORCE_AUTOHINT| (true ? FT_LOAD_TARGET_NORMAL : FT_LOAD_MONOCHROME | FT_LOAD_TARGET_MONO) ) ) { return 0; }
xCharTexture& charTex = g_TexID[ch];
//得到字模 FT_Glyph glyph; if(FT_Get_Glyph( m_FT_Face->glyph, &glyph )) return 0;
//转化成位图 FT_Render_Glyph( m_FT_Face->glyph, FT_RENDER_MODE_LCD );//FT_RENDER_MODE_NORMAL ); 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 = bitmap.width; int height = bitmap.rows;
m_FT_Face->size->metrics.y_ppem; m_FT_Face->glyph->metrics.horiAdvance;
charTex.m_Width = width; charTex.m_Height = height; charTex.m_adv_x = m_FT_Face->glyph->advance.x / 64.0f; charTex.m_adv_y = m_FT_Face->size->metrics.y_ppem; //m_FT_Face->glyph->metrics.horiBearingY / 64.0f; charTex.m_delta_x = (float)bitmap_glyph->left; charTex.m_delta_y = (float)bitmap_glyph->top - height; glGenTextures(1,&charTex.m_texID); glBindTexture(GL_TEXTURE_2D,charTex.m_texID); char* pBuf = new char[width * height * 4]; for(int j=0; j < height ; j++) { for(int i=0; i < width; i++) { unsigned char _vl = (i>=bitmap.width || j>=bitmap.rows) ? 0 : bitmap.buffer[i + bitmap.width*j]; pBuf[(4*i + (height - j - 1) * width * 4) ] = 0xff; pBuf[(4*i + (height - j - 1) * width * 4)+1] = 0xff; pBuf[(4*i + (height - j - 1) * width * 4)+2] = 0xff; pBuf[(4*i + (height - j - 1) * width * 4)+3] = _vl; } }
glTexImage2D( GL_TEXTURE_2D,0,GL_RGBA,width, height,0,GL_RGBA,GL_UNSIGNED_BYTE,pBuf); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); glTexEnvi(GL_TEXTURE_2D,GL_TEXTURE_ENV_MODE,GL_REPLACE); delete[]pBuf; return charTex.m_chaID; }
}g_FreeTypeLib;
绘制代码如下: void drawText(wchar_t* _strText,int x , int y, int maxW , int h) { int sx = x; int sy = y; int maxH = h; for(int i = 0 ; i < wcslen(_strText) ; i ++) {
if(_strText[i] =='n') { sx = x ; sy += maxH + 12; continue; } xCharTexture* pCharTex = getTextChar(_strText[i]); glBindTexture(GL_TEXTURE_2D,pCharTex->m_texID); glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); //glDisable(GL_TEXTURE_2D); int w = pCharTex->m_Width; int h = pCharTex->m_Height;
int ch_x = sx + pCharTex->m_delta_x; int ch_y = sy - h - pCharTex->m_delta_y;
if(maxH < h) maxH = h; glBegin ( GL_QUADS ); { glTexCoord2f(0.0f, 1.0f); glVertex3f(ch_x , ch_y , 1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f(ch_x + w, ch_y , 1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(ch_x + w, ch_y + h, 1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(ch_x , ch_y + h, 1.0f); } glEnd(); sx += pCharTex->m_adv_x; if(sx > x + maxW) { sx = x ; sy += maxH + 12; } }
}
http://bbs.gameres.com/upload/sf_200692103510.png
|