转VBO, PBO与FBO
Posted 泉_哥
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了转VBO, PBO与FBO相关的知识,希望对你有一定的参考价值。
PBO,即Pixel Buffer Object也是用于GPU的扩展()。这里的缓存当然就是GPU的缓存。PBO与VBO扩展类似,只不过它存储的是像素数据而不是顶点数据。PBO借用了VBO框架和所有API函数形式,并加了上两个"target"标志。这两个标识是:
这里的“pack”还是“unpack”,可分别理解为“传给”和“得到”。它们也都可以统一理解为“拷贝”,也就是像素数据的“”。
图1 opengl PBO
图2 不使用PBO的纹理载入
图3 使用PBO的纹理载入
生成PBO
映射PBO
____________________________________________________
Demo
例子程序pboUnpack.zip使用了不同方式来比较将纹理传给OpenGL的模式:
使用一个PBO; 使用两个PBO; 不使用PBO;
通过按空格键,可以不同模式间切换。
在PBO模式下,每帧的纹理源(像素)都是在映射PBO状态下直接写进去的。再通过调用glTexSubImage2D将PBO中的像素传递给纹理对象。通过使用纹理对象可以在PBO和纹理对象间进行异步DMA传递。它能大大提高像素传递的性能。
由于glTexSubImage2D立即返回,因此CPU能够直接进行其它工作,无需等待实际的像素传递。
图4 两个PBO更新纹理
为了将像素传递的性能最大化,可以使用多个PBO对象。图4中表明同时使用了两个PBO。在glTexSubImage2D将像素数据从PBO拷贝出来的同时,另一份像素数据写进了另一个PBO。
在第n帧时,PBO1用于glTexSubImage2D,而PBO2用于生成一个新的纹理对象了。再到n+1帧时,两个PBO则互换了角色。由于异步DMA传递,像素数据的更新和拷贝过程可同时进行,即CPU将纹理源更新到PBO,同时GPU将从另一PBO中拷贝出纹理。
例子程序pboPack.zip从窗口的左边读出(pack)像素数据到PBO,在更改它的亮度后,把它在窗口的右边绘制出来。通过按空格键,可以看glReadPixels的性能。
传统使用glReadPixels将阻塞渲染管道(流水线),直到所有的像素数据传递完成,才会将控制权交还给应用程序。相反,使用PBO的glReadPixels可以调度异步DMA传递,能够立即返回而不用等待。因此,CPU可以在OpenGL(GPU)传递像素数据的时候进行其它处理。
例子程序也使用了两个PBO,在第n帧时,应用帧缓存读出像素数据到PBO1中,同时在PBO中对像素数据进行处理。读与写的过程可同时进行,是因为,在调用glReadPixels时立即返回了,而CPU立即处理PBO2而不会有延迟。在下一帧时,PBO1和PBO2的角色互换。
参考文章
1. http://www.songho.ca/opengl/gl_pbo.html
2. http://hacksoflife.blogspot.com/2006/10/vbos-pbos-and-fbos.html
3. http://www.paulsprojects.net/opengl/rtotex/rtotex.html
以上是关于转VBO, PBO与FBO的主要内容,如果未能解决你的问题,请参考以下文章
OpenGL ES之深入解析PBOUBO与TBO的功能和使用
Android OpenGL 1.1 FBO 和 VBO 支持
SDL2 OpenGL C++ 移动使用 VBO 和 FBO 绘制的精灵