如何更改 VBO 中的数据?
How can I change data in a VBO?
我正在尝试使用 glMapData()
和 glBufferSubData()
方法来修改现有的 VBO。
我当前的代码如下:
public void updateBufferData(int vaoID, int vboID, long index, int value){
GL30.glBindVertexArray(vaoID); //bind VAO
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboID); //bind VBO
IntBuffer buffer = storeDataInIntBuffer(new int[]{value}); //I'm not sure if I should do it like this?
GL15.glBufferSubData(vboID, index, buffer); //set data
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0); //unbind VBO
GL30.glBindVertexArray(0); //unbind VAO
}
但是当我调用这个方法时,它似乎对VBO没有任何影响。渲染出来的对象还是一样
我很确定 VBO/VAO 在调用 updateBufferData()
方法时不会绑定到任何其他内容。
在我使用 opengl es 2.0 的 android 项目中,我使用以下代码:
...
buffer = ByteBuffer.allocateDirect(vertexCount * vertexDimension * BYTES_PER_FLOAT).order(ByteOrder.nativeOrder()).asFloatBuffer();
...
// Bind to the buffer. Future commands will affect this buffer specifically.
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, bindingId);
// Transfer data from client memory to the buffer.
GLES20.glBufferSubData(GLES20.GL_ARRAY_BUFFER, 0, buffer.capacity() * BYTES_PER_FLOAT, buffer);
// IMPORTANT: Unbind from the buffer when we're done with it.
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
代码不完整,但是我觉得已经很清楚了。可以看到,bindBuffer和bufferSubData的第一个参数总是GLES20.GL_ARRAY_BUFFER。
我不会在每次必须修改 VBO 时都分配新的字节缓冲区。我只是用下面的代码更新本机缓冲区
buffer.put(coords, 0, size).position(0);
然后我使用 buffersubdata 指定我要更新的数据范围。
好的,这里有两件事:
首先,您不需要绑定 VAO 来更新 VBO。一旦您指定 VBO 是 glVertexAttribArrayPointer
的来源(您在创建 VAO 时执行此操作),您就不需要再将它们绑定在一起。对于绘图,您绑定 VAO,对于 VBO 修改,您绑定 VBO。可以这样想:同一个 VBO 可能已经绑定到多个 VAO,因此绑定一个特定的 VAO 来更新它是没有意义的。
现在进入实际答案,您的 glBufferSubData
调用错误。它应该使用 GL15.GL_ARRAY_BUFFER
作为第一个参数,而不是 VBO ID,因为它已经绑定到 GL15.GL_ARRAY_BUFFER
绑定点。
我正在尝试使用 glMapData()
和 glBufferSubData()
方法来修改现有的 VBO。
我当前的代码如下:
public void updateBufferData(int vaoID, int vboID, long index, int value){
GL30.glBindVertexArray(vaoID); //bind VAO
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboID); //bind VBO
IntBuffer buffer = storeDataInIntBuffer(new int[]{value}); //I'm not sure if I should do it like this?
GL15.glBufferSubData(vboID, index, buffer); //set data
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0); //unbind VBO
GL30.glBindVertexArray(0); //unbind VAO
}
但是当我调用这个方法时,它似乎对VBO没有任何影响。渲染出来的对象还是一样
我很确定 VBO/VAO 在调用 updateBufferData()
方法时不会绑定到任何其他内容。
在我使用 opengl es 2.0 的 android 项目中,我使用以下代码:
...
buffer = ByteBuffer.allocateDirect(vertexCount * vertexDimension * BYTES_PER_FLOAT).order(ByteOrder.nativeOrder()).asFloatBuffer();
...
// Bind to the buffer. Future commands will affect this buffer specifically.
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, bindingId);
// Transfer data from client memory to the buffer.
GLES20.glBufferSubData(GLES20.GL_ARRAY_BUFFER, 0, buffer.capacity() * BYTES_PER_FLOAT, buffer);
// IMPORTANT: Unbind from the buffer when we're done with it.
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
代码不完整,但是我觉得已经很清楚了。可以看到,bindBuffer和bufferSubData的第一个参数总是GLES20.GL_ARRAY_BUFFER。
我不会在每次必须修改 VBO 时都分配新的字节缓冲区。我只是用下面的代码更新本机缓冲区
buffer.put(coords, 0, size).position(0);
然后我使用 buffersubdata 指定我要更新的数据范围。
好的,这里有两件事:
首先,您不需要绑定 VAO 来更新 VBO。一旦您指定 VBO 是 glVertexAttribArrayPointer
的来源(您在创建 VAO 时执行此操作),您就不需要再将它们绑定在一起。对于绘图,您绑定 VAO,对于 VBO 修改,您绑定 VBO。可以这样想:同一个 VBO 可能已经绑定到多个 VAO,因此绑定一个特定的 VAO 来更新它是没有意义的。
现在进入实际答案,您的 glBufferSubData
调用错误。它应该使用 GL15.GL_ARRAY_BUFFER
作为第一个参数,而不是 VBO ID,因为它已经绑定到 GL15.GL_ARRAY_BUFFER
绑定点。