【问题标题】:How do I only change the texture coords once I've rendered a VBO?渲染 VBO 后,如何仅更改纹理坐标?
【发布时间】:2015-03-18 13:06:34
【问题描述】:

当我渲染一个立方体时,它看起来像这样:

glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glVertexAttribPointer(vertexPositionAttribute, 3,  GL_FLOAT, false, 0, 0);

glBindBuffer(GL_ARRAY_BUFFER, textureCoordsBuffer);
glVertexAttribPointer(textureCoordsAttribute, 2, GL_FLOAT, false, 0, 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textureId);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);

glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_SHORT, 0);

我只想更改纹理坐标,而不是更改顶点或索引。 我的问题是我是否必须重新发送顶点数据和索引数据才能再次渲染这个立方体,或者我可以只发送新的纹理坐标吗?如果我可以发送新的纹理坐标,我需要做什么 OpenGL 调用?

【问题讨论】:

    标签: c++ opengl opengl-es opengl-es-2.0


    【解决方案1】:

    你可以的

    glBindBuffer(GL_ARRAY_BUFFER, textureCoordsBuffer);
    glBufferData(GL_ARRAY_BUFFER, size, data, GL_DYNAMIC_DRAW);
    

    这意味着再次绑定缓冲区并在其上调用glBufferData

    您还可以使用纹理坐标创建一个新的 vbo,并将其设置为属性缓冲区,方法是调用 glVertexAttribPointer(textureCoordsAttribute, 2, GL_FLOAT, false, 0, 0); 并将其绑定到 GL_ARRAY_BUFFER

    【讨论】:

    • 所以我会做 glBindBuffer 和 glBufferData 来复制新坐标?然后保持和上面一样的步骤进行渲染?
    【解决方案2】:

    您可以使用glBufferSubData() 更新现有缓冲区中的数据:

    glBindBuffer(GL_ARRAY_BUFFER, textureCoordsBuffer);
    glBufferSubData(GL_ARRAY_BUFFER, 0, textureDataSizeInBytes, textureData);
    

    如果你经常更新数据,你应该相应地选择初始glBufferData()调用的usage参数:

    glBufferData(GL_ARRAY_BUFFER, textureDataSizeInBytes, NULL, GL_DYNAMIC_DRAW);
    

    每次修改数据时都可以调用glBufferData()。但它的效率可能要低得多,因为它意味着每次都分配一个新的缓冲区对象。

    请注意,glBufferData()data 参数在这种情况下可以指定为 NULL。以这种方式使用时,它只会为数据分配内存,期望您稍后通过调用 glBufferSubData() 来指定数据本身。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-05-16
      • 2011-11-08
      • 1970-01-01
      • 2020-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多