opengl - 带有 PBO 的异步 glReadPixels

标签 opengl glreadpixels pbo

我想使用两个 PBO 以替代方式读取像素。我认为PBO方式会快很多,因为glReadPixels在使用PBO时会立即返回,并且很多时间可以重叠。

奇怪的是,似乎没有太大的好处。考虑一些代码,如:

    glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
    Timer t; t.start();
    glReadPixels(0,0,1024,1024,GL_RGBA, GL_UNSIGNED_BYTE, buf);
    t.stop(); std::cout << t.getElapsedTimeInMilliSec() << " ";

    glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pbo);
    t.start();
    glReadPixels(0,0,1024,1024,GL_RGBA, GL_UNSIGNED_BYTE, 0);
    t.stop(); std::cout << t.getElapsedTimeInMilliSec() << std::endl;

结果是
1.301 1.185
1.294 1.19
1.28 1.191
1.341 1.254
1.327 1.201
1.304 1.19
1.352 1.235

PBO方式稍微快一点,但不是令人满意的立即返回

我的问题是:
  • 影响 glReadPixels 性能的因素是什么?有时,它的成本达到 10 毫秒,但这里是 1.3 毫秒。
  • 为什么立即返回 成本高达1.2ms?是太大还是正常?

  • ================================================== ==========================

    通过和一个demo对比,我发现了两个因素:
  • GL_BGRA 优于 GL_RGBA,1.3ms=>1.0ms(无 PBO),1.2ms=>0.9ms(有 pbo)
  • glutInitDisplayMode(GLUT_RGB|GLUT_ALPHA) 而不是 GLUT_RGBA,0.9ms=>0.01ms。 这就是我想要的性能。在我的系统中,GLUT_RGBA=GLUT_RGB=0。 GLUT_ALPHA=8

  • 然后还有两个问题:
  • 为什么 GL_BGRA 比 GL_RGBA 好?是针对特定平台还是针对所有平台?
  • 为什么 GLUT_ALPHA 如此重要以至于它会极大地影响 PBO 性能?
  • 最佳答案

    不知道glutInitDisplayMode记住,但这通常是因为您的内部和外部格式不匹配。例如,当组件数量不匹配时,您不会注意到异步行为,因为此转换仍会阻止 glReadPixels .

    所以最有可能的问题是 glutInitDisplay(GLUT_RGBA)您实际上将创建一个默认帧缓冲区,其内部格式实际上是 RGB甚至 BGR .路过 GLUT_ALPHA参数很可能使它RGBABGRA在内部,它与您想要的组件数量相匹配。

    编辑:我发现了一个 nvidia document解释有关像素打包和性能影响的一些问题。

    edit2:BGRA 的性能提升可能是因为内部硬件缓冲区在 BGRA ,没有更多了。

    关于opengl - 带有 PBO 的异步 glReadPixels,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11409693/

    相关文章:

    java - 我在使用 open gl 和 glfw (LWJGL) 将模型渲染到窗口时遇到问题

    c++ - 在 Opengl 中渲染。重叠对象

    c++ - 将立方体的纹理区域与当前 Oculus 视口(viewport)相关联

    c++ - 使用 PBO 上传 OpenGL 纹理?

    c++ - PBO 的竞争条件

    c++ - 为什么我的法线不能在顶点之间进行插值,从而产生平面着色效果?

    iphone - glReadPixels 仅在 iOS 7 设备上提供黑色图像

    ios - screenShot 代码在 ipad 上不起作用,在 iphone 上起作用

    ios - 使用 glReadPixels 读取 Tap Point 的值? OpenGL 2.0 iOS

    c++ - glUnmapBuffer 同时保持 glMapBuffer 内存有效为只读