For this lesson, you will be given a vertex buffer and a shader, and you should then set up an attribute pointer and draw the contents of the buffer. The attribute is a vec2 at location 0, and the buffer is a densely packed float array.
As we saw in the last lesson, buffers store data for vertex attributes. However, just storing the data is not enough, we also need to tell the vertex shader where it is. This is done with attribute pointers.
Vertex attribute pointers are pointers to slices of buffer data. The data in a vertex attribute pointer consists of the following:
- An index to the attribute location
- The data type of the attribute (float, vec2, vec3, etc.)
- An offset to the start of the attribute
- A stride representing the distance (in bytes) between attributes
This is a bit much to unpack, so lets walk through the details step by step. First, suppose that we have a vertex shader with an attribute at location 0 of type vec3:
attribute vec3 position; //At location 0And that the data for the vertices is encoded as follows:
var data = [
x0, y0, z0, //Components of first vertex
x1, y1, z1, //Components of second vertex
x2, y2, z2, //Components of third vertex
...
]And is uploaded to a buffer as follows:
var buffer = gl.createBuffer(gl.ARRAY_BUFFER)
gl.bindBuffer(gl.ARRAY_BUFFER, buffer)
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(data), gl.STATIC_DRAW)From here, there are two commands that we need to call to set up an attribute pointer. First, we need to tell WebGL to use an attribute pointer instead of constant attribute value:
gl.enableVertexAttribArray(0)Which works as follows:
Tells WebGL to use an attribute pointer for the attribute at
location
And once this is done, we can then specify the data of the pointer using the following method:
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0)This method is pretty complicated, so lets unpack how it works:
Sets up an attribute pointer for the attribute at
locationusing the vertex buffer currently bound togl.ARRAY_BUFFER:
sizeis the size of the attribute in terms of number of elements, egsize=1meansfloatsize=2meansvec2size=3meansvec3size=4meansvec4
typeis the type of the data in the buffer. The possible values aregl.FLOAT, gl.BYTE, gl.SHORT, gl.INT, gl.UNSIGNED_BYTE, gl.UNSIGNED_SHORT, gl.UNSIGNED_INT, gl.FIXEDnormalizedis a flag which checks if set forBYTE, SHORTorINTtypes rescales them to the range+/- 1. This can be useful for encoding values like normals or texture coordinates compactlystrideis the distance between successive attributes in bytes. If set to0, then it assumes that the attributes are tightly packed.offsetis a pointer (in bytes) to the start of the first attribute in the array.