10

我正在阅读有关 OpenGL 和 OpenGLES 的教程,我对glVertexAttribPointer在这两个 API 中使用该函数有点困惑。

OpenGL教程中,此函数使用数字偏移作为最后一个参数(通过转换为 const GLVoid*),我认为顶点直接取自当前数组缓冲区。

glVertexAttribPointer(vs_position, 2, GL_FLOAT, GL_TRUE, 5 * sizeof(GLfloat), (const GLvoid*) (3*sizeof(GLfloat)) );

OpenGLES教程中,最后一个参数直接指向表示顶点的结构:

GLFloat vertices[] = {...definition};
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vertices);

我不明白这两个功能是如何工作的。它们是完全不同的功能吗?

4

2 回答 2

26

它们是以两种不同的方式使用的相同功能。我会解释为什么它会这样工作,但你不会在乎,这是出于非常愚蠢和不相关的原因。

重要的是他们在做什么。他们在做什么取决于你没有展示的东西:什么是GL_ARRAY_BUFFER.

看,glVertexAttribPointer 变化的行为取决于它。如果在GL_ARRAY_BUFFER调用时没有绑定缓冲区对象glVertexAttribPointer,则函数将假定最终值是一个指针(如函数名称所示: glVertexAttrib Pointer)。具体来说,它是指向客户端拥有的内存的指针。

渲染时,顶点属性数据将来自先前提供的指针。因此,第二个示例只是使用以标准 C 样式声明的客户端数据数组作为源数据。不涉及缓冲区对象。

注意:OpenGL 3.1+ 的核心配置文件移除了使用客户端内存的能力;在那里,您必须使用缓冲区对象,如下所述。

如果一个缓冲区对象被绑定到GL_ARRAY_BUFFERwhenglVertexAttribPointer被调用,那么就会发生一些特殊的事情。OpenGL 将假装指针(就 C/C++ 而言,这是最终参数)实际上是绑定GL_ARRAY_BUFFER. 它将指针转换为整数,然后存储该整数偏移量和当前绑定到的缓冲区对象GL_ARRAY_BUFFER

因此,上面的代码采用3*sizeof(GLfloat)字节偏移量,并将其转换为指针。OpenGL 将获取指针并将其转换回偏移量,3*sizeof(GLfloat)再次产生。

当需要渲染时,OpenGL 将使用之前给定的偏移量从之前给定的缓冲区对象中读取。

第一个示例将顶点数据放入 GPU 内存中的缓冲区对象中。第二个示例将顶点数据放在 CPU 内存中的常规 C/C++ 数组中。

于 2013-03-13T09:04:16.397 回答
1

GL 规范清楚地提到了这一点:

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

情况 2:指定指向数组中第一个通用顶点属性的第一个组件的指针。

于 2014-02-26T18:14:03.417 回答