有关OpenGL字体渲染的问题很多,其中许多问题由纹理图集(快速但错误)或字符串纹理(仅固定文本)满足。

但是,这些方法很差,而且似乎已经过时了几年(如何使用着色器更好/更快地执行此操作?)。对于OpenGL 4.1,有一个很好的问题要看“您今天应该使用什么?”:

What is state-of-the-art for text rendering in OpenGL as of version 4.1?

那么,今天我们应该在iOS GL ES 2上使用什么?

我很失望,似乎没有开源(甚至商业解决方案)。我知道很多团队都花了很多时间并花了数周的开发时间来重新发明这个轮子,逐渐学习如何调整字距和空间等等(但是),但是必须有一个比重写整个“字体”更好的方法从头开始?

据我所知,这包括两部分:

  • 我们如何使用字体渲染文本?
  • 我们如何显示输出?

  • 对于1(如何渲染),Apple提供了许多方法来获取“正确的”渲染输出-但“简单”的不支持OpenGL(也许其他一些支持OpenGL)-例如,是否有一种简单的方法来映射CoreText输出到OpenGL?)。

    对于2(如何显示),我们有着色器,我们有VBO,我们有字形纹理,我们有查找纹理以及其他技术(例如上面链接的OpenGL 4.1东西?)

    这是我所知道的两种常见的OpenGL方法:
  • 纹理图集(渲染所有字形一次,然后从共享纹理渲染每个字符1个纹理四边形)
  • 这是错误的,除非您使用的是1980年代的“位图字体”(即使这样:如果需要对非平凡的字体进行校正,则纹理图集需要做的工作比看上去还多)
  • (字体不是“字形的集合”,存在大量的定位,布局,环绕,间距,字距调整,样式,着色,权重等。纹理图集会失效)
  • 固定的字符串(使用任何Apple类正确渲染,然后对背景图像数据进行截图,并作为纹理上传)
  • 用人类的话来说,这是很快的。在帧渲染中,这非常非常慢。如果您在进行大量更改文本的情况下执行此操作,则帧速率将通过最低限度
  • 从技术上讲,这基本上是正确的(不完全是:您会通过这种方式丢失一些信息),但是
  • 的效率非常低下

    我也看过,但是听到了关于好坏的事情:
  • Imagination/PowerVR“Print3D”(链接断开)(来自制造GPU的人员!但是他们的站点已移动/删除了文本呈现页面)
  • FreeType(需要预处理,解释,大量代码,额外的库吗?)
  • ...和/或FTGL http://sourceforge.net/projects/ftgl/(传闻:缓慢? buggy ?很长时间未更新?)
  • 字体隐藏http://digestingduck.blogspot.co.uk/2009/08/font-stash.html(高质量,但是很慢?)
  • 1。

    在Apple自己的OS/标准库中,我知道几种文本渲染来源。注意:我已经在2D渲染项目中详细使用了其中的大部分,我关于它们输出不同渲染的陈述是基于直接经验的

    带有NSString的
  • CoreGraphics
  • 最简单的方法:渲染“成CGRect”
  • 似乎是人们推荐的“固定字符串”方法的稍微快一点的版本(即使您希望它几乎一样)
  • 带有纯文本的
  • UILabel和UITextArea
  • 注意:它们不一样!它们呈现smae文本
  • 的方式略有差异
  • NSAttributedString,呈现为上述之一
  • 再次:呈现不同的外观(我知道的差异相当细微,被归类为“bug”,对此有各种SO问题)
  • CATextLayer
  • iOS字体和旧C渲染之间的混合体。使用“不完全”的免费桥接CFFont/UIFont,它揭示了更多的渲染差异/奇怪
  • CoreText
  • ...最终解决方案?但是它自己的野兽...
  • 最佳答案

    我做了一些进一步的实验,当将CoreText与纹理图集和Valve的有符号差纹理(可以将位图字形转换为与分辨率无关的高分辨率纹理)结合使用时,似乎CoreText可能是一个完美的解决方案。

    ...但是我还没有运行,仍在尝试。

    更新:Apple的文档说,它们使您可以访问除最终细节以外的所有内容:要渲染的字形+字形布局(根据文档,您可以获取行布局和字形数量,但不能获取字形本身)。毫无明显的原因,CoreText显然缺少了这一核心信息(如果这样的话,这使CT几乎一文不值。我仍在寻找是否可以找到获取实际glpyhs +每个字形数据的方法)

    UPDATE2:我现在可以使用Apple的CT正常工作(但没有不同的纹理),但是最终它是3个类文件,10个数据结构,大约300行代码以及OpenGL代码来渲染它。 SO答案太多了:(。

    简短的答案是:是的,您可以这样做,并且如果您执行以下操作,它将起作用:

  • 创建CTFrameSetter
  • 为理论2D框架创建CTFrame
  • 创建一个将转换为GL纹理的CGContext
  • 逐个字形浏览,允许Apple渲染到CGContext
  • 每次Apple渲染字形时,都要计算边界框(这是HARD),然后将其保存在
  • 并保存唯一的字形ID(例如,“o”,“f”和“of”(一个字形!)将有所不同)。
  • 最后,将CGContext作为纹理
  • 发送给GL

    渲染时,请使用Apple创建的字形ID列表,并使用已保存的信息和纹理来渲染每个四边形,并使用带有纹理坐标的四边形将各个字形从您上传的纹理中拉出。

    这行之有效,速度很快,它适用于所有字体,可以正确获取所有字体布局和字距调整等。

    10-05 20:42
    查看更多