方法一:glReadPixels
首先创建一个fbo,绑定fbo后,attach上需要操作的texture,再进行读取。
if(fbo == 0)
{
glGenFramebuffers(1, &fbo);
}
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureID, 0);
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, dataPointer);
方法二: glGetTexImg
也是比较简单,bind需要读取的texture后,就可以直接调用glGetTexImg进行读取
glBindTexture(GL_TEXTURE_2D, textureID);
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, dataPointer);
glBindTexture(GL_TEXTURE_2D, 0);
方法三:使用pbo
使用pbo是最复杂的,但是比前两种要快。只使用一个pbo的话,也就是同步,比glReadpixel快那么一点点,但是如果使用多个pbo进行异步读取,呵呵,那就快了几百倍了。
首先初始化的时候,可生成两个pbo
GLuint pbo[2];
//creates PBOs to hold the data, this allocates memory for them too
glGenBuffers(2, pbo);
glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo[0]);
glBufferData(GL_PIXEL_PACK_BUFFER, height* width, 0, GL_STREAM_READ);
glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo[1]);
glBufferData(GL_PIXEL_PACK_BUFFER, height* width, 0, GL_STREAM_READ);
//unbind buffers for now
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
然后创建fbo
if(fbo == 0)
{
glGenFramebuffers(1, &fbo);
}
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureID, 0);
接下来就是fbo的异步处理了
writeIndex = (writeIndex + 1) % 2;
readIndex = (readIndex + 1) % 2;
//bind FBO to read pixels. This buffer is being compied from GPU to CPU memory
glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo[writeIndex]);
//copy from framebuffer to FBO asynchronously. it will be ready in the Next Frame
glReadPixels(0,0 ,width, height, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
//now read other FBO which should be already in CPU memory
glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo[readIndex]);
//map buffer so we can access it
cpixel = (unsigned char *)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
if (cpixel)
{
// ok we have the data now avaliable and could process it or copy it somewhere
// ...
// unmap the buffer again
memcpy(dataPointer,cpixel,height * width);
//cpixel = nullptr;
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
}
//back to conventional pixel operation
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
三种方法介绍完了,其实还有很多其他的写法。第一次分享,嘻嘻~
转载请注明出处,谢谢!