nautilus_rs
nautilus_rs

Reputation: 45

How can I change data in a VBO?

I am attempting to use the glMapData() and glBufferSubData() methods to modify an existing VBO.

My current code is the following:

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
}

However when I call this method, it doesn't seem to have any effect on the VBO. The rendered object is still the same.

I'm pretty sure that the VBO/VAO aren't bound to anything else when the updateBufferData() method is called.

Upvotes: 3

Views: 1292

Answers (2)

Dani Torramilans
Dani Torramilans

Reputation: 365

Okay, two things here:

First off, you don't need to bind a VAO to update an VBO. Once you've specified that said VBO is the source for the glVertexAttribArrayPointer (you do this when you create the VAO) you don't need to bind them together anymore. For drawing you bind the VAO, for VBO modifications you bind the VBO. Think of it this way: the same VBO may have been bind to several VAOs, so there's no sense in binding a specific VAO to update it.

Now on to the actual answer, you're doing the glBufferSubData call wrong. It should be using GL15.GL_ARRAY_BUFFER as the first parameter, not the VBO ID, since that has already been bind to the GL15.GL_ARRAY_BUFFER binding point.

Upvotes: 6

xcesco
xcesco

Reputation: 4838

In my android projects with opengl es 2.0 i use the following code:

...
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);

Code is not complete, but i think it is quite clear. As you can see, the first parameter of bindBuffer and bufferSubData is always GLES20.GL_ARRAY_BUFFER.

I don't alloc a new byte buffer every time i have to modify VBO. Simply i update native buffer with the following code

buffer.put(coords, 0, size).position(0);

and then i use the buffersubdata specifing the data range i want to update.

Upvotes: 1

Related Questions