OpenGL 我什么时候可以再次开始发出命令

标签 opengl

这些标准暗示从我的第一个 gl 命令开始渲染,并继续与其他命令并行。某些函数(如 glBufferSubData)表示只要对象当前未在使用中,就可以在渲染期间进行加载。这引入了“框架”的逻辑概念,尽管标准中从未明确提及。

所以我的问题是什么定义了这个逻辑框架?也就是说,哪些调用划分了游戏,以便我可以再次开始进行 gl 调用而不会干扰前一帧?

例如,使用 EGL 您最终会调用 eglSwapBuffers(大多数实现都有某种交换命令)。从逻辑上讲,这是一帧和下一帧之间的边界。但是,这会调用块以支持 v-sync,这意味着在它返回之前您无法发出新命令。然而,文档暗示您可以在另一个线程中返回之前开始发出新命令(前提是您不接触任何正在使用的缓冲区)。

即使交换命令仍在前一个缓冲区上阻塞,我如何开始向下一个缓冲区发出命令?我想在 GPU 处理旧帧时开始为下一帧流式传输数据(特别是,我将有两个顶点缓冲区,它们将专门为此目的交换每一帧,并在 OpenGL 文档中有所提及)。

最佳答案

OpenGL 没有“框架”的概念,无论是逻辑的还是其他的。

OpenGL 真的很简单:每条命令的执行就好像所有先前的命令都事先完成了一样。

注意关键短语“好像”。假设您从缓冲区对象渲染,然后立即修改其数据。像这样:

glBindVertexArray(someVaoThatUsesBufferX);
glDrawArrays(...);
glBindBuffer(GL_ARRAY_BUFFER, BufferX);
glBufferSubData(GL_ARRAY_BUFFER, ...);

这在 OpenGL 中是 100% 合法的。关于这将如何运作,没有任何警告、问题、担忧等。该 glBufferSubData 调用将像 glDrawArrays 命令已完成一样执行。

您唯一需要考虑的是规范未指定的一件事:性能。

实现完全在其权限范围内检测您正在修改可能正在使用的缓冲区,因此在 glBufferSubData 中停止 CPU,直到该缓冲区的渲染完成。需要 OpenGL 实现来执行此操作或执行其他操作,以防止实际源缓冲区在使用时被修改。

因此,根据规范,OpenGL 实现在可能的情况下异步执行命令。只要外界无法判断 glDrawArrays 还没有画完任何东西,实现就可以为所欲为。如果您在绘图命令之后立即发出 glReadPixels,管道将不得不停止。您可以这样做,但不能保证性能。

这就是为什么 OpenGL 被定义为一个封闭的盒子的原因。这为实现提供了尽可能多的异步实现自由。每次访问 OpenGL 数据都需要一个 OpenGL 函数调用,这允许实现检查该数据是否实际可用。如果没有,它就会停滞不前。

摆脱摊位是 buffer object invalidation 成为可能的原因之一;它有效地告诉 OpenGL 您想要孤立缓冲区的数据存储。这就是为什么 buffer objects can be used for pixel transfers 的原因;它允许传输异步发生。这就是为什么 fence sync objects exist 的原因,以便您可以判断资源是否仍在使用中(可能用于 GL_UNSYNCHRONIZED_BIT 缓冲区映射)。等等。

However, this calls blocks to support v-sync, meaning you can't issue new commands until it returns.



谁说的?缓冲区交换命令可能会停止。可能不会。它是实现定义的,可以更改 with certain commands eglSwapBuffers 的文档只说它执行刷新,这可能会使 CPU 停顿但不是必须的。

关于OpenGL 我什么时候可以再次开始发出命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12034262/

相关文章:

c++ - Windows Visual C++ 链接到 Mesa3D OpenGL

c++ - 使用 clCreateFromGLTexture 的 opencl/opengl 互操作无法绘制到纹理(纹理黑色)

c++ - 在 OpenGL 中使用 Wu 算法的数字微分分析仪

java - NetBeans OpenGL Pack 中缺少 GLCanvas 和其他 JOGL 类吗?

windows - 如何为 Windows 配置 OpenGL makefile?(来自 Linux)

java - 如何在不移动点的情况下旋转点?

java - 避免多次加载纹理

opengl - 从深度重建的世界位置是错误的

opengl - Assimp三角测量不起作用

macos - OSX Cocoa 在 webview 中嵌入 opengl view