如果我将绘图目标作为后台缓冲区调用glDrawElements
,然后我调用glReadPixels
,是否可以保证我会读取绘制的内容?
换句话说,glDrawElements
是阻止通话吗?
注意:我在这里观察到一个奇怪的问题,可能是因glDrawElements
没有阻塞而造成的......
答案 0 :(得分:8)
换句话说,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可以为此提供帮助。