2
\$\begingroup\$

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.

\$\endgroup\$
1
\$\begingroup\$

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.

\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.