如果我打电话给glDrawElements
,其中抽取目标是后台缓冲区,然后我打电话给glReadPixels
,是否保证我会读取提取的内容?glDrawElements是否在后台缓冲区同步?
换句话说,是glDrawElements
阻止呼叫?
注:我观察这里的奇怪的问题可以通过glDrawElements
没有被阻塞引起...
如果我打电话给glDrawElements
,其中抽取目标是后台缓冲区,然后我打电话给glReadPixels
,是否保证我会读取提取的内容?glDrawElements是否在后台缓冲区同步?
换句话说,是glDrawElements
阻止呼叫?
注:我观察这里的奇怪的问题可以通过glDrawElements
没有被阻塞引起...
换句话说,是glDrawElements阻塞调用?
这不是OpenGL的工作方式。
OpenGL memory model构建于“仿佛”规则上。除了某些例外,everything in OpenGL will function as if all of the commands you issued have already completed。实际上,一切都会像每个命令都被阻塞直到完成一样。
但是,这并不意味着OpenGL实现实际上以这种方式工作。它只需要尽一切努力使出现即可。
因此,glDrawElements
一般不是阻塞呼叫;然而,glReadPixels
(当读到客户端内存时)是阻塞呼叫。因为当返回glReadPixels
时,像素直接传输到客户端内存的结果必须可用,所以实现必须检查是否有任何正在读取的帧缓冲区的渲染命令。如果有,那么它必须阻止,直到这些渲染命令完成。然后它可以执行读取并将数据存储在客户端内存中。
如果您是reading to a buffer object,则不需要glReadPixels
来阻止。由于您正在读入缓冲区对象,所以客户端无法访问的内存将被该函数修改。所以驱动程序可以异步发布回读。但是,如果您发出一些取决于此缓冲区内容的命令(如将其映射为读取或使用glGetBufferSubData
),则OpenGL实现必须停止,直到读取操作完成。
简而言之,OpenGL试图尽可能延迟阻塞。除非绝对必要,否则你的工作,以确保性能,是帮助 OpenGL这样做,而不是forcing an implicit synchronization。 Sync objects可以帮助这一点。