# How to associate multiple arrays of vertex data and uv data with an attribute? OpenGL ES

I create the buffers to to put on them the vertex data and uv data:

    ByteBuffer bb = ByteBuffer.allocateDirect(coord.getVertices().length * 4);
...
vertexBuffer.position(0);

ByteBuffer dlb = ByteBuffer.allocateDirect(coord.getIndices().length * 2);
...
drawListBuffer.position(0);

ByteBuffer uv = ByteBuffer.allocateDirect(uv.getUv().length * 4);
...
uvBuffer.position(0);


Then I pass this vertex data using these buffer to shader with:

glGetAttribLocation(Shader.program_Image, Shader.V_POSITION);
...
glVertexAttribPointer(v_Location, 3, GL_FLOAT, false, 0, vertexBuffer);


and the uv data with:

glVertexAttribPointer(a_Location, 2, GL_FLOAT, false, 0, uvBuffer);


This allows me to render multiple shapes using ONE array, and I also can use a texture atlas and load a special of "multiple-texture", and at this point my app run correctly without any error, but I want to do now is have different arrays and send them to shader, to be able to transform only some arrays, I don't know if this is possible, for the moment I have tried without success, and I was thinking if there is a way to add all the arrays to the same buffer and how to do it.

I want to do now is have different arrays and send them to shader, to be able to transform only some arrays, I don't know if this is possible, for the moment I have tried without success, and I was thinking if there is a way to add all the arrays to the same buffer and how to do it.

What you can do is use the same VBO, but only a specified range for each drawing operation. You can use glMapBufferRange to map the VBO from range A to B, pass the data, then make a draw call (glDrawArrays) that only renders from the range A to B. After that, you can map from range B to C and make a draw call that only renders from B to C.

You still have only one VAO. But a VAOs are agnostic, and you can make some trickery with the offsets that will make it work as if it had two layouts:

// Layout 0 for the 3D world
// 3D Pos
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, layout0_stride,
0); // look at the offset
// UV
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, layout0_stride,
4 * sizeof(GLfloat)); // look at the offset

// Layout 1 for the 2D UI
// 2D Pos
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, layout1_stride,
0); // look at the overlapping offset
// UV
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, layout1_stride,
2 * sizeof(GLfloat)); // look at the overlapping offset


This is, of course, an example. It doesn't make much sense to have two layouts just to have a specific layout for 2D drawing. You could use the layout for 3D drawing for that, by simply not using the z component.

After that, you can use an uniform variable in the shader to specify which layout to use. If layout_to_use is 0, then you use the in variables in the layout position 0 and 1. If layout_to_use is 1, then you use the in variables in the layout position 2 and 3:

layout (location = 0) in vec4 in_pos3d;
layout (location = 1) in vec2 in_uv3d;
layout (location = 2) in vec2 in_pos2d;
layout (location = 3) in vec2 in_uv2d;
uniform int layout_to_use;

void main()
{
if (layout_to_use == 0) {
// Do thing with in_pos3d and in_uv3d.
} else if (layout_to_use == 1) {
// Do thing with in_pos2d and in_uv2d.
}
}


When you use the VBO from range A to B, you enable the attribute pointers 0 and 1, and set layout_to_use to 0. When you use the VBO from range B to C, you enable the attribute pointers 2 and 3, and set layout_to_use to 1.

Before doing all that, you should consider if it's worth to add this complexity to your code. Depending on what you are doing, making a single big layout (wasting some bytes) could be a better option.

The other option is using multiple VAOs and multiple VBOs, which has nothing special about but binding each VAO and VBO that you will be using. A costly operation that I don't recommend.