65.9K
CodeProject 正在变化。 阅读更多。
Home

FreeType on OpenGL ES (iPhone)

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.75/5 (10投票s)

2010年11月9日

CPOL

4分钟阅读

viewsIcon

90549

downloadIcon

3016

使用 OpenGL ES 渲染的更快、更智能、更好看的字体

引言

此项目使用 OpenGL ES 和 FreeType 库渲染字体。 FreeType 库使用字体微调,这使得字体看起来比普通的抗锯齿字体更好。 这个项目主要为 iPhone 设计,但代码是可移植的,应该可以在其他平台上工作。

此外,此代码被设计为高效的。 所有字体都被打包到一个纹理中,并实现了绘制调用批处理。

在 OpenGL 中渲染文本的标准方法是为每个字符创建一个纹理四边形。 你可以为每个字符设置一个单独的纹理和四边形,但这非常浪费,因为 OpenGL 纹理只能是 2 的幂(即 32x32、64x32 等),这意味着会有很多不必要的填充。 更好的方法是将所有字符打包到一个纹理中 - 称为纹理图集。

characters bin packed into a texture atlas

将字符打包到 128x128 纹理中

将所有内容放在同一个纹理中的另一个优点是,它允许你将更多的 OpenGL 绘制调用批量处理在一起。 这减少了 GPU 的工作负载并提高了性能。

Using the Code

主要的类是 FontAtlas。 要准备要使用的字体,您必须首先将 TrueType 字体(即 .ttf 文件)作为资源包含在您的项目中。 然后,您使用字体的文件名、所需的磅值和您需要的字符列表调用 FontAtlas::AddFont。 对于您需要的每种字体,您都需要调用此函数,然后调用 FontAtlas::CreateAtlas()FontAtlas 类从 FreeType 库检索每个字符的大小,然后使用其箱体打包算法将它们放入 OpenGL ES 纹理中。

初始化字体

const char* szLetters = " !\"#&'()*,-./0123456789:;
<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\\_abcdefghijklmnopqrstuvwxyzÁáÉéÍíÑñÓóÚú";

m_pFontAtlas = new FontAtlas();
m_pFontAtlas->AddFont("arial.ttf", 12, szLetters);
m_pFontAtlas->AddFont("times.ttf", 18, szLetters);
m_pFontAtlas->AddFont("times.ttf", 16, szLetters);
m_pFontAtlas->CreateAtlas();

然后您可以按如下方式渲染 string

FTBitmapFont* pArialFont = m_pFontAtlas->GetFTFont(ARIAL_IX);
pArialFont->DrawString(5, 0, "AV Arial font 12 point", BLACK);

  • FontAtlas

    这是主要的类。 它创建纹理图集并保存所有 FTBitmapFont 对象。 每次调用 AddFont 时,都会创建一个新的 FTBitmapFont 对象。

  • FTBitmapFont

    FTBitmapFont 保存来自 FreeType 库的字符列表和字距调整数据。 可以通过 DrawString 方法渲染 StringGetWidth 返回以给定字体渲染的 string 的宽度。

  • FTBitmapChar

    对于字体中的每个字形(即字符),都有一个 FTBitmapChar。 此类将字形位图复制到纹理中,并计算字符的纹理坐标和顶点尺寸。

  • GLCallBatcher

    此类负责批处理绘制调用。 每次 FTBitmapChar 想要绘制自身时,它都会调用 GLCallBatcher::AddQuadGLCallBatcher 不是直接绘制,而是将所有四边形一起 string 放在一个数组中,并且仅在调用 RenderCurr 或需要状态更改时才将网格数据发送到 GPU。 例如,如果您更改文本的 alpha 值或颜色,则需要状态更改。 这样,绘制调用的数量就减少了。

  • TreeNode

    此类用于实现用于创建纹理图集的箱体打包算法。 是该算法的更详细信息。

字距调整

您可以通过在创建图集之前设置 useKerning 标志来启用字距调整

m_pFontAtlas->SetUseKerning(true); 

就我个人而言,我不认为字距调整值得性能上的损失,因为你几乎不会注意到质量上的差异。

在 XCode 上编译 FreeType

FreeType 源代码包含在项目的 OpenGLFont\Classes\freetype-2.4.3 目录中。 Freetype 实际上应该构建为一个独立的库,但我没有时间这样做(练习留给读者 ;) )。 我按照 FreeType 文档中的 INSTALL.ANY 中详述的说明进行操作。 删除所有我不需要的部分使目录结构扁平化,并禁用了未使用的模块。

构建项目

您需要下载 Boost 并将其解压缩到您驱动器上的某个位置。 然后在 xcode 中设置 include 路径以指向 Boost include 目录。 另外,当您在那里时,修复 FreeType 的路径(即 OpenGLFont/Classes/freetype-2.4.3/include/)。

质量

在 PC 上渲染时,FreeType 字体的质量非常好,但不如其他应用程序(例如 OpenOffice)。 但是,在 iPhone 本身上,它要好得多 - 可能是因为屏幕的像素密度。

历史

  • 版本 1
  • 版本1.01
    • 修复的错误:处理字符代码 > 128
    • 忽略字体中不存在的字符
    • 更智能的内存处理
© . All rights reserved.