OpenGL读取帧缓存数据
简述
有些时候我们可能需要获取渲染后的图像数据,比较常用的函数是glReadPixels,它可以直接把显存中的数据拷贝到内存中
有些时候我们可能需要获取渲染后的图像数据,比较常用的函数是glReadPixels,它可以直接把显存中的数据拷贝到内存中
glReadPixels读取帧缓存数据
void glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels) 功 能:读取帧缓存数据 参 数: x,y帧缓存左下角的坐标 width, height读取帧缓存的款和高 format读取的数据格式 type 读取的数据类型 pixels存储读取到数据的内存空间 |
使用方法
float* data = (float*)malloc(mWidth * mHeight * sizeof(float)* 3);
glReadPixels(0, 0, mWidth, mHeight, GL_RGB, GL_FLOAT, data);
这种方式比较简单,只需要分配好内存空间,然后调用glReadPixels,
把数据读取到内存空间就可以了,但这种读取方式效率太低,
当我们需要每帧实时读取时,画面就会出现卡顿,我们需要使用更快的读取方式,比如通过内存映射
float* data = (float*)malloc(mWidth * mHeight * sizeof(float)* 3);
glReadPixels(0, 0, mWidth, mHeight, GL_RGB, GL_FLOAT, data);
这种方式比较简单,只需要分配好内存空间,然后调用glReadPixels,
把数据读取到内存空间就可以了,但这种读取方式效率太低,
当我们需要每帧实时读取时,画面就会出现卡顿,我们需要使用更快的读取方式,比如通过内存映射
内存映射方式读取帧缓存数据
直接调用glMapBuffer从帧缓存中映射时,发现映射失败,这是因为glMapBuffer只能从glGenBuffers创建的缓存中读取数据,我们从帧缓存(由glGenFramebuffers创建)中映射自然失败,所以必须先从帧缓存中把数据读取到顶点缓存中,然后再通过
直接调用glMapBuffer从帧缓存中映射时,发现映射失败,这是因为glMapBuffer只能从glGenBuffers创建的缓存中读取数据,我们从帧缓存(由glGenFramebuffers创建)中映射自然失败,所以必须先从帧缓存中把数据读取到顶点缓存中,然后再通过
使用方法
(1)创建顶点缓存,glGenBuffers(1, &readBuffer);
glBindBuffer(GL_ARRAY_BUFFER, readBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * FRAME_WIDTH * FRAME_HEIGHT * 3, NULL, GL_DYNAMIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, readBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * FRAME_WIDTH * FRAME_HEIGHT * 3, NULL, GL_DYNAMIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
(2)把帧缓存数据读取到顶点缓冲readBuffer
//缓存绑定
glBindBuffer(GL_PIXEL_PACK_BUFFER, readBuffer);
//输出到readBuffer上
glReadPixels(0, 0, FRAME_WIDTH, FRAME_HEIGHT, GL_RGB, GL_FLOAT, NULL);
//缓存绑定
glBindBuffer(GL_PIXEL_PACK_BUFFER, readBuffer);
//输出到readBuffer上
glReadPixels(0, 0, FRAME_WIDTH, FRAME_HEIGHT, GL_RGB, GL_FLOAT, NULL);
(3)把readBuffer中的数据映射到内存中
//映射
float *data = (float *)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
//完成后解除映射
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
//映射
float *data = (float *)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
//完成后解除映射
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);