使用OpenGL ES渲染动态位图字体的最佳方法

时间:2013-04-28 20:56:58

标签: android opengl-es

我一直在Android上进行一些游戏开发,并且只需使用GL扩展库中的glDrawTexfOES方法就可以完成大部分绘图。使用它来绘制我的精灵似乎产生了良好的性能,直到我开始尝试将它用于位图字体之前我没有任何抱怨。

通过我现在设置位图字体的方式,我从XML文件中读取字符定义,纹理和字符属性,以便初始化我的字体类。使用这些属性,调用glDrawTexfOES并进行格式化,以便绘制所请求的字符并将其缩放到所需的大小。这适用于较小的字符串,但不幸的是,对于绘制的每个字符,都需要单独调用glDrawTexfOES。可以想象,这会导致更大的字符串出现明显的延迟和性能问题。

有没有人有关于如何更智能地渲染这个的建议?我听说过将VBO用于大型静态对象组,但我不确定这些是否适合于需要动态文本的用例。来自使用OpenGL ES实现类似功能的人的建议将不胜感激。

1 个答案:

答案 0 :(得分:0)

有几种方法可以提高代码的redering速度。 glDrawTexfOES的文档没有提供很多细节,只提到了纹素到片段的直接映射,所以我最好的猜测是你使用的实现不是很优化,而且是你速度问题的主要原因(我是假设您正在使用OpenGL ES 1.1)。

我的建议是摆脱glDrawTexfOES并用自定义渲染功能替换它,使用三角形条和degenerate triangles来连接不同的条带。

它的工作原理如下:

1)创建一个缓冲区来存储顶点位置,纹理坐标和索引,以便在一个批处理中绘制三角形。每个字母将使用两个三角形绘制,并使用(或忽略)另一个退化三角形将其连接到另一个字母。

2)使用以下算法创建退化三角形:

for (int k = 0; k < MAX_NUMBER_OF_LETTERS ; k++)
{
    indices[k*6] = k*4;

    for (int p=0; p<4; p++)
        indices[k*6+p+1] = k*4+p;

    indices[k*6+5] = k*4+3;
}

3)将所有绘制调用批处理到在步骤1中创建的缓冲区。您可以使用glDrawArrays将三角形发送到渲染管道。您可以根据需要批量生成三角形,加速渲染的技巧是保持对glDrawArrays的调用,直到OpenGL的状态发生变化(比如更改绑定纹理)。

4)你显然需要使用texture atlas

如果您正在做一些基本的2D内容,我还建议不要做VBO。走这条路线意味着将代码更改为OpenGL ES 2.0而不是1.1,它们完全不同。