把字符串中的每一个字符都通过 freetype 取出对应的 bitmap,再把这些 bitmap 上传为纹理交给 GL 绘制,就可以在游戏里显示文字。

下面是 Lite2D::Text 中 getCharBitMapData 的实现,它负责把单个字符渲染成一张带 Alpha 通道的 RGBA 纹理。

CharBitMap *Text::getCharBitMapData(unsigned short _char)
                {
                	CharBitMap *bitmap = new CharBitMap;
                
                
                
                
                	FT_Set_Pixel_Sizes(face, _fontsize, _fontsize);
                	//FT_Set_Char_Size(face, 2*64, 2*64, 900, 900);
                
                	auto _index = FT_Get_Char_Index(face, _char);
                	auto _glyph = FT_Load_Glyph(face, _index, FT_LOAD_DEFAULT);
                
                
                
                
                
                	FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL);
                	FT_Bitmap&bitmap1 = face->glyph->bitmap;
                
                
                
                	int width = bitmap1.width;
                	int height = bitmap1.rows;
                
                	char* data1 = new char[width*height * 4];
                	//	memset(data1, 0, width*height * 4);
                
                
                	//make a bitmap
                	for (int j = 0; j < height; j++)
                	{
                		for (int i = 0; i < width; i++)
                		{
                			unsigned char _value = (i >= bitmap1.width || j >= bitmap1.rows) ? 0x0 :
                				bitmap1.buffer[i + bitmap1.width*j];
                
                			//R G B A
                			data1[(4 * i + (height - j - 1) * width * 4)] = _color3b.r;  //R
                			data1[(4 * i + (height - j - 1) * width * 4) + 1] = _color3b.g; // G
                			data1[(4 * i + (height - j - 1) * width * 4) + 2] = _color3b.b;//B
                			data1[(4 * i + (height - j - 1) * width * 4) + 3] =  _value; //A
                		}
                	}
                
                
                
                	//memset(data1, 0xf0, width );
                
                	//	memcpy(data1, bitmap1.buffer, width*height * 4);
                
                
                
                
                
                
                
                	bitmap->data = data1;
                	bitmap->height = height;
                	bitmap->width = width;
                	bitmap->size = width*height * 4;
                	bitmap->_char = _char;
                
                	//deal with ' '
                	if (_char == 32)
                	{
                		bitmap->width = _fontsize / 2.0f;
                	}
                
                
                 	log1(" char %d   %d %d", _char, width, height);
                //
                //
                
                	glGenTextures(1, &bitmap->texture_id);
                
                	glBindTexture(GL_TEXTURE_2D, bitmap->texture_id);
                
                
                	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
                	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
                
                
                
                
                	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
                	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
                
                
                	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
                
                	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bitmap->width, bitmap->height, 0,
                		GL_RGBA, GL_UNSIGNED_BYTE, bitmap->data);
                	//glBindTexture(GL_TEXTURE_2D, bitmap->texture_id);
                
                
                	return bitmap;
                
                }