greedsin
greedsin

Reputation: 1270

How can i generate multiple VBO with an ByteBuffer

According to lwjgl javadooc, there is a function :

public static void glGenBuffers(int n, ByteBuffer buffer)

But i dont exactly understand how this works. Do i create an ByteBuffer :

ByteBuffer buffer = ByteBuffer.allocate("how much???")
glGenBuffers(4, buffer);

And especially do i have to fill the Buffer with glBufferSubData OR is it better to create 4 buffers and bind and fill them?

My thought was, that it is more efficient when i only create 1 Buffer ,which stores vertices,texturecoords,normals and indices.

Upvotes: 3

Views: 253

Answers (1)

javac
javac

Reputation: 2441

glGenBuffers(int n, ByteBuffer buffer) generates n vertex buffer objects (VBOs), which you can use to store your data, and puts them in the specified buffer. This buffer is not actually the one that holds your data, but the ids of the VBOs just generated. You have to manually define the VBO data with glBufferData.

The function is useful if you want to create multiple VBOs with a single call. Each VBO id is an integer, and the buffer has to be large enough to hold n (in this case 4) buffers.

ByteBuffer buffer = BufferUtils.createByteBuffer(4 * Integer.BYTES);
glGenBuffers(4, buffer);

However, to make things easier, you can also use an IntBuffer.

IntBuffer buffer = BufferUtils.createIntBuffer(4);
glGenBuffers(4, buffer);

You can then attach the data to each of the VBOs.

glBindBuffer(GL_ARRAY_BUFFER, buffer.get(2); /*value from 0 to 3*/
glBufferData(GL_ARRAY_BUFFER, data, GL_STATIC_DRAW);

(If you are using a ByteBuffer, you have to call buffer.getInt(2) instead.)


It is generally more efficient to have all data in a single buffer, but note that in this case you have to use at least two because indices have to be in a GL_ELEMENT_ARRAY_BUFFER. However, the performance difference is very small, so it may be easier to use several different VBOs.

It is preferred to tightly pack all the data in a buffer and upload that with glBufferData instead of calling glBufferSubData for each type of data. Your data layout will then look something like this (P = position, T = texture coordinate, N = normal vector):

PPPTTNNNPPPTTNNNPPPTTN...

Now you can setup the vertex attribute pointers to correctly read the values from this buffer.

int vbo = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, tightlyPackedData, GL_STATIC_DRAW);

int stride = (3 + 2 + 3) * Float.BYTES;

glVertexAttribPointer(positionIndex, 3, GL_FLOAT, false, stride, 0);
glVertexAttribPointer(texCoordIndex, 2, GL_FLOAT, false, stride, 3 * Float.BYTES);
glVertexAttribPointer(normalIndex,   3, GL_FLOAT, false, stride, (3 + 2) * Float.BYTES);

positionIndex, texCoordIndex and normalIndex are the attribute locations of your vertex shader attributes. You can get them with glGetAttribLocation.

stride is the number of bytes between the value of one vertex and the value of the next one. We have 3 positions, 2 texture coordinates and 3 normals, which are all floats, so we multiply them with Float.BYTES.

The last parameter to glVertexAttribPointer is the offset in bytes, i.e. the number of bytes from the start of the buffer to where the first value is located.

Upvotes: 2

Related Questions