OpenGL glVertexAttribFormat vs glVertexAttribPointer

I am attempting to change my code from using glVertexAttribPointer to glVertexAttribFormat as I have heard it;s more efficiend since it reduces binding calls overhead.

I have 2 versions of the code, one working one not.

The code looks like:

glGenBuffers(1, &tvbo1);
glBindBuffer(GL_ARRAY_BUFFER, tvbo1);
glObjectLabel(GL_BUFFER, tvbo1, 21, "\"Mesh Vertex Buffer\"");
glBufferData(GL_ARRAY_BUFFER, sizeof(vec3)*triangle.size(), triangle.data(), GL_STATIC_DRAW);

glGenBuffers(1, &tvbo2);
glBindBuffer(GL_ARRAY_BUFFER, tvbo2);
glObjectLabel(GL_BUFFER, tvbo2, 22, "\"Mesh Normals Buffer\"");
glBufferData(GL_ARRAY_BUFFER, sizeof(vec3)*ns.size(), ns.data(), GL_STATIC_DRAW);

glEnableVertexAttribArray(0);
//glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glVertexAttribFormat(0, 3, GL_FLOAT, GL_FALSE, 0); //comment
glVertexAttribBinding(0,0); //comment

glEnableVertexAttribArray(1);
//glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, 0); //comment
glVertexAttribBinding(1,1); //comment

GLuint ptrs[] = {tvbo1, tvbo2};
GLintptr offsets[] = {0,0};
int strides[] = {0,0};
glBindVertexBuffers(0, 2, ptrs, offsets, strides); //comment


So whenever you see a //comment. That's to denote that in the other version that line is commented out.

The version that does work uses:

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);


The version that does not work uses:

glVertexAttribFormat(0, 3, GL_FLOAT, GL_FALSE, 0); //comment
glVertexAttribBinding(0,0); //comment

glBindVertexBuffers(0, 2, ptrs, offsets, strides); //comment


The difference between working and not working is having a purple triangle vs having a black screen.

It seems that the error comes from the line

glBindVertexBuffers(0, 2, ptrs, offsets, strides); //comment


As having that line present results in a black screen regardless of the rest of the code.

Strides cannot be zero.

Try:

int strides[] = { (int)sizeof(vec3), (int)sizeof(vec3)};
glBindVertexBuffers(0, 2, ptrs, offsets, strides); //comment


Otherwise, even if it was a valid OpenGL value, you'd be sending the same vector over and over.

This is the value to advance the feed pointer by when sending the next attribute to the vertex shader.

glVertexAttribPointer used to deduce automatically the stride when set to 0 for tightly packed values but neither glBindVertexBuffers nor glBindVertexBuffer have that feature. This was done to simplify driver code and reduce overhead.

• To clarify, strings in glBindVertexBuffer(s) cannot be 0. OpenGL cannot compute the stride based on a format that it doesn't have, so the stride always has to be provided by you. – Nicol Bolas Apr 25 '18 at 15:40