从GPU读取数据到系统内存的三种方式

方法一: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);

三种方法介绍完了,其实还有很多其他的写法。第一次分享,嘻嘻~

转载请注明出处,谢谢!

猜你喜欢

转载自blog.csdn.net/qingsebianbaifa/article/details/81095131
今日推荐