glGenVertexArrays and glGenBuffers arguments

In a tutorial about OpenGL 3.0+, we create a Vertex Array Object and Vertex Buffer Object this way:

GLuint VAO, VBO; glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); 

Here, VAO is an unsigned int (GLuint) and we pass a̶ ̶r̶e̶f̶e̶r̶e̶n̶c̶e̶ its address to it in the function glGenVertexArray. However, according to the documentation, the second argument of the function should be an array of unsigned int (GLuint*). Same goes for VBO and glGenBuffers. I don't understand why the above code works with such arguments.

I've tried to replace the above code by this one (and do the necessary modifications elsewhere in my code) :

GLuint VAO[1]; GLuint VBO[1]; glGenVertexArrays(1, VAO); glGenBuffers(1, VBO); glBindVertexArray(VAO[1]); glBindBuffer(GL_ARRAY_BUFFER, VBO[1]); 

It compiles and executes, but I get an unexpected behaviour : my textured rectangle renders with the first syntax but not with the second one. I don't understand why this happens as well.

EDIT : Thank you. As stated, there is an indexing mistake in the second code.

2

3 Answers

The function signature in the specs is:

void glGenVertexArrays( GLsizei n, GLuint *arrays); 

So arrays expects a GLuint pointer where it is valid to write n * sizeof(GLuint) bytes of data to.

It is perfectly fine and valid to write:

GLuint VAO, VBO; glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); 

Because glGenVertexArrays wants to have an pointer to GLuint where it is valid to write n * sizeof(GLuint) bytes of data to (in your case 1) and because VAO can hold this amount of data, it is correct to write it that way. And and is preferable if you create only one id per call.

As already stated by others the first element in an array has the index 0. As of that it has to be:

GLuint VAO[1]; GLuint VBO[1]; glGenVertexArrays(1, VAO); glGenBuffers(1, VBO); glBindVertexArray(VAO[0]); glBindBuffer(GL_ARRAY_BUFFER, VBO[0]); 

If you want to create more elements in one call, you want to use std::array over [].

std::array<GLuint,3> VAOs; std::array<GLuint,3> VBOs; glGenVertexArrays(VAOs.size(), &VAOs[0]); glGenBuffers(VBOs.size(), &VBOs[0]); 

As a note unsigned int and GLuint does not necessarily the same type or size, unsigned int has a minimum guaranteed number range, but the size could still vary on different platforms. GLuint on the other hand has a defined size.

1

First index is 0

GLuint VAO[1]; GLuint VBO[1]; glGenVertexArrays(1, VAO); glGenBuffers(1, VBO); glBindVertexArray(VAO[0]); glBindBuffer(GL_ARRAY_BUFFER, VBO[0]); 

An array in C and C++ is represented as a pointer. Putting this the other way around, a pointer is equivalent to an array of one element. Therefore, if you are creating a single buffer object, you can simply declare a single variable and pass a pointer to it like you do in your first example (it's not a reference, it's a pointer) and there is nothing wrong with that. I've always done it that way myself.

For why your second example doesn't work, see Jonathan Olson's answer above.

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

You Might Also Like