OpenGLES 2(iOS - CoreText?)中的文本/字体渲染 - 选项和最佳实践? [英] Text/font rendering in OpenGLES 2 (iOS - CoreText?) - options and best practice?

查看:18
本文介绍了OpenGLES 2(iOS - CoreText?)中的文本/字体渲染 - 选项和最佳实践?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

关于 OpenGL 字体渲染有很多问题,其中很多问题都可以通过纹理图集(快速但错误)或字符串纹理(仅限固定文本)来解决.

There are many questions on OpenGL font rendering, many of them are satisfied by texture atlases (fast, but wrong), or string-textures (fixed-text only).

但是,这些方法很差,并且似乎已经过时了(使用着色器来更好/更快地做到这一点怎么样?).对于 OpenGL 4.1,有一个很好的问题是关于你今天应该使用什么?":

However, those approaches are poor and appear to be years out of date (what about using shaders to do this better/faster?). For OpenGL 4.1 there's this excellent question looking at "what should you use today?":

从 4.1 版开始,OpenGL 中文本渲染的最新技术是什么?

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

我很失望似乎没有开源(甚至商业解决方案).我知道很多团队都把它搞砸了,花费数周的开发时间重新发明这个轮子,逐渐学习如何调整字距和空间等(呃)——但肯定有比重写整个字体"更好的方法从头开始?

I'm disappointed that there appears to be no open-source (or even commercial solution). I know a lot of teams suck it down and spend weeks of dev time re-inventing this wheel, gradually learning how to kern and space etc (ugh) - but there must be a better way than re-writing the whole of "fonts" from scratch?

据我所知,这有两个部分:

As far as I can see, there are two parts to this:

  1. 我们如何使用字体呈现文本?
  2. 我们如何显示输出?

对于 1(如何渲染),Apple 提供了许多方法来获得正确"的渲染输出 - 但简单"的方法不支持 OpenGL(也许其他一些支持 - 例如,有没有简单的方法来将 CoreText 输出映射到 OpenGL?).

For 1 (how to render), Apple provides MANY ways to get the "correct" rendered output - but the "easy" ones don't support OpenGL (maybe some of the others do - e.g. is there a simple way to map CoreText output to OpenGL?).

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

For 2 (how to display), we have shaders, we have VBOs, we have glyph-textures, we have lookup-textures, and other tecniques (e.g. the OpenGL 4.1 stuff linked above?)

以下是我所知道的两种常见的 OpenGL 方法:

Here are the two common OpenGL approaches I know of:

  1. 纹理图集(渲染所有字形一次,然后从共享纹理中为每个字符渲染 1 x 纹理四边形)
  1. Texture atlas (render all glyphs once, then render 1 x textured quad per character, from the shared texture)
  1. 这是错误的,除非您使用的是 1980 年代的位图字体"(即便如此:纹理图集需要比看起来更多的工作,如果您需要正确处理非平凡字体)
  2. (字体不是字形的集合",有大量的定位、布局、环绕、间距、字距调整、样式、着色、权重等.纹理图集失败)

  • 固定字符串(使用任何 Apple 类正确渲染,然后截取背景图像数据,并作为纹理上传)

  • Fixed string (use any Apple class to render correctly, then screenshot the backing image-data, and upload as a texture)

    1. 就人类而言,这很快.在帧渲染中,这非常非常慢.如果您使用大量不断变化的文本来执行此操作,那么您的帧速率会下降
    2. 从技术上讲,它大部分是正确的(不完全正确:这样会丢失一些信息),但效率极低

  • 我也见过,但也听说过:

    I've also seen, but heard both good and bad things about:

    1. Imagination/PowerVR Print3D"(链接断开)(来自制造 GPU 的人!但他们的网站已移动/删除了文本渲染页面)
    2. FreeType(需要预处理、解释、大量代码、额外库?)
    3. ...和/或 FTGL http://sourceforge.net/projects/ftgl/(传闻:速度慢?有bug?很久没更新了?)
    4. 字体存储 http://digestingduck.blogspot.co.uk/2009/08/font-stash.html(高质量,但速度很慢?)
    5. 1.
    1. Imagination/PowerVR "Print3D" (link broken) (from the guys that manufacture the GPU! But their site has moved/removed the text rendering page)
    2. FreeType (requires pre-processing, interpretation, lots of code, extra libraries?)
    3. ...and/or FTGL http://sourceforge.net/projects/ftgl/ (rumors: slow? buggy? not updated in a long time?)
    4. Font-Stash http://digestingduck.blogspot.co.uk/2009/08/font-stash.html (high quality, but very slow?)
    5. 1.

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

    Within Apple's own OS / standard libraries, I know of several sources of text rendering. NB: I have used most of these in detail on 2D rendering projects, my statements about them outputting different rendering are based on direct experience

    1. 带有 NSString 的 CoreGraphics
    1. CoreGraphics with NSString
    1. 最简单的:渲染成 CGRect"
    2. 似乎是人们推荐的固定字符串"方法的一个稍微快一点的版本(尽管您希望它大致相同)

  • 带有纯文本的 UILabel 和 UITextArea

  • UILabel and UITextArea with plain text

    1. 注意:它们不一样!它们呈现 smae 文本的方式略有不同

  • NSAttributedString,呈现为上述之一

  • NSAttributedString, rendered to one of the above

    1. 再次:呈现方式不同(我所知道的差异相当微妙,被归类为错误",关于此的各种 SO 问题)

  • CATextLayer

  • CATextLayer

    1. iOS 字体和旧 C 渲染的混合体.使用不完全"的免费桥接 CFFont/UIFont,这揭示了更多的渲染差异/奇怪

  • CoreText

  • CoreText

    1. ...最终的解决方案?但它自己的野兽......

  • 推荐答案

    我做了更多的实验,似乎 CoreText 结合纹理图集和 Valve 的符号差分纹理(可以转位图字形转换为与分辨率无关的高分辨率纹理).

    I did some more experimenting, and it seems that CoreText might make for a perfect solution when combined with a texture atlas and Valve's signed-difference textures (which can turn a bitmap glyph into a resolution-independent hi-res texture).

    ...但我还没有让它工作,还在试验中.

    ...but I don't have it working yet, still experimenting.

    更新:Apple 的文档说他们可以让您访问除最终细节之外的所有内容:要呈现的字形 + 字形布局(根据文档,您可以获得行布局和字形数量,但不能获得字形本身).没有明显的原因,CoreText 显然缺少这条核心信息(如果是这样,那 CT 几乎一文不值.我仍在寻找是否能找到一种方法来获取实际的 glpyhs + per-glyph 数据)

    UPDATE: Apple's docs say they give you access to everything except the final detail: which glyph + glyph layout to render (you can get the line layout, and the number of glyphs, but not the glyph itself, according to docs). For no apparent reason, this core piece of info is apparently missing from CoreText (if so, that makes CT almost worthless. I'm still hunting to see if I can find a way to get the actual glpyhs + per-glyph data)

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

    UPDATE2: I now have this working properly with Apple's CT (but no different-textures), but it ends up as 3 class files, 10 data structures, about 300 lines of code, plus the OpenGL code to render it. Too much for an SO answer :(.

    简短的回答是:是的,你可以做到,而且它有效,如果你:

    The short answer is: yes, you can do it, and it works, if you:

    1. 创建 CTFrameSetter
    2. 为理论上的二维帧创建 CTFrame
    3. 创建一个将转换为 GL 纹理的 CGContext
    4. 逐个字形检查,允许 Apple 渲染到 CGContext
    5. 每次 Apple 渲染字形时,计算边界框(这是 HARD),并将其保存在某处
    6. 并保存唯一的字形 ID(这对于例如o"、f"和of"(一个字形!)会有所不同)
    7. 最后,将 CGContext 作为纹理发送到 GL

    渲染时,请使用 Apple 创建的字形 ID 列表,并为每个字形 ID 使用保存的信息和纹理,以渲染具有纹理坐标的四边形,从而将单个字形从您上传的纹理中提取出来.

    When you render, use the list of glyph-IDs that Apple created, and for each one use the saved info, and the texture, to render quads with texture-co-ords that pull individual glyphs out of the texture you uploaded.

    这很有效,速度很快,它适用于所有字体,它可以让所有字体布局和字距调整正确,等等.

    This works, it's fast, it works with all fonts, it gets all font layout and kerning correct, etc.

    这篇关于OpenGLES 2(iOS - CoreText?)中的文本/字体渲染 - 选项和最佳实践?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆