我可以使用像素缓冲区对象(PBO)直接从FBO读取像素值(即使用glReadPixels)(即当FBO仍然连接时)?
如果是,
{
//DATA_SIZE = WIDTH * HEIGHT * 3 (BECAUSE I AM USING 3 CHANNELS ONLY)
// FBO and PBO status is good
.
.
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId);
//Draw the objects
以下glReadPixels工作正常
glReadPixels(0, 0, screenWidth, screenHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE, (uchar*)cvimg->imageData);
以下glReadPixels无效:(
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboId);
//yes glWriteBuffer has also same target and I also checked with every possible values
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
glReadPixels(0, 0, screenWidth, screenHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE, (uchar*)cvimg->imageData);
.
.
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); //back to window framebuffer
答案 0 :(得分:10)
当使用PBO作为glReadPixels
的目标时,您必须指定缓冲区(0
,而不是(uchar*)cvimg->imageData
)作为目标地址的字节偏移量。它类似于在使用VBO时在glVertexPointer
中使用缓冲区偏移量。
编辑:当PBO绑定到GL_PIXEL_PACK_BUFFER
时,glReadPixels
的最后一个参数不被视为指向系统内存的指针,而是作为字节偏移量进入系统内存绑定缓冲区的内存。因此,将像素写入缓冲区只需传递0(将它们写入缓冲存储器的开头)。然后,您可以通过glMapBuffer
访问缓冲存储器(以获取像素)。您在评论中提供的示例链接也是这样做,只是广泛阅读。我还建议阅读他们在开始时提到的关于顶点缓冲区对象的部分,因为这些对于理解缓冲区对象是基础。
答案 1 :(得分:8)
是的,我们可以一起使用FBO和PBO。
回答1:
对于同步阅读:没有PBO的'glReadPixels'很快。
对于异步读取:'glReadPixels'具有2 / n PBO更好 - 一个用于通过GPU读取帧缓冲到PBO(n)的像素和另一个PBO(n + 1)来处理像素中央处理器。然而,快速没有被授予,这是问题和设计的特点。
回答2:
Christian Rau的解释是正确的,修改后的代码在下面
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboId);
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
//glReadBuffer(GL_DEPTH_ATTACHMENT_EXT);
glReadPixels(0, 0, screenWidth, screenHeight, GL_BGR, GL_UNSIGNED_BYTE, 0);
//GLubyte* src = (GLubyte*)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY_ARB);
//OR
cvimg->imageData = (char*) glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY_ARB);
if(cvimg_predict_contour->imageData)
{
//Process src OR cvim->imageData
glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB); // release pointer to the mapped buffer
}
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);