使glReadPixel()运行得更快

Ank*_*jay 3 opengl

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

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

Dam*_*mon 7

线程不起作用,弃用该方法.

正如您所注意到的,创建多个线程失败,因为只有一个线程具有当前的OpenGL上下文.原则上,您可以在调用之前使每个工作线程中的上下文glReadPixels变为当前,但这需要您身边的额外同步(否则,在创建上下文当前和读回之间可以抢占一个线程!),并且(wgl|glx)MakeCurrent速度非常慢将严重阻碍OpenGL的功能.最后,你会做更多的工作来获得更慢的东西.

没有办法让glReadPixels任何更快的1,但你可以解耦它所花费的时间(即回读以异步方式运行),因此它不会阻止你的应用程序并且实际上似乎 "更快"地运行.
您想要使用Pixel缓冲区对象.一定要确保缓冲区标记正确.

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


1有很多方法可以让它变慢,例如,如果你要求OpenGL做一些奇怪的转换,或者你使用错误的缓冲区标志.但是,通常情况下,没有办法让它更快,因为它的速度取决于在传输甚至可以启动之前完成的所有先前的绘制命令,并且数据通过PCIe总线传输(具有固定的时间开销加上有限的带宽) .
使回读"更快"的唯一可行方法是隐藏这种延迟.它当然仍然不会更快,但你感觉不到它.