3

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

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

4

1 回答 1

8

线程不起作用,弃权该方法。

正如您所注意到的,创建多个线程会失败,因为只有一个线程具有当前的 OpenGL 上下文。原则上,您可以在调用之前使每个工作线程中的上下文处于当前状态glReadPixels,但这需要您进行额外的同步(否则,线程可能会在使上下文处于当前状态和回读之间被抢占!),而且(wgl|glx)MakeCurrent速度非常慢会严重停止 OpenGL 的函数。最后,你会做更多的工作来获得慢得多的东西。

没有办法使glReadPixels任何更快1,但您可以解耦它所花费的时间(即回读异步运行),因此它不会阻止您的应用程序并且实际上看起来运行“更快”。
您想为此使用Pixel 缓冲区对象。确保缓冲区标志正确。

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


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

于 2013-11-14T10:34:56.733 回答