【问题标题】:OpenGL render fonts instancedOpenGL 渲染字体实例化
【发布时间】:2017-06-01 15:25:15
【问题描述】:

我想用 OpenGL 渲染字体。我得到了一个包含所有字符的纹理和一个文件,其中保存了纹理上数字的每个位置。

例如:

char id=40      x=167  y=0    width=21   height=74   xoffset=-3   yoffset=33   xadvance=59   page=0    chnl=0 
char id=41      x=188  y=0    width=21   height=74   xoffset=-3   yoffset=33   xadvance=59   page=0    chnl=0 

我现在想把它渲染到一个四边形上。但是这通常是怎么做的呢?每个数字都有一个渲染调用?或者我应该渲染数字实例?这意味着我将纹理坐标和偏移等作为实例属性存储在我的 VBO 中。 这将是最难的解决方案,而且它必须更容易。 每个渲染调用一次可能需要很长时间才能渲染。

我看到了一个解决方案,其中创建了一个新的 VAO + VBO,其中四边形彼此相邻以适合文本。在那里,他将纹理坐标存储在顶点中。 但这不是很无效吗?我也想更改文本的内容。

有人知道我的问题的好方法吗?

【问题讨论】:

    标签: java opengl fonts render


    【解决方案1】:

    既然您提到了四边形,我假设您正在使用成对的三角形。 Quads 在 OpenGL 规范中早已被弃用。

    要设置渲染,想法是创建一个缓冲区,其中包含许多并排的矩形,每个矩形上都投影有一个字符。正如你所说,这可以使用 VAO+VBO 组合来完成。这是我个人会这样做的方式。

    由于顶点可能具有不同的纹理坐标而不是共享相同的坐标,因此您确实需要分别使用纹理坐标定义每个顶点。这确实不是低效的。这是由于OpenGL中渲染过程的实现方式造成的。

    渲染文本的方式是使用glBindTexture() 绑定字体纹理。接下来,您使用glBindVertexArray() 绑定您的VAO,最后使用单个glDrawElements() 调用绘制它。因此,无论您需要多少文本,您只需发出一个 drawcall。

    这里重要的是尽量减少发出的绘制调用次数。绘图调用相对昂贵,因此适当地最小化它们是要走的路。这就是实例渲染存在的原因;多次绘制完全相同的对象,而不会产生太多的绘制调用开销。但是,在这种情况下,最好将所有内容都放在一个缓冲区中并发出一个绘制调用来绘制它。

    【讨论】:

    • 感谢您的快速回复。我将使用您描述的方法:)
    • 实际上,您现在应该使用 VAO+VBO 组合绘制所有几何图形。这确实是有效绘制几何图形的最佳方式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多