我正在尝试使用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没有任何影响。渲染的对象仍然是相同的。
我很确定在调用updateBufferData()
方法时,VBO / VAO没有绑定任何其他东西。
答案 0 :(得分:3)
好的,这里有两件事:
首先,您不需要绑定VAO来更新VBO。一旦您指定所述VBO是glVertexAttribArrayPointer
的源(您在创建VAO时执行此操作),就不再需要将它们绑定在一起了。对于绘图,您绑定VAO,对于VBO修改,您绑定VBO。可以这样想:相同的VBO可能已经绑定到几个VAO,因此绑定特定的VAO来更新它是没有意义的。
现在回答实际答案,你正在做glBufferSubData
电话错误。它应该使用GL15.GL_ARRAY_BUFFER
作为第一个参数,而不是VBO ID,因为它已经绑定到GL15.GL_ARRAY_BUFFER
绑定点。
答案 1 :(得分:1)
在我的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指定我想要更新的数据范围。