我正在阅读有关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);
我不明白这两个功能是如何工作的。它们的功能完全不同吗?
最佳答案
它们是通过两种不同方式使用的相同功能。我会解释为什么它会以这种方式工作,但是您不会在意,这是出于非常愚蠢和无关紧要的原因。
重要的是他们在做什么。他们正在做什么取决于您未显示的内容:GL_ARRAY_BUFFER
绑定(bind)了什么。
请参见,glVertexAttribPointer
的行为随其而变化。如果在调用GL_ARRAY_BUFFER
时没有绑定(bind)到glVertexAttribPointer
的缓冲区对象,则该函数将假定最终值是一个指针(如函数名称所示:glVertexAttribPointer)。具体来说,它是指向客户端拥有的内存的指针。
当需要渲染时,顶点属性数据将来自先前提供的指针。因此,第二个示例仅使用以标准C样式声明的客户端数据数组作为源数据。不涉及任何缓冲区对象。
注意:OpenGL 3.1+的核心配置文件删除了使用客户端内存的功能;在那里,您必须使用缓冲区对象,如下所述。
如果在调用GL_ARRAY_BUFFER
时将缓冲区对象绑定(bind)到glVertexAttribPointer
,则会发生一些特殊情况。 OpenGL会假装指针(就C/C++而言,这是最终参数)实际上是绑定(bind)到GL_ARRAY_BUFFER
的缓冲区的字节偏移量。它将指针转换为整数,然后存储该整数偏移量和当前绑定(bind)到GL_ARRAY_BUFFER
的缓冲区对象。
因此,以上代码采用3*sizeof(GLfloat)
(字节偏移量),并将其转换为指针。 OpenGL将获取指针并将其转换回偏移量,再次产生3*sizeof(GLfloat)
。
当需要渲染时,OpenGL将使用先前给定的偏移量从先前给定的缓冲区对象中读取。
第一个示例将顶点数据放入GPU内存中的缓冲区对象中。第二个示例将顶点数据放入CPU内存中的常规C/C++数组中。
关于java - OpenGL和OpenGLES中的glVertexAttribPointer,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15380491/