【问题标题】:OpenGL text rendering - Modify single VBO or use one VBO per Text object?OpenGL 文本渲染 - 修改单个 VBO 或每个文本对象使用一个 VBO?
【发布时间】:2021-09-09 03:04:57
【问题描述】:

我正在制作一个小型 2D 引擎/游戏来学习 OpenGL(使用 OpenGL 330 Core),并且我正在尝试抽象出大多数 OpenGL 函数调用。

现在,我正试图弄清楚如何最好地处理文本渲染。我有一个字体图集,但我不确定如何处理文本的顶点。现在,我有一个 Renderer 类,它有一个 drawText(const Text& text) 方法,如下所示:

const std::vector<Text::Vertex>& vertices = text.getVertices();
glBufferData(GL_ARRAY_BUFFER, sizeof(Text::Vertex) * vertices.size(), vertices.data(), GL_STREAM_DRAW);
glDrawArrays(GL_TRIANGLES, 0, vertices.size());

我不确定这是否好,因为我正在为每个绘制的 Text 对象重新定义 VBO 的内容,并且每帧可能绘制多个 Text 对象。

注意:我没有使用 Text 进行批量渲染,因为:

  • 这是一款简单的 2D 游戏,所以我宁愿等绘制调用成为实际问题后再优化它们
  • Text 可以通过多种方式更新(即在工具提示旁边可见、悬停时更改颜色等),这需要我修改包含批处理顶点数据的单个 VBO

所以,既然我的 Text 对象在转换时是如此不稳定,我是否应该只为每个实例设置一个 VBO,在适当的时候进行修改,并在我在屏幕上绘制文本时绑定一个新的 VBO?

我的理解是,如果这样做,每次绑定新 VBO 时都需要手动调用 glVertexAttribPointer() 方法,因为绑定新 VBO 本身不会影响绘图调用。

或者我应该只拥有一个 VBO 并不断更新其值?

我不确定哪种方法是首选方法,并且我了解到重新绑定 VBO 可能会很昂贵,但我不确定覆盖它们的数据是否更快/更慢。另外,查看 SFML 的源代码以获取一个真实世界的示例,他们似乎每次绘制某些东西时都会设置新顶点(尽管他们的情况可能与我的不同,因为他们不使用 OpenGL 3+ 并且不做任何批处理渲染)。

【问题讨论】:

    标签: c++ opengl vbo


    【解决方案1】:

    文本渲染最好被视为vertex streaming 的一种形式,因为它就是这样。您应该假设您的文本每一帧都在变化,并且每帧都更新它。由于文本不多,即使文本数据没有变化,流式传输文本数据也没什么大不了的。

    鉴于您正在流式传输,处理此问题的最佳方法是通过映射。在开始寻找要呈现的文本之前,您已经映射了缓冲区。您将顶点数据写入每个字形的缓冲区。完成文本渲染后,取消映射缓冲区并绘制它。

    现在,这假设是纯文本绘图。也就是说,你不是在做 UI 的东西,窗口剪裁的视口剪裁等等。如果是这样,那么事情会变得更加复杂,因为您将需要从缓冲区的不同部分发出多次绘制。但即使在这种情况下,您要做的就是为您的文本构建一个绘制列表,然后在写入所有字形数据后发布它们。

    映射缓冲区。当您遍历需要绘制的文本时,将字形顶点数据写入映射的指针。完成后,取消映射缓冲区并绘制字形。 (注意:请随意使用persistent mappinginvalidation techniques 来提高性能。您可能需要在缓冲区区域之间进行乒乓操作,以免与GPU 同步)。

    这是关于内存分配,而不是绘制调用的数量。您应该选择一个足以绘制您需要的所有文本的缓冲区大小。

    这里的要点是填充缓冲区,然后从中绘制。不要在同一个循环中填充和绘制,并且绝对不要在渲染过程中分配缓冲区对象。

    【讨论】:

    • 感谢您的回答。这几乎是我需要的一切!虽然我计划最终为我的 UI 提供类似滚动区域的东西。您能否详细说明“从缓冲区的不同部分发出多次绘制”位?你的意思是说我需要从偏移量开始绘制,例如,如果我的文本的上半部分被模板打印在滚动区域之外?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多