PDA

View Full Version : Not Instance rendering, still need VertexAttribDivisors



Septimra
06-27-2015, 02:32 PM
Ok. So I am not instance rendering and this is my code

It am attempting to pass a 4 * 4 matrix called transformation_matrix to OpenGL as a vertex attribute

glEnableVertexAttribArray(2);
glEnableVertexAttribArray(3);
glEnableVertexAttribArray(4);
glEnableVertexAttribArray(5);
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(transformation_matrix), 0);
glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, sizeof(transformation_matrix), (void *)(sizeof(float) * 4));
glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, sizeof(transformation_matrix), (void *)(sizeof(float) * 8));
glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, sizeof(transformation_matrix), (void *)(sizeof(float) * 12));

I know I can send it as a uniform but this is an exercise.

However this does not show anything on the screen--it's blank. However once I add

glVertexAttribDivisor(2, 1);
glVertexAttribDivisor(3, 1);
glVertexAttribDivisor(4, 1);
glVertexAttribDivisor(5, 1);

then all is well. I am confused. Why do we need attrib divisors if there is no instancing going on? Will OpenGL only allow you to send a matrix this way if you it assumes you are instancing via glVertexAttribDivisor? Otherwise does it assume you would only send it as a unifrom?

I have not called glDrawArrays or glDrawElements in their instanced variations yet I still am required to use glVertexAttribDivisor?

Thanks

Alfonse Reinheart
06-27-2015, 05:39 PM
Remember how vertex array specification works without the divisor. For each vertex in the range of vertices specified, the vertex fetching system will fetch a value from each enabled array. You have specified 4 arrays, so 4 values will be fetched.

But without the divisor, the index for that fetch is gl_VertexID. If you're using glDrawArrays, then that index increases monotonically from the start index to the final index. With indexed rendering, the index comes from the index in the index array (possibly biased by a base vertex index).

If your matrix buffer object only has space for one matrix, then only the first vertex will get reasonable data. The rest of the vertices will walk off the end of the array.

By using the divisor, you're saying that, within each instance, the vertex shader will get the same values. Without the divisor, each vertex shader gets a value based on the vertex index, not the instance count.

mhagain
06-27-2015, 06:29 PM
An interesting quirk of OpenGL vs D3D is that in OpenGL if you specify a stride 0 it means that the data is tightly packed, whereas in D3D stride 0 means literally 0 and the data will repeat for each vertex. If you were coding this in D3D you could therefore specify stride 0 in your vertex declaration/input layout and have the result you wish, even without instancing; in OpenGL you need glVertexAttribDivisor to get that result.

You could also get the same result with some glVertexAttrib4fv calls.