2
votes

I want to keep multiple different meshes in the same VBO, so I can draw them with glDrawElementsBaseVertex. How different can vertex specifications for different meshes be in such a VBO in order to be able to draw them like that?

To be more specific:

  1. Can vertex arrays for different meshes have different layouts (interleaved (VNCVNCVNCVNC) vs batch(VVVVNNNNCCCC))?
  2. Can vertices of different meshes have different numbers of attributes?
  3. Can attributes at same shader locations have different sizes for different meshes (vec3, vec4, ...)?
  4. Can attributes at same shader locations have different types for different meshes (GL_FLOAT, GL_HALF_FLOAT, ...)?

P.S. When i say mesh I mean an array of vertices, where each vertex has some attributes (position, color, normal, uv, ...).

2

2 Answers

1
votes

openGL doesn't care what is in each buffer, all it looks at is how the attributes are specified and if they happen to use the same buffer or even overlap then fine. It assumes you know what you are doing.

  1. Yes, if you use a VAO for each mesh then the layout of each is stored in the VAO and binding the other will set the attributes correctly. This way you can define the offset from the start of the buffer so you don't need the glDraw*BaseVertex variants

  2. Yes

  3. not sure

  4. yes they will be auto converted to the correct type as defined in the attributePtr call.

1
votes

In addition to ratchet freak's answer, I'll only elaborate on point 3:

Yes, you can do that. If you set up your attribute pointers to specify more elements than your shader uses, the additional values are just never used.

If you do it the other way around and read more elements in the shader than are specified in your array, the missing elements are automatically extened to build a vector of the form (0, 0, 0, 1), so the fourth component will be implicitely 1 and all other (unspecified) ones 0. This makes it possible to use the vectors directly as homogenous coordinates or RGBA colors in many cases.

In many shaders, one sees somehting like

in vec3 pos;
...
gl_Position = matrix * vec4(pos, 1.0);

This is actually not necessary, one could directly use:

in vec4 pos;
...
gl_Position = matrix * pos;

while still storing only 3 component vectors in the attribute array. As a side effect, one now has a shader which also can deal with full 4-component homogenous coordinates.