OpenGL 渲染字体实例化

OpenGL render fonts instanced

我想用 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,其中四边形彼此相邻以适合文本。他在那里将纹理坐标存储在顶点中。 但这不是很无效吗?我也想更改我的文字内容

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

既然你提到四边形,我假设你正在处理成对的三角形。 OpenGL 规范早就弃用了四边形。

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

由于顶点可能具有不同的纹理坐标而不是共享相同的纹理坐标,因此您确实需要单独定义每个顶点的纹理坐标。这真的不是低效的;这是在 OpenGL 中实现渲染过程的方式所必需的。

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

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