【问题标题】:how to update vertex buffer data frequently (every frame) opengl [duplicate]如何频繁更新顶点缓冲区数据(每帧)opengl [重复]
【发布时间】: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

标签: c++ opengl opengl-es


【解决方案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/… 以获取对上述内容的更详细说明。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多