2013-03-13 45 views
8

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

OpenGL教程这个函数使用最后一个参数的数值偏移量(通过强制转换为常量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); 

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

回答

25

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

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

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

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

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

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

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

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

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

+0

完美的解释!谢谢。 - 你从哪里得到这些信息?我找不到有关这方面的文件。 - 你说OpenGL3.1而不使用内存客户端对OpenGLEs 2.0也有效? – MatterGoal 2013-03-13 09:10:19

+0

@MatterGoal:一般来说,应用程序总是使用客户端内存或缓冲区对象。所以没有人需要谈论它们之间的差异。大部分的桌面OpenGL文档都转向了核心配置文件行为,所以它也不会谈论它。但是它正好在[GL ES的手册页](http://www.khronos.org/opengles/sdk/docs/man/xhtml/glVertexAttribPointer.xml)中。请阅读说明的第二段。 – 2013-03-13 09:15:03

+0

@MatterGoal:它也在[这个答案](http://stackoverflow.com/a/5402762/734069)中解释了相关的问题。 – 2013-03-13 09:17:00

1

GL spec清楚地提到了这一点:

壳体1:如果在指定的一个通用的顶点属性阵列非零命名缓冲器对象绑定到GL_ARRAY_BUFFER目标,指针将被视为一个字节偏移到缓冲对象的数据存储。

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

相关问题