OpenGL:如何使用buffer_objects绘制

时间:2011-01-19 23:11:52

标签: opengl

在OpenGL红皮书的第103页中,他们给出了一个关于如何使用buffer_object绘制内容的示例(例2-17)。

#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));

在这里,我们假设有一个数组指向我们将在哪个数组中找到数据。那应该是指向服务器中某个内存地址的指针吗?

我只是不明白BUFFER_OFFSET(0)。

这是否意味着服务器中始终只有一个Vertex_Array,程序会自动选择该地址? BUFFER_OFFSET(0)只是告诉你从这个数组开始的地方?????????????

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));

这里也是一样的。我们假设在最后一个参数给出一个地址。但我没有看到BUFFER_OFFSET(0)是一个有用的地址。

3 个答案:

答案 0 :(得分:2)

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

最后一个参数指向某个内存地址。不管怎么说。

它说“使用当前绑定缓冲区的偏移量0”。

您已致电

glBindBuffer(GL_ARRAY_BUFFER, buffers[VERTICES]);

因此,这两个调用的耦合(首先绑定,VertexPointer为秒)实质上意味着“使用缓冲区的地址,缓冲区的句柄是缓冲区[VERTICES],偏移量为0”。

答案 1 :(得分:1)

如果存在绑定的缓冲区,则将指定给glDrawElements的指针视为该缓冲区的偏移量而不是常规指针。

需要BUFFER_OFFSET,因为原始的ARB_vertex_buffer_object扩展想要使用相同的函数原型,因此有必要将整数偏移转换为指针。

请参阅OpenGL.org wiki中的更多信息。

答案 2 :(得分:1)

当您有交错数据或缓冲区中未紧密打包的数据时,偏移量会很有用。零步幅假设数据紧凑。零偏移告诉OpenGL您的数据立即开始。一个例子如下。使用当前方法,您需要一个单独的缓冲区用于顶点和法线。但是,您可以交错该数据:

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

然后您可以将该数据绑定到缓冲区。然后当你告诉OpenGL绑定缓冲区时,你需要让它知道步幅和偏移量。假设您有一个包含交错顶点和普通数据的浮点数组,您的示例可能会变为

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)); 

请注意,stride的值是6 * sizeof(GLfloat),表示缓冲区中连续条目之间有24个字节。正常指针的偏移量为3 * sizeof(GLfloat),表示正常数据从缓冲区的起始位置偏移了12个字节。

希望这有帮助 - 如果我犯了错误,请告诉我。