以下为几种数据拷贝方式:
(1)glCopyPixels 直接将屏幕像素拷贝到framebuffer,没有经过内存,严格来说不算拷贝texture方式
(2)glReadPixels 从帧缓存中读取一个像素块到内存data中, 可以结合FBo使用
(3)glGetTexImage()根据纹理Id,读取数据到内存
(1)glGetTeImage使用比较方便:但是速度较慢。
exp1:获取指定Id的纹理数据
unsigned char* output_image = new unsigned char[M_WIDTH * M_HEIGHT * 3];
glBindTexture(GL_TEXTURE_2D, texture_ID);
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, output_image);
exp2:获取纹理再拷贝
unsigned char* output_image = new unsigned char[M_WIDTH * M_HEIGHT * 3];
glBindTexture(GL_TEXTURE_2D, src_id);
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, output_image);
glBindTexture(GL_TEXTURE_2D, dest_id);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, M_WIDTH ,M_HEIGHT , GL_RGB, GL_UNSIGNED_BYTE, output_image);
glBindTexture(GL_TEXTURE_2D, 0);
此时数据保存到output_image 中, 可以另存成图片文件
但是Opengl ES 不支持。
(2)FBO拷贝
GLuint fbo
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, src_id, 0);
glBindTexture(GL_TEXTURE_2D, dest_id);
(3)glReadPixels 是从framebuffers里面读,而不是texture,但是可以借助FBO,可以绑定到FBO,然后从FBO用glReadPixels读取
glGenFramebuffers(1, &offscreen_fbo);
glBindFramebuffer(GL_FRAMEBUFFER, offscreen_fbo);
//创建tex
glGenTextures(1, &my_texture);
glBindTexture(GL_TEXTURE_2D, my_texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHEMENT0, GL_TEXTURE_2D, my_texture, 0);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if(status != GL_FRAMEBUFFER_COMPLETE){
printf("failed %x", status);
}
//
glBindFramebuffer(GL_FRAMEBUFFER, offscreen_fbo);
glViewport(0, 0, width, height);
GLubyte* pixels = (GLubyte*) malloc(width * height * sizeof(GLubyte) * 4);
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
//
glBindFramebuffer(GL_FRAMEBUFFER, sceen_framebuffer);
glViewPort(0, 0, screen_width, screen_height);