1

Is it possible to push/uplink 2 (or more) VBOs to a single Opengl's vertex-attribute location?

enter image description here

Here is my current code. It works if I push at most 1 VBO per 1 location.

glBindBuffer(GL_ARRAY_BUFFER, VBO); 
...
glBindVertexArray(VAO);  // (VAO-scope)
glEnableVertexAttribArray(gl_location);
glVertexAttribPointer(
gl_location, numOfFloat_usually1to4, 
  GL_FLOAT, GL_FALSE, amountOfSpace_inByte_betweenAttribute_usually0,  
  (void*)(stripN.stepOffset* sizeof(float)));  
glVertexAttribDivisor(gl_location,var_0IfPerVertex_1IsPerInstance);

I don't want to use 2 locations. Each location is a precious resource.

Is it just impossible by Opengl's specification?

cppBeginner
  • 1,114
  • 9
  • 27
  • "*Each location is a precious resource.*" If you could fit arbitrary amounts of data into a single location, why do you think there would even *be* a limit on the number of vertex shader inputs? – Nicol Bolas Feb 09 '21 at 03:04
  • @Nicol :: Because of the 16 locations limit. Each location can support only 4 float maximum. (reference: https://stackoverflow.com/a/18543827/ ) Did i read it wrong? – cppBeginner Feb 09 '21 at 03:09
  • You misunderstand my question. The number of locations is limited by the implementation. If you could shove arbitrary amounts of data through a *single* location, that would be no different from simply having an arbitrary *number* of locations. That is, if there was no limit on the total amount of stuff a VS is allowed to read, there would be no need for a limit on the number of attributes. – Nicol Bolas Feb 09 '21 at 03:11

1 Answers1

4

A single vertex shader input location (aka: vertex attribute) represents up to 4 scalar values worth of data. It cannot be more than 4.

From the OpenGL API side of the data, the format of the up-to-4 elements for each attribute is defined by a single invocation of glVertexAttribFormat/Pointer for that attribute location. Subsequent calls that try to use the same location in that VAO will overwrite the previous format specification.

From the GLSL side that receives the data, the mapping from locations to variables is not quite so strict. Some variable types naturally take up more than one location; layout(location = 0) in mat4 matrix; will consume 4 attribute locations (0-3).

Similarly, for basic types or vectors with fewer than 4 elements, multiple input variables can share the same location through the component layout qualifier:

layout(location = 0, component = 0) in vec2 first_two;
layout(location = 0, component = 2) in float third;
layout(location = 0, component = 3) in float fourth;

All 3 variables use the same attribute location, but they use different parts of it. first_two uses the first two components of the location, third comes from the third component, and fourth comes from the fourth.

From the API side, it is still just using a format of glVertexAttribFormat(0, 4, ...); The 4 components simply feed 3 separate variables.

There are of course restrictions. The components of two different variables using the same location are not allowed to overlap. Also, their basic types (float, double, or integer) must be the same for all variables that use the same location.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • Thank, I never heard about it. In this solution, I can upload a VBO to `layout(location = 0, component = 0)` and another VBO to `layout(location = 0, component = 2)`, as example? I am very new and excited about this. – cppBeginner Feb 09 '21 at 03:24
  • @cppBeginner: ... no, that is exactly what I said you *cannot do* in the second paragraph. – Nicol Bolas Feb 09 '21 at 03:33
  • Thus, it is impossible? i.e. If I need to restrict consumption to only 1 location, the only way is to shove 2 VBOs into 1 VBO. – cppBeginner Feb 09 '21 at 03:42