1

在 iOS 5 的股票“旋转立方体”OpenGL 示例中,他们有以下代码:

glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW);

glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));

混乱的部分是glVertexAttribPointer. 文档说最后一个参数是指向数组的指针。

但在这个程序中,他们使用的是直数。确实,BUFFER_OFFSET定义为

#define BUFFER_OFFSET(i) ((char *)NULL + (i))

那么他们是否依赖于gCubeVertexData从内存地址 0 开始的数组?

所以,我不明白两件事:

  1. 为什么当我“更正”第三行代码时示例不起作用(没有绘制立方体)

    glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, gCubeVertexData );
    
  2. 调用 glVertexAttribPointer 的正确方法是什么?

我认为你应该为最后一个索引传递一个内存指针,如文档所述。实际上,这里的另一个示例使用了 glVertexAttribPointer:

glVertexAttribPointer(ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, sizeof(vertexStruct), &vertices[0].position);
glEnableVertexAttribArray(ATTRIB_POSITION);
glVertexAttribPointer(ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(vertexStruct), &vertices[0].color);
glEnableVertexAttribArray(ATTRIB_COLOR);

所以你在后一个例子中看到他们传递了指针(最后一个参数)的内存地址,而不是直数。

4

1 回答 1

2

glVertexAttribPointer 可以通过两种方式使用:

1) 使用客户端顶点数组。在这种情况下,最后一个参数是一个指向数组的指针,你是对的。

2)除了用作指针之外,如果您在链接的文档页面中进一步阅读,它会显示:

如果一个非零命名缓冲区对象绑定到 GL_ARRAY_BUFFER 目标(请参阅 glBindBuffer),同时指定了一个通用顶点属性数组,则指针被视为缓冲区对象数据存储中的字节偏移量。

这适用于当您使用 glVertexAttribPointer 指向 VBO 时,您之前已上传到 opengl (glBindBuffer/glBufferData) 的缓冲区。

澄清:

如果您没有与 glBindBuffer 绑定的活动缓冲区,则 glVertexAttribArray 需要一个指针。如果确实有缓冲区绑定,则 glVertexAttribArray 将偏移量放入绑定缓冲区。0如果您想从缓冲区的开头开始绘制,这将是该值。

于 2012-09-06T05:33:33.147 回答