在某些场合需要快速的将Video Frame stream到GPU texture, 比如要使用GPU渲染从相机过来的帧数据。这时候就可以将数据直接写入pixel unpack buffer object.
OpenGL 支持几种buffer objects, 其中用的最多的大概就是vertex buffer object (VBO) 用来存储顶点相关数据。 创建和绑定buffer object的函数:
void glGenBuffers(GLsizei n, GLuint *buffers);
void glBindBuffer(GLenum target, GLuint buffer);
target
: 可以是以下任一个, 在绑定buffer object之后,下一步就是分配GPU存储空间了:
void glBufferData(GLenum target, GLsizeiptr size,const void *data, GLenum usage);
size
: 缓存大小,单位 bytedata
: 用来初始化缓存的原始数据指针,当为NULL时,缓存不会被初始化,但是空间已经分配。分配好空间的buffer object 可以使用以下函数更新缓存:
void glBufferSubData(GLenum target, GLintptr offset,GLsizeiptr size, const void *data);
我们知道当target
为GL_ARRAY_BUFFER时,我们称这个buffer object 为Vertex Buffer Object(VBO), 本文重点要阐述的则是GL_PIXEL_UNPACK_BUFFER对应于Pixel Buffer Object(PBO),我们在向texture上传/填充数据的时候数据来源可以直接位于GPU中.
PBO作为buffer object, 我们可以通过memory map的方式直接得到PBO的指针:
void* glMapBufferRange(GLenum target,
GLintptr offset,
GLsizeiptr length,
GLbitfield access);
target
: GL_PIXEL_UNPACK_BUFFERoffset
: offset in bytes into the buffer data storelength
: number of bytes of the buffer data to mapaccess
: a bitfield combination of access flags函数所返回的指针可以用来更新PBO的内容。当更新完毕之后我们需要调用相应的unmap函数指示数据更新已经完成并释放指针。
GLboolean glUnmapBuffer(GLenum target);
调用texture填充函数更新texture像素信息:
glTexImage*,
glTexSubImage*,
glCompressedTexImage*,
glCompressedTexSubImage*
当GL_PIXEL_UNPACK_BUFFER绑定有效的PBO时,这些函数都直接从PBO获取数据源,而不用从系统内存上传数据到GPU. 因为数据已经位于GPU,这些函数会立即返回,因此使用这种方式更新texture数据非常高效,当然前提条件是性能非常重要或者内存使用有限制的情况下才应该考虑这种方法!
最后总结一下:
原文地址:http://blog.csdn.net/techx/article/details/44093625