Rud*_*udi 12 opengl fbo framebuffer glreadpixels pbo
我可以使用像素缓冲区对象(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
Run Code Online (Sandbox Code Playgroud)
以下glReadPixels工作正常
glReadPixels(0, 0, screenWidth, screenHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE, (uchar*)cvimg->imageData);
Run Code Online (Sandbox Code Playgroud)
以下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
Run Code Online (Sandbox Code Playgroud)
Chr*_*ica 10
当使用PBO作为目标时,glReadPixels您必须指定缓冲区中的字节偏移量(0我猜),而不是(uchar*)cvimg->imageData目标地址.它类似于在glVertexPointer使用VBO时使用缓冲区偏移量.
编辑:当PBO绑定到时GL_PIXEL_PACK_BUFFER,最后一个参数glReadPixels不被视为指向系统内存的指针,而是作为绑定缓冲区内存的字节偏移量.因此,将像素写入缓冲区只需传递0(将它们写入缓冲存储器的开头).然后,您可以通过以下方式访问缓冲存储器(以获取像素)glMapBuffer.您在评论中提供的示例链接也是这样做,只是广泛阅读.我还建议阅读他们在开始时提到的关于顶点缓冲对象的部分,因为这些对于理解缓冲对象是有意义的.
是的,我们可以一起使用FBO和PBO.
答案1:
对于同步读取:没有PBO的'glReadPixels'很快.
对于异步读取:具有2/n PBO的'glReadPixels'更好 - 一个用于通过GPU读取帧缓冲到PBO(n)的像素,而另一个PBO(n + 1)用于通过CPU处理像素.然而,快速不被授予,它是问题和设计spefic.
答案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);
Run Code Online (Sandbox Code Playgroud)