如何更改VBO中的数据?

时间:2015-07-15 15:55:53

标签: java opengl 3d buffer lwjgl

我正在尝试使用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没有绑定任何其他东西。

2 个答案:

答案 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指定我想要更新的数据范围。