WebGL 中的 swapBuffer OpenGL 调用在哪里

Where is the swapBuffer OpenGL call in WebGL

注意到 WebGL 中不存在 SwapBuffer 功能,如果是这种情况,我们如何在 WebGL 中跨绘制调用更改状态并绘制多个对象,WebGL 在什么时间点内部调用 swapBuffer?

AFAIK,swap buffers 调用通常不会改变任何 visible GL 状态。不过,有很多 GL 调用可以在绘制调用之间更改该状态。至于缓冲区交换,浏览器会在使用渲染代码 returns 进行回调后的某个时间为您执行此操作(是的,无法直接控制何时实际发生)。

首先,OpenGL 中没有 SwapBuffers。 SwapBuffers is a platform specific thing that is not part of OpenGL

无论如何,WebGL 中隐含了 SwapBuffers 的等价物。如果您调用任何影响绘图缓冲区的 WebGL 函数(例如,drawArray、drawElements、clear 等),那么下次浏览器合成页面时,它将有效 "swapbuffers".

请注意,它实际上是 "swaps" 还是 "copies" 取决于浏览器。例如,如果启用抗锯齿(默认设置),则浏览器将在内部有效地执行 "copy" 或 "blit",将内部多重采样缓冲区转换为实际可以显示的内容。

另请注意,由于交换是隐式的,WebGL 将在下一个渲染命令之前清除 drawingBuffer。这是为了使行为保持一致,而不管浏览器是否决定在内部交换或复制。

您可以通过将 {preserveDrawingBuffer: true} 作为第二个参数传递给 getContext 来强制复制而不是交换(并避免清除),但当然代价是不允许交换。

同样重要的是要注意交换本身以及交换发生的时间是半未定义的。换句话说,调用 gl.drawXXXgl.clear 将告诉浏览器在下一个复合时 swap/copy 但在那个时间和浏览器实际复合的时间之间,其他事件可以得到处理。在您当前的事件退出之前不会发生交换,例如 requestAnimationFrame 事件,但是,在您的事件退出时间和浏览器合成时间之间可能会发生更多事件(比如 mousemove)。

所有这一切的要点是,如果不使用 {preserveDrawingBuffer: true},您应该始终在一个事件中完成所有绘图,通常是 requestAnimationFrame,否则您可能会得到不一致的结果。