OpenGL读取像素的速度比glReadPixels快

OpenGL读取像素的速度比glReadPixels快,opengl,Opengl,有没有办法提高glReadPixels的速度?目前我有: Gdx.gl.glReadPixels(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), GL20.GL_RGBA, GL20.GL_UNSIGNED_BYTE, pixels); 问题是它会阻止渲染,并且速度较慢 我听说过像素缓冲区对象,但我很不确定如何连接它,以及它是否更快 除此之外,还有其他解决方案吗 基本上,我希望尽可能快地拍摄一张截图,而不妨碍下一个场景的绘制 有

有没有办法提高glReadPixels的速度?目前我有:

Gdx.gl.glReadPixels(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), GL20.GL_RGBA, GL20.GL_UNSIGNED_BYTE, pixels);
问题是它会阻止渲染,并且速度较慢

我听说过像素缓冲区对象,但我很不确定如何连接它,以及它是否更快

除此之外,还有其他解决方案吗

基本上,我希望尽可能快地拍摄一张截图,而不妨碍下一个场景的绘制

有没有办法提高glReadPixels的速度

嗯,那次行动的速度其实不是主要问题。它必须将一定数量的字节从帧缓冲区传输到系统内存。在典型的带有离散GPU的桌面系统中,这涉及到通过PCI Express发送数据,而这是无法避免的

但是正如您已经说过的,隐式同步是一个大问题。如果您需要尽快获得像素数据,那么您真的没有比同步回读更好的了。但是,如果您可以接受以后获取该数据,那么通过像素缓冲区对象(PBO)进行异步回读是一个不错的选择

其伪代码为:

  • 创建PBO
  • 将PBO绑定为
    GL\u像素\u块\u缓冲区
  • 执行
    glReadPixels
  • 做点别的。在CPU上工作和为GPU发出新命令都是理想的
  • 通过使用
    glGetBufferSubData
    或映射PBO以进行读取,从PBO读回数据

  • 关键点是第5步的时间安排。如果你这么做很早,你仍然会阻塞客户端,因为它会等待数据变得可用。对于一些截图,即使是一两帧,也不难延迟这一步。这样,它只会对整体渲染性能产生轻微影响,并且不会使GPU或CPU暂停。

    PBOs肯定会更快,因为您可以调用
    glReadPixels
    读取PBO,然后绘制帧,直到命令完成。您需要一个同步对象来确定PBO何时已完全写入。与
    glReadPixels
    性能相关:PBO的良好起点:您可以使用同步对象来查询操作是否通过在glReadPixels之后立即执行glFenceSync并在超时为0的情况下检查glClientWaitSync来完成。是否需要一些代码创建并绑定PBO,并使用
    glGetBufferSubData
    读取它。我有点迷恋OpenGL。而且Libgdx似乎没有
    Gdx.gl.glGetBufferSubData
    @Niklas:我对Libgdx一无所知。本手册本身有一节介绍使用示例。示例3是异步回读的更高级版本:它们回读两个半图像,并开始处理前半图像,而第二个半图像可能仍在传输。它们还直接映射用于读取的缓冲区,但是如果您想使用
    glGetBufferSubData
    ,则应该解释所有需要的内容。