一旦我渲染了VBO,我怎么才能改变纹理坐标?

时间:2015-03-17 17:30:42

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

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

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调用的新纹理坐标,我需要做什么?

2 个答案:

答案 0 :(得分:3)

你可以做到

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

表示再次绑定缓冲区并在其上调用glBufferData

您还可以使用纹理坐标创建一个新的vbo,并通过调用绑定到glVertexAttribPointer(textureCoordsAttribute, 2, GL_FLOAT, false, 0, 0);的{​​{1}}将其设置为属性缓冲区。

答案 1 :(得分:0)

您可以使用glBufferSubData()

更新现有缓冲区中的数据
glBindBuffer(GL_ARRAY_BUFFER, textureCoordsBuffer);
glBufferSubData(GL_ARRAY_BUFFER, 0, textureDataSizeInBytes, textureData);

如果您经常更新数据,则应相应地选择初始glBufferData()电话的使用参数:

glBufferData(GL_ARRAY_BUFFER, textureDataSizeInBytes, NULL, GL_DYNAMIC_DRAW);

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

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