在OpenGL和OpenGLES中使用glVertexAttribPointer

时间:2013-03-13 08:44:34

标签: java opengl opengl-es

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

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

我无法理解这两个功能是如何工作的。它们是完全不同的功能吗?

2 个答案:

答案 0 :(得分:25)

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

重要的是他们正在做的事情。他们正在做的事情取决于你没有展示的东西: GL_ARRAY_BUFFER的约束。

请参阅glVertexAttribPointer 的行为,具体取决于此。如果在调用GL_ARRAY_BUFFER时没有绑定到glVertexAttribPointer的缓冲区对象,则该函数将假定最终值为指针(如函数名称所示:glVertexAttrib < b>指针的)。具体来说,它是指向客户端拥有的内存的指针。

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

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

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

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

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

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

答案 1 :(得分:1)

GL spec明确提到了这一点:

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

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