0

I'm pretty new to 3D programming. I'm trying to learn OpenGL from this site. During the reading I couldn't really understand how the layout (location = 0) line really operates. I've tried to search for other explanation online both in the OpenGL wiki and in other sites, and I've managed to find this site from which I understood a little more.

So if I am correct the vertex shader takes some inputs and generates some outputs. The input of the shader are called vertex attributes and each one of them as an index location called attribute index. Now I expect that if the shader takes as input a single vertex and its attributes, it has to run multiple times, one for each vertex of the object I'm trying to render. Is it correct what I wrote up until this point?

Now, what I didn't manage to understand is how layout (location = 0) really works. My assumption is that this intruction needs to tell the shader from where location in memory to pick the first index attribute. Thus each time the shader re-runs (if it actually re-runs), the location should move by one unit, like in a normal for loop. Is this interpretation correct? And, please, can anyone actually explain me, in an organic way, how the vertex shader operates?

P.S. Thank you in advance for your time and excuse my poor English: I'm still practising it!

Edit

This is the code. Following the first guide I linked I created an array of vertices:

float vertices[] {

   -0.5f, -0.5f, 0.0f,
    0.5f, -0.5f, 0.0f,
    0.0f,  0.5f, 0.0f

};

then I created a vertex buffer object:

unsigned int VBO;
glGenBuffer(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);

I added the data to the VBO:

glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

while the vertex shader reads:

#version 330 core
layout (location = 0) in vec3 aPos:

void main() {
    gl_Position(aPos.x, aPos.y, aPos.z, 1.0f);
}
6
  • It's no the first index attribute, it's the location of the buffer itself. So when your binding a buffer, you know to bind that buffer at the 0'th location. Sorry, I think this is backwards. Commented Sep 2, 2021 at 8:36
  • but how do I know that the buffer is specifically at 0th place. And moreover do the shader have to rrerun to compute all the vertices? Commented Sep 2, 2021 at 8:43
  • Using the 'layout' key word you're specifying the attriblocation. If that attribute is a vector then it points to the first index of the element. Commented Sep 2, 2021 at 8:47
  • Then why do I have to specify it, isn't it the standard that the first index is always 0? Commented Sep 2, 2021 at 8:49
  • But if the buffer contains more than on vertex, then the 0 I specify isn't the location of the buffer, but the index at which I start inputing the vector, right? Commented Sep 2, 2021 at 8:52

1 Answer 1

1

You need to look at both sides of this. You bind a buffer containing all of your data. Say position and color.

layout(location = 0) in vec3 position;
layout(location = 1) in vec3 color;

Now in the program, I can use these vectors without specifying the index of the vertex I am processing because we had to tell GL how to buffer the data.

We do that when we bind buffers to the program.

Lets say we want to create a triangle. It has 3 vertexes, each vertex has two attributes: color and position. We create a vertex shader that processes each vertex, in that program it is implied that each vertex has a color and position. You don't care about the index in the array it is (for now).

The program will take vertex i, v_i and process it. How it populates position and vector depend on how you bind the data. I could have two arrays,

positionData = [x0, y0, z0, x1, ... z3];
colorData = [r0, g0, b0, r1, ... b3];

So I would buffer this data, then I would bind that buffer to the program at the attribute location and specify how it is read. Eg. bind the positionBuffer to attribute location 0, read it in strides of three with no offset.

The same with the color data, but with location 1.

Alternatively I could do.

posColData = [ x0, y0, z0, r0, g0, b0, x1, y1, ... b3];

Then I would create posColBuffer and bind it to the 0th attribute, with a stride of 6. I would also bind the posColBuffer to the 1st attribute with a stride of 6 and an offset of 3.

The code you are using does this here.

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);  ;

They utilize the layout clause by just saying 0 since they know the location.

Sign up to request clarification or add additional context in comments.

2 Comments

following the guide I linked you in my question (the first one), to manage the memory I had to create a vertex buffer object, to which I passed an array of vertices (of one dimension: float verttice[] = {...}). Sorry but I can't really figure out how should I imagine the buffer in first place (should I imagine as the memory of the computer with different contigue cells?). And the rest of the process is cloudy too... Could you please explain me the whole process that binds a buffer to the shader in little more detail?
So, imagining the buffer subdivided into contigue cells, if I first bind pos array and then col array I will have the 0th cell containing the whole vertex array, and the 1st cell containing the color array. But at this point the program doesn't yet know hot to subdivide the vertices array into actual vertices, so I have to tell it. In the guide it is tiold that this task is accomplished using glVertexAttribPointer. Is this reasoning correct?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.