如果我调用glDrawElementsdraw目标作为后台缓冲区,然后我调用glReadPixels,是否保证我会读取绘制的内容?
换句话说,是glDrawElements阻塞电话吗?
注意:我在这里观察到一个奇怪的问题,可能是由于glDrawElements没有阻塞造成的......
换句话说,glDrawElements是阻塞调用吗?
这不是OpenGL的工作原理.
在OpenGL的内存模型是建立在"好像"规则.除了某些例外,OpenGL中的所有内容都将起作用,就像您发出的所有命令都已完成一样.实际上,一切都会好像每个命令都被阻塞直到它完成.
但是,这并不意味着OpenGL实现实际上是这样工作的.它必须做所有事情才能使它看起来像这样工作.
因此,glDrawElements一般不是阻塞电话; 但是,glReadPixels(当读取到客户端内存时)是一个阻塞调用.因为glReadPixels返回时像素直接传输到客户端内存的结果必须可用,所以实现必须检查是否有任何未完成的渲染命令进入正在读取的帧缓冲区.如果有,则必须阻塞,直到完成这些渲染命令.然后它可以执行读取并将数据存储在客户端内存中.
如果您正在读取缓冲区对象,则无需glReadPixels阻止.由于您正在读取缓冲区对象,因此该函数不会修改客户端可访问的内存.因此驱动程序可以异步发出回读.但是,如果发出一些取决于此缓冲区内容的命令(如将其映射为读取或使用glGetBufferSubData),则OpenGL实现必须停止,直到读取操作完成.
简而言之,OpenGL试图尽可能地延迟阻塞.为确保性能,您的工作是帮助 OpenGL通过不强制进行隐式同步来实现,除非绝对必要.同步对象可以帮助解决此问题.