I'm putting this information here, as it took me way more time than it should to understand how the stride argument works in glVertexAttribPointer.
This argument is extremely important if you want to pack data in the same order as they are accessed by the CPU/GPU.
When reading the manual, I thought that stride was the number of bytes the OpenGL implementation would skip after reading size elements from the provided array.
However, it tends to work like this. glVertexAttribPointer :
- Start reading data from the provided address,
- Read size elements from the address,
- Pass the values to the corresponding GLSL attribute,
- Jump stride bytes from the address it started reading from,
- Repeat this procedure count times, where count is the third argument passed to glDrawArrays.
So, for example, let's take a float array stored at memory's address 0x20000, containing the following 15 elements :
GLfloat arr[] = { /* 0x20000 */ -1.0f, 1.0f, 1.0f, 0.0f, 1.0f, /* 0x20014 */ -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, /* 0x20028 */ 0.0f, 1.0f, 1.0f, 1.0f, 1.0f };
If you use glVertexAttribArray like this :
glVertexAttribArray(your_glsl_attrib_index, 3, GL_FLOAT, GL_FALSE, 20, arr);
And then use glDrawArrays, the OpenGL implementation will do something akin to this :
- Copy the address arr (0x20000).
- Start reading {-1.0f, 1.0f, 1.0f} from the copied address (referred as copy_arr here) and pass these values to the GLSL attribute identified by your_glsl_attrib_index.
- Do something like copy_arr += stride. At this point, copy_arr == 0x20014.
Then, on the second iteration, it will read {-1.0f, 0.0f, 1.0f} from the new copy_arr address, redo copy_arr += stride and continue like this for each iteration.
Here's a concise diagram resuming this.