This is part of a tutorial series teaching advanced modern OpenGL. To use all features to their fullest you will need to target OpenGL 4.6. These articles assume you have familiarity with OpenGL.
With the old way of using OpenGL, it required that you send things like vertex, uv, and normal data in a format that the driver could understand and use. This meant using vertex buffer objects (VBOs) and vertex array objects (VAOs). With programmable vertex pulling we will be getting rid of VBOs entirely and using our own data format with manual data unpacking in the shader. This gives us a lot of flexibility with how we structure our data and will be very useful in future articles that will discuss other advanced techniques.
Let’s start by looking at an example of how we would pack up the vertices to send to the GPU in a stream with the old way of doing things.
main.cpp
Then the shader would look something like this:
shader.vs
New Method - Programmable Vertex Pulling with SSBOs
This will work for both indexed and non-indexed drawing and can be extended to further support multi-draw indirect commands. In the above example we put all the data into a vector of floats, then sent it to an OpenGL array buffer and told OpenGL how it was supposed to interpret the data and which locations it was supposed to send it to. With programmable vertex pulling we do away with that and instead manually unpack our data in the shader.
The advantage of this is that we get OpenGL out of the way when it comes to interpreting our data and instead write the code to deal with our data directly a lot like we would do with C++, but now in GLSL. This offers us a lot of flexibility both with vertex data but other with other data that will be discussed in future tutorials.
Based on discussion in the comments, we will be using an empty VAO to avoid issues. More information can be found here.
main.cpp
Inside of the vertex shader we will be making use of a built-in input called gl_VertexID. When using non-indexed drawing such as glDrawArrays, gl_VertexID will be equal to the current vertex index. When using indexed drawing such as glDrawElements, gl_VertexID will be equal to the current index from the element array buffer.
shader.vs
Now we have access to a very convenient vertex processing method. Nice!