返回
以实力雄辩:“Android OpenGL 渲染图像读取”界独领风骚的解决方案
Android
2023-11-06 04:59:07
OpenGL ES 2.0 和 3.0中的读取图像方式
glReadPixels()函数
glReadPixels() 是 OpenGL ES 的 API ,OpenGL ES 2.0 和 3.0 均支持。 使用非常方便,下面一行代码即可搞定,但是效率也是最低的。 当调用 glReadPixels 时,首先会影响 CPU 时钟周期,同时 GPU 会等待当前帧绘制完成,读取的像素由 glReadPixels() 在绘制操作执行结束后从帧缓冲区中读出。代码如下:
void readPixel(int x, int y, int width, int height, GLint format, GLint type, void * pixels)
通过纹理读取图像
该方法的思路与前面提到的使用glReadPixels()读取帧缓冲区的方式类似,不同之处在于使用纹理缓冲区替代帧缓冲区。使用纹理读取数据,首先必须将数据复制到一个纹理中,然后再通过纹理读取数据,可以将纹理想象成一块内存区域,而纹理对象就是一块内存空间的指针。
通过缓冲区对象读取图像
在OpenGL中,帧缓冲区不仅可以用纹理来创建,还可以使用缓冲区对象(Pixel Buffer Objects,简称PBO)来创建。PBO 是一种特殊的缓冲区,它允许 CPU 和 GPU 同时访问。 通过 PBO 读取数据,分为四个步骤:
- 创建一个 PBO 并绑定它。
- 调用 glReadPixels()将像素从帧缓冲区复制到 PBO。
- 将 PBO 的内容复制到系统内存。
- 解绑 PBO。
Android OpenGL 渲染图像读取方案比较
性能比较
下表是三种读取图像方式的性能比较。
方式 | 优缺点 |
---|---|
glReadPixels() | 最简单,效率最低 |
通过纹理读取图像 | 比glReadPixels()快,但需要额外的内存复制 |
通过缓冲区对象读取图像 | 速度最快,但需要额外的编程开销 |
内存占用比较
下表是三种读取图像方式的内存占用比较。
方式 | 优缺点 |
---|---|
glReadPixels() | 最少 |
通过纹理读取图像 | 比glReadPixels()多,但可以复用 |
通过缓冲区对象读取图像 | 最多,但可以复用 |
易用性比较
下表是三种读取图像方式的易用性比较。
方式 | 优缺点 |
---|---|
glReadPixels() | 最简单 |
通过纹理读取图像 | 比glReadPixels()复杂,但可以复用 |
通过缓冲区对象读取图像 | 最复杂,但可以复用 |
结论
从性能、内存占用和易用性三个方面综合来看,通过缓冲区对象读取图像是最优的方案。它不仅速度最快,而且内存占用最少,易用性也最好。