【问题标题】:Making glReadPixel() run faster使 glReadPixel() 运行得更快
【发布时间】:2013-11-14 18:44:25
【问题描述】:

我想要一种非常快速的方法来为我的应用程序捕获 openGL 帧缓冲区的内容。通常,glReadPixels() 用于将帧缓冲区的内容读入缓冲区。但这很慢。

我试图通过创建 4 个线程使用 glReadPixels() 从 4 个不同区域读取帧缓冲区来并行化读取帧缓冲区内容的过程。但是由于分段错误,应用程序正在退出。如果我从线程中删除 glReadPixels() 调用,则应用程序运行正常。

【问题讨论】:

  • 之后你想对这些像素做什么?你检查过 FramebufferObjects 吗?
  • 从 FBO 读取到缓冲区也需要调用 glReadPixels()

标签: opengl


【解决方案1】:

线程不起作用,弃权。

如您所见,创建多个线程会失败,因为只有一个线程具有当前的 OpenGL 上下文。原则上,您可以在调用glReadPixels 之前使每个工作线程中的上下文成为当前的,但这需要您进行额外的同步(否则,线程可能会在使上下文成为当前和回读!),而(wgl|glx)MakeCurrent 是一个非常慢的函数,会严重阻碍 OpenGL。最后,你会做更多的工作来获得更慢的速度

没有办法让glReadPixels 更快1,但你可以解耦它所花费的时间(即读回异步运行),所以它不会阻塞你的应用程序并且有效地似乎运行“更快”。
您想为此使用Pixel buffer object。确保缓冲区标志正确。

请注意,如果完整的内容尚未完成传输,则映射缓冲区以访问其内容将仍然阻塞,因此它仍然不会更快。考虑到这一点,您要么必须阅读前一帧,要么使用可以查询的栅栏对象以确保它已完成。
或者,更简单但不太可靠,您可以在glReadPixels 和访问数据之间插入“一些其他工作”。这不能保证在您访问数据时传输已经完成,因此它可能仍会阻塞。然而,它可能只是工作,它会可能阻塞更短的时间(因此运行“更快”)。


1 有很多方法可以使其变慢,例如如果您要求 OpenGL 进行一些奇怪的转换,或者您使用了错误的缓冲区标志。然而,一般来说,没有办法让它更快,因为它的速度取决于所有先前的绘制命令在传输开始之前已经完成,以及通过 PCIe 总线传输的数据(它具有固定的时间开销加上有限的带宽) .
使回读“更快”的唯一可行方法是隐藏这种延迟。当然,它仍然没有更快,但你不会感觉到它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-11-28
    • 1970-01-01
    • 1970-01-01
    • 2011-05-10
    • 1970-01-01
    • 2015-10-19
    • 2011-04-30
    • 1970-01-01
    相关资源
    最近更新 更多