2

In page 103 of OpenGL redbook, they give an example (example 2-17) about how to use buffer_object to draw something.

#define BUFFER_OFFSET(bytes) ((GLubyte*) NULL + (bytes))


GLuint buffers[NUM_BUFFERS];

GLfloat vertices[][3] = {
{ -1.0, -1.0, -1.0 },
{ 1.0, -1.0, -1.0 },
{ 1.0, 1.0, -1.0 },
{ -1.0, 1.0, -1.0 },
{ -1.0, -1.0, 1.0 },
{ 1.0, -1.0, 1.0 },
{ 1.0, 1.0, 1.0 },
{ -1.0, 1.0, 1.0 }
};

GLubyte indices[][4] = {
{ 0, 1, 2, 3 },
{ 4, 7, 6, 5 },
{ 0, 4, 5, 1 },
{ 3, 2, 6, 7 },
{ 0, 3, 7, 4 },
{ 1, 5, 6, 2 }
};

glGenBuffers(NUM_BUFFERS, buffers);
//Generate NUM_BUFFERS of buffers and put them in buffers array.

glBindBuffer(GL_ARRAY_BUFFER, buffers[VERTICES]);
//bind buffers


glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
//allocate space for buffers


glVertexPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0));

Here, we suppose to have a point to a array to specify in which array we will find the data. Then is that should be a pointer to some memory address in server?

I just do not understand that BUFFER_OFFSET(0).

Does that mean that there is always only one Vertex_Array in server and the program will choose that address automatically? The BUFFER_OFFSET(0) just tell you where to start in this array?????????

glEnableClientState(GL_VERTEX_ARRAY);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[INDICES]);

glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, BUFFER_OFFSET(0));

Same thing here. We suppose to give a address at the last parameter. But I do not see that BUFFER_OFFSET(0) is a useful address.

3 Answers 3

2
glVertexPointer(3, GL_FLOAT, 6 * sizeof(GLfloat), BUFFER_OFFSET(0))

The last parameter does not point to some memory address. Not directly anyways.

It says "use the offset 0 of the currently bound buffer".

You have called

glBindBuffer(GL_ARRAY_BUFFER, buffers[VERTICES]);

So the coupling of these 2 calls (bind first, VertexPointer second) essentially means "use the address of the buffer whose handle is buffer[VERTICES], offset by 0".

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks. So is there always only one GL_ARRAY_BUFFER? I mean if I bind two GL_ARRAY_BUFFERsm, say buffers[0] and buffers[1]. Which one does program choose?
@NoviceCai: it remembers the one that was bound at the time you called the *Pointer call. so BindBuffer(a)/VertexPointer/BindBuffer(b)/NormalPointer will use buffer a for vertex and b for normal
Thank you so much. I also read this opengl.org/wiki/Vertex_Array_Object
1

If there is a buffer binded, that pointer given to glDrawElements is treated as an offset to that buffer and not as a regular pointer.

BUFFER_OFFSET is needed because the original ARB_vertex_buffer_object extension wanted to use the same function prototype, so it's necessary to convert integer offset to a pointer.

See some more information in OpenGL.org wiki.

1 Comment

But I mean, for this function glVertexPointer(3, GL_FLOAT, 6 * sizeof(GLfloat), BUFFER_OFFSET(0)); The last parameter is a pointer to some memory address, right? But BUFFER_OFFSET(0) is not a memory address, at least is not a normal memory address, which confuse me. So how this function find the right array??
1

The offset becomes useful when you have interleaved data, or data in the buffer that is not tightly packed. A stride of zero assumes tightly packed data. An offset of zero tells OpenGL that your data starts right away. An example could be as follows. Using your current method, you would need a separate buffer for vertices and normals. However, you could interleave that data:

vertex.x, vertex.y, vertex.z, normal.x, normal.y, normal.z

And then you could bind that data to a buffer. Then when you tell OpenGL to bind the buffer you need to let it know the stride and offsets. Assuming you have an array of floats that contains the interleaved vertex and normal data, your example could become

glGenBuffers(NUM_BUFFERS, buffers);
glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(interleaved_data), interleaved_data, GL_STATIC_DRAW);
glVertexPointer(3, GL_FLOAT, 6 * sizeof(GLfloat), BUFFER_OFFSET(0));
glNormalPointer(3, GL_FLOAT, 6 * sizeof(GLfloat), BUFFER_OFFSET(3 * sizeof(GLfloat)); 

Notice the value of stride is 6 * sizeof(GLfloat), which indicates that there are 24 bytes between successive entries in the buffer. And the offset of the normal pointer is 3 * sizeof(GLfloat), which indicates that the normal data is offset by 12 bytes from the start of the buffer.

Hopefully this helps - let me know if I've made a mistake.

2 Comments

But I mean, for this function glVertexPointer(3, GL_FLOAT, 6 * sizeof(GLfloat), BUFFER_OFFSET(0)); The last parameter is a pointer to some memory address, right? But BUFFER_OFFSET(0) is not a memory address, at least is not a normal memory address, which confuse me. So how this function find the right array??
You've already bound the vertex object with glBindBuffer. glVertexPointer is just letting OpenGL know that it should use the contents of that array for the vertex positions.

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.