如何频繁更新顶点缓冲区数据(每帧)opengl [重复]

Posted

技术标签:

【中文标题】如何频繁更新顶点缓冲区数据(每帧)opengl [重复]【英文标题】:how to update vertex buffer data frequently (every frame) opengl [duplicate] 【发布时间】:2017-01-21 21:35:56 【问题描述】:

我有一个简单的二维三角形显示在屏幕上,我想每帧更新颜色缓冲区数据,所以三角形的颜色不断变化,但我不知道如何有效地更新数据。

这是颜色缓冲区的代码:

GLfloat colourVert[] = 
        0.0f, 1.0f, 0.0f,
        1.0f, 0.0f, 0.0f,
        0.0f, 0.0f, 1.0f
    ;



GLuint colourBuffer;
glGenBuffers(1, &colourBuffer);
glBindBuffer(GL_ARRAY_BUFFER, colourBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(colourVert), colourVert, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);

我需要在这些行中添加一些东西还是需要修改着色器,谁能解释一下,谢谢你的帮助。

【问题讨论】:

你应该决定你想要哪种类型的OpenGL,因为答案很大程度上取决于这个。并请说明是哪个版本。例如,es 3.0 使用 VAO 来存储属性绑定,而 2.0 则没有。 @BDL 在ios opengl es 2.0 完全支持VAOs 但不支持android glMapBuffer 似乎是正确的解决方案:khronos.org/registry/OpenGL-Refpages/gl4/html/glMapBuffer.xhtml 【参考方案1】:

您绝对不应该每帧都生成一个新缓冲区。只需重用已经存在的。同样设置属性指针也可以只进行一次,因为它们存储在 VAO 中。实际上唯一需要的两行是glBindBufferglBufferData(或者更好地使用glBufferSubData,因为这将重用分配的内存而不是分配新的内存段)。

请注意,此答案仅适用于 OpenGL 3.3 Core(及更高版本)和 OpenGL-ES 3.0(及更高版本)。对于不支持/不需要 VAO 的 OpenGL 版本,可能还必须在每一帧中进行属性设置。

【讨论】:

是否使用VAO都没有关系。无论哪种情况,我们只需要更新 VBO 而不是 VAO @Sung:我从来没有说过你必须更新 VAO。我说:“如果你使用 VAO,你不应该每帧都调用glVertexAttribPointer,因为这个设置存储在 vao 状态”。 您说“设置属性指针也可以只进行一次,因为它们存储在 VAO 中”“请注意,此答案仅适用于 OpenGL 3.3 Core(和更新版本)和 OpenGL-ES 3.0”你的前提是他使用的是VAO,不需要提及。 如果您想避免内存分配,值得流水线化您的缓冲区更新。如果您每帧都使用相同的缓冲区,则很可能您将排队渲染工作,持有对缓冲区现有内容的引用,因此即使没有显式内存分配,您也可能会得到一个,因为驱动程序会插入一个。通常,您希望(至少)在帧之间对您的 VBO 进行双重缓冲,以便在使用之间获得两个帧。这最大限度地减少了分配驱动程序的机会。 请参阅community.arm.com/graphics/b/blog/posts/… 以获取对上述内容的更详细说明。

以上是关于如何频繁更新顶点缓冲区数据(每帧)opengl [重复]的主要内容,如果未能解决你的问题,请参考以下文章

每帧调用 glGetUniformLocation()

如何在 OpenCL 内核中更新 OpenCL-OpenGL 共享缓冲区数据?

OpenGL更新缓冲区如何影响速度

OpenGL +无法使用buffersubdata更新缓冲区数据

Metal 最佳实践:三重缓冲 – 纹理?

JOGL/OpenGL VBO - 如何渲染顶点?