【问题标题】:What's the best way to render a lot of text with OpenGL用 OpenGL 渲染大量文本的最佳方法是什么
【发布时间】:2020-02-06 12:30:30
【问题描述】:

我开发的软件需要在屏幕上打印大量文本,大约 200 到 400 个字符串和很多独特的字符(一些对象由一个字符表示),该软件已经在使用OpenGL。 我已经处理过文本渲染并且能够渲染文本,但是使用 200 个绘图调用绘制超过 200 个字符串会导致性能问题。

该软件仅在 2D 中绘制。

请务必注意,我的软件在 32 位计算机上运行旧显卡,我不能使用比 2.0 更新的 OpenGL 版本。

您认为最好的选择是什么?

  1. 在每个字体一次绘制调用中渲染所有内容,使用一个包含所有信息的大缓冲区。

  2. 在纹理中渲染每个字符串,然后为每个字符串进行一次绘制调用。 (文字变化不大,最多每秒)

  3. 还有其他想法吗?

【问题讨论】:

  • 200 到 400 个字符串应该不会导致性能问题,比如 1000 页 pdf 可能。
  • 这台电脑真的很旧。该软件的早期版本使用 Qt 来渲染相同的场景。 CPU 快到了 65%。这就是为什么我试图找到最好的方法
  • 我想您应该首先调查性能问题的根源。使用分析器并检查代码的哪一部分消耗更多时间。像std::map<GLText, std::list<size_t>> 这样的东西看起来很俗气。这当然不是纹理图集的实现方式。
  • 是的,我知道。这就是我在这里的原因。我们对软件进行了分析,问题是 Qt 对屏幕上的每个元素都使用了一个 drawcall。所有的 CPU 时间都花在寻找变化和绘图上

标签: c++ opengl text rendering


【解决方案1】:

虽然我不认为我的文本渲染方式接近标准,但我将字体预渲染到一个巨大的字形映射中,并将元数据(字形的位置)存储到一个 ssbo 缓冲区(存储一个数组字形数据(位图和前进除外)。之后,当我需要渲染一堆文本时,我将字符码转换为字形 ID 数组。然后通过循环遍历它并只传递一个 vec2 位置和一个提示字形 Id 每个字符,我通过读取 ssbo 中的数据将点转向几何着色器中的一个矩形,并将纹理坐标传递给片段着色器。

这种方法速度非常快,可以轻松渲染 10000 条文本。它还允许快速切换字体集,并且只要字体具有字形,就能够支持任何 unicode 字符。

【讨论】:

    【解决方案2】:

    由于 OpenGl 不支持在屏幕上呈现字体,因此由程序员定义系统。

    Freetype 是一个很好的字体渲染库。

    https://www.freetype.org/

    您可以将字体纹理渲染到四边形或制作字体图集,然后将它们渲染到四边形

    通常 200 个字符串应该不难,但您可以检查符号距离字段等技术。

    这是一个在opengl中渲染字体的好教程。

    https://learnopengl.com/In-Practice/Text-Rendering

    【讨论】:

      【解决方案3】:

      据我所知,标准方法是制作字体图集纹理。这是您可以将字形光栅化到的位置,并将光栅化字形的 uv 坐标保存到查找表中。然后批处理顶点并在一次绘制调用中绘制所有文本,方法是使用单个纹理(您的图集)并为所有顶点位置设置一个缓冲区。

      只要您制作足够大的纹理,所有字体和字符大小都可以写入同一个图集。您也可以为独特的字符使用第二个图集纹理。

      【讨论】:

      • 是的,图集是必须的,我已经用它画了文字。关键是要维护一个包含每个字符串每个字符的所有数据的缓冲区并不容易。由于字符串可以增长和减少,因此可以更改字母、颜色等。我的实际方法是有一个 std::map> ,其中列表是索引列表,其中给定字符串的每个字符数据都存储在缓冲区中。使用实例化很容易,但 opengl 2 没有。
      • 那么,如果我理解正确的话,您无法为文本的所有顶点提供一个缓冲区?
      • 不,我可以。但这并不容易,或者我不知道如何做好。如果我每帧都重建缓冲区会很容易,但这样会很昂贵。你的意思是顶点,正方形的每个顶点用于渲染角色或只是它的位置?
      • 我不能确定你的情况,但我有一种预感,与 400 个绘图调用相比,为约 400 个字符串重建一个顶点缓冲区对性能的影响应该更小。
      猜你喜欢
      • 1970-01-01
      • 2020-02-27
      • 2011-08-05
      • 2023-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-21
      • 1970-01-01
      相关资源
      最近更新 更多