OpenGL: 渲染字体的批处理操作

一、问题描述

在OpenGL中,绘制字体通过纹理贴图的方式。一个场景中有200个单词,按照正常做法:一个单词生成一个贴图,指定Quad四个顶点纹理坐标,最后把数据传给OpenGL,进行绘制。

OpenGL顶点数组是客户端-服务器模式:客户端是当前应用程序;服务器端包含三部分:链接到应用程序中的OpenGL库、在操作系统内核中的OpenGL驱动、以及GPU。

绘制200个单词中,每个单词都需要进行两次数据传输:

  • 将保存在内存中的顶点数据,通过CPU 上传给 服务器端缓存中。
  • 将保存爱内存中的纹理数据,通过CPU 上传给 服务器端缓存中。
如果设备(PC/Mobile)上有GPU,则数据传输次数越多,GPU的利用率越低。(参见 Batch,Batch,Batch文档)

二、解决方案

使用批处理的思想 ,在OpenGL中批量处理字体, 减少Draw Call次数,减少OpenGL的状态改变,只要不超过硬件处理能力,每次CPU给GPU传输的数据块越大越好。英文字体比较易于处理,可以预先把26个字符全部保存到一张图片中,如果程序中有不同尺寸的字体,可以把各个尺寸下所有字母 数字保存到图片中,程序启动时候 一次传给OpenGL,绘制每个字母时,需要获取该字母在纹理中的纹理坐标,然后计算字母四个角的顶点位置,把场景中所有字母 的纹理和位置数据 全部保存到一个vertex_buffer中,最后调用 一次  glDrawElements函数 绘制。

为了加速顶点数据传输,可以采用 VBO技术,顶点数组模式下顶点数据在客户端,每次绘制时将数据传给服务器,而Vertex buffer object是在服务器,客户端要修改vbo中的数据时,必须先将服务器端的缓存映射到客户端。因为VBO是在服务器端,所以绘制时 OpenGL直接从VBO中取数据,效率更高。

三、实例

google code上开源项目freetype进行了不错的尝试。http://code.google.com/p/freetype-gl/

freetype-gl :A quick OpenGL/Freetype example for displaying a unicode text using a (single) vertex buffer. The idea is simply to tightly pack every necessary glyphs into a single texture and to generate a single vertex buffer to draw the text. 


参考文献:

1. Batch, Batch, Batch:” What Does It Really Mean

2. OpenGL Vertex Buffer Object :http://www.songho.ca/opengl/gl_vbo.html

你可能感兴趣的:(OpenGL)