Jointts Jointts - 1 month ago 13
C++ Question

OpenGL glBufferData -> Why &vertices[0] instead of &vertices as data parameter?

Hello I am having trouble figuring out why does passing the first element of an array of GLfloat positions (xyz) suddenly give the buffer all the elements of that array.

glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * vertices.size(), &vertices[0], GL_STATIC_DRAW);


Here the argument for data is &vertices[0] which during debugging results in only one xyz vector, however when the whole object is rendered it surely cant only have this one vector.

The sane thing to do would be to pass the whole vector &vertices to my mind, would it not?

Perhaps I am having a misunderstanding how OpenGL buffers work?

I have been following the tutorials from here: http://learnopengl.com/#!Model-Loading/Mesh

To sum up: Why &vertices[0] instead of &vertices

Answer

I'm assuming vertices is a std::vector<Vertex>. Since it is, that means that &vertices is of type std::vector<Vertex>*, or a pointer to the vector.

However, OpenGL doesn't want a vector. OpenGL was written for C, which has no notion of vectors. Therefore, it expects a C-style array. (If you're not sure what that is, see here.)

According to the C++ standard, a std::vector must store all of its elements in continuous memory. That means that vertices[1] must come right after vertices[0], vertices[2] after vertices[1], and so forth. This is essentially exactly what C-style array is: a pointer to a continuous set of items.

If vertices[0] is the first element of the vector, then &vertices[0] is a pointer to the first element. Like I said above, all elements are stored continuously, so &vertices[0] is really just a pointer to a C-style array.

In C++11, you can instead use vertices.data(), which is essentially the same thing but cleaner.