0
votes

This is some simple code that draws to the screen.

GLuint vbo;

glGenBuffers(1, &vbo);

glUseProgram(myProgram);

glBindBuffer(GL_ARRAY_BUFFER, vbo);

glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);

//Fill up my VBO with vertex data
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexes), &vertexes, GL_STATIC_DRAW);

/*Draw to the screen*/

This works fine. However, I tried changing the order of some GL calls like so:

GLuint vbo;

glGenBuffers(1, &vbo);

glUseProgram(myProgram);

glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);

//Now comes after the setting of the vertex attributes.
glBindBuffer(GL_ARRAY_BUFFER, vbo);

//Fill up my VBO with vertex data
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexes), &vertexes, GL_STATIC_DRAW);

/*Draw to the screen*/

This crashes my program. Why does there need to be a VBO bound to GL_ARRAY_BUFFER while I'm just setting up vertex attributes? To me, what glVertexAttribPointer does is just set up the format of vertexes that OpenGL will eventually use to draw things. It is not specific to any VBO. Thus, if multiple VBOs wanted to use the same vertex format, you would not need to format the vertexes in the VBO again.

2

2 Answers

3
votes

I believe that's because the last argument to glVertexAttribPointer is pointer which is an offset into a the VBO after glBindBuffer(nonzero) but when a VBO is not bound it's supposed to be a pointer to an actual array of data. So if you weren't using VBOs at all the last argument would be &vertexes and it wouldn't crash.

3
votes

Why does there need to be a VBO bound to GL_ARRAY_BUFFER while I'm just setting up vertex attributes?

No, you're not "just" setting up vertex attributes. You're actually creating a reference with the currently bound buffer object.

If there's no buffer object bound, then gl…Pointer will create a reference to your process address space pointed at the given address. Since this is a null pointer in your case, any attempt to dereference a vertex will cause a segmentation fault/access violation.

To me, what glVertexAttribPointer does is just set up the format of vertexes that OpenGL will eventually use to draw things.

No. It also creates a reference to where to get the data from.

It is not specific to any VBO.

Yes it actually is specific to the bound VBO, or the process address space if no VBO is bound. And changing the buffer binding will not update along the gl…Pointer references.