在OpenGL中,为什么glVertexAttribPointer需要"指针"要作为void *传递的参数?

时间:2015-01-21 09:10:33

标签: opengl

glVertexAttribPointer的规范如下:

void glVertexAttribPointer( GLuint index,
    GLint size,
    GLenum type,
    GLboolean normalized,
    GLsizei stride,
    const GLvoid * pointer);

鉴于最后一个参数只是一个4字节的整数偏移量,为什么OpenGL希望它作为void指针传入?

2 个答案:

答案 0 :(得分:9)

这个论点在VBO之前有不同的含义:你将顶点数据保存在客户端内存中并传递数组的地址(参见glEnableClientState等)。

现在最后一个参数可以有2个含义(缓冲区对象的偏移量,客户端状态数组的地址)。 Khronos没有为缓冲区对象的gl*Pointer函数提供单独的版本,所以你需要做这个笨拙的演员。

答案 1 :(得分:2)

查看它的一种方法是最后一个参数始终是一个指针:

  • 如果没有绑定VBO,它是一个相对于基地址0的指针。这是一个常规的内存地址,就像指针在C / C ++中通常使用的那样。
  • 如果VBO绑定,则它是一个相对于缓冲区基址的指针。

至少那是我能找到的唯一合乎逻辑的解释。

就我个人而言,我认为以这种方式超载入口点是一个非常不幸的决定,原因有很多:

  • 让人们感到困惑。
  • 它需要在C / C ++中使用丑陋的类型转换。
  • 它在Java等更安全的语言中根本不起作用。

在Java等语言中,您通常会遇到接受不同类型的函数的重载版本。作为一个有点奇怪的历史记录,Android中int绑定的初始版本中缺少带有GLES20参数的重载版本,这意味着您无法使用Java中的VBO。因此,这偶尔会让偶然的OpenGL程序员绊倒更多。