线程不起作用,请放弃这种方法。
正如您所注意到的,创建多个线程会失败,因为只有一个线程具有当前的 OpenGL 上下文。原则上,你could在调用之前使上下文在每个工作线程中处于当前状态glReadPixels
,但这需要您进行额外的同步(否则,在使上下文成为当前上下文和读回之间,线程可能会被抢占!),并且(wgl|glx)MakeCurrent
是一个非常慢的函数,会严重阻碍 OpenGL。最后,你会做更多的工作得到很多东西slower.
There is no way to make glReadPixels
any faster1, but you can decouple the time it takes (i.e. the readback runs asynchronously), so it does not block your application and effectively appears to run "faster".
You want to use a Pixel buffer object for that. Be sure to get the buffer flags correct.
请注意,映射缓冲区以访问其内容将still如果完整的内容还没有完成传输,则阻塞,所以它会still不会再快了。为了解决这个问题,您要么必须读取前一帧,要么使用可以查询的栅栏对象以确保它已完成。
或者,更简单但不太可靠,您可以在两者之间插入“一些其他工作”glReadPixels
并访问数据。这不能保证在您访问数据时传输已完成,因此它可能仍会阻塞。然而,它may只要工作,它就会likely阻塞时间较短(因此运行“更快”)。
1 There are plenty of ways of making it
slower, e.g. if you ask OpenGL to do some weird conversions or if you use wrong buffer flags. However, generally, there's no way to make it faster since its speed depends on all previous draw commands having finished before the transfer can even start, and the data being transferred over the PCIe bus (which has a fixed time overhead plus a finite bandwidth).
The only viable way of making readbacks "faster" is hiding this latency. It's of course still not faster, but you don't get to feel it.