使用像素缓冲区对象 (PBO) 从帧缓冲区对象 (FBO) 读取像素值

发布于 2024-11-10 03:04:04 字数 974 浏览 4 评论 0原文

我可以使用像素缓冲区对象 (PBO) 直接从 FBO 读取像素值(即使用 glReadPixels)(即当 FBO 仍连接时)?

如果是,

  1. 将 PBO 与 FBO 结合使用有何优点和缺点?
  2. 以下代码有什么问题

{

//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

Can I use Pixel Buffer Object (PBO) to directly read the pixels values (i.e. using glReadPixels) from the FBO (i.e. while FBO is still attached)?

If yes,

  1. What are the advantages and disadvantages of using PBO with FBO?
  2. What is the problem with following code

{

//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

Following glReadPixels works fine

glReadPixels(0, 0, screenWidth, screenHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE,  (uchar*)cvimg->imageData);

Following glReadPixels DOES NOT WORK :(

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不…忘初心 2024-11-17 03:04:04

当使用 PBO 作为 glReadPixels 的目标时,您必须指定缓冲区中的字节偏移量(我想是 0),而不是 (uchar*)cvimg-> ;imageData 作为目标地址。它类似于使用 VBO 时在 glVertexPointer 中使用缓冲区偏移量。

编辑:当 PBO 绑定到 GL_PIXEL_PACK_BUFFER 时,glReadPixels 的最后一个参数不会被视为指向系统内存的指针,而是被视为一个字节绑定缓冲区内存中的偏移量。因此,要将像素写入缓冲区,只需传递 0(将它们写入缓冲区内存的开头)。然后您可以稍后通过 glMapBuffer 访问缓冲区内存(以获取像素)。您在评论中提供的示例链接也可以做到这一点,只需广泛阅读即可。我还建议阅读他们在开始时提到的有关顶点缓冲区对象的部分,因为这些为理解缓冲区对象奠定了基础。

When using a PBO as target for glReadPixels you have to specify a byte offset into the buffer (0, I suppose) instead of (uchar*)cvimg->imageData as target address. It is similar to using a buffer offset in glVertexPointer when using VBOs.

EDIT: When a PBO is bound to the GL_PIXEL_PACK_BUFFER, the last argument to glReadPixels is not treated as a pointer into system memory but as a byte offset into the bound buffer's memory. So to write the pixels into the buffer just pass a 0 (write them to the start of the buffer memory). You can then later acces the buffer memory (to get the pixels) by means of glMapBuffer. The example link you provided in your comment does that, too, just read it extensively. I also suggest reading the part about vertex buffer objects they mention at the start, as these lay the ground to understand buffer objects.

妄司 2024-11-17 03:04:04

是的,我们可以一起使用FBO和PBO。

答案 1:

对于同步读取: 没有 PBO 的“glReadPixels”速度很快。

对于异步读取: 具有 2/n PBO 的“glReadPixels”更好 - 一个用于通过 GPU 将像素从帧缓冲区读取到 PBO (n),另一个 PBO (n+1) 用于通过 CPU 处理像素。然而,速度并不是理所当然的,它是特定于问题和设计的。

答案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);

Yes, we can use FBO and PBO together.

Answer 1:

For synchronous reading: 'glReadPixels' without PBO is fast.

For asynchronous reading: 'glReadPixels' with 2/n PBOs is better- one for reading pixels from framebuffer to PBO (n) by GPU and another PBO (n+1) to process pixels by CPU. However fast is not granted, it is problem and design spefic.

Answer 2:

Christian Rau's explanation is correct and revised code is below

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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文