Stride argument in OpenGL ES 2.0
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
:
- starts reading data from the provided address (or from the current
GL_ARRAY_BUFFER
if any is bound), - read size elements from the address,
- passes the values to the corresponding GLSL attribute,
- jump stride bytes from the address it started reading from,
- repeats 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 ascopy_arr
here) and pass these values to the GLSL attribute identified byyour_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.