0
\$\begingroup\$

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.

\$\endgroup\$
2
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ 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. \$\endgroup\$ – Nicol Bolas Apr 25 '18 at 15:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.