opengl - 什么时候应该调用 glVertexAttribPointer?

标签 opengl

glVertexAttribPointer 时,从文档中并不明显。应该调用。看起来它是 VBO 初始化的一部分,但我注意到在渲染过程中调用它的示例代码。
glVertexAttribPointer(vertexAttributeId, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), reinterpret_cast<const GLvoid*>(offsetof(Vertex2D, m_x)));
应该 glVertexAttribPointer在初始化 GL_ARRAY_BUFFER 期间调用还是应该在渲染期间调用它(在调用 glBindBuffer 之后)?

最佳答案

函数glVertexAttribPointer指定渲染某些东西(即下一个 glDraw... 调用)时使用的顶点属性的格式和源缓冲区(忽略不推荐使用的客户端数组)。

现在有两种情况。您要么使用顶点数组对象 (VAO),要么不使用(尽管在现代 OpenGL 中不推荐使用和不鼓励/禁止使用 VAO)。如果您不使用 VAO,那么您通常会调用 glVertexAttribPointer (以及相应的 glEnableVertexAttribArray )在渲染之前正确设置状态。但是,如果使用 VAO,您实际上会在 VAO 创建代码(通常是某些初始化或对象创建的一部分)中调用它(和启用函数),因为它的设置存储在 VAO 中,渲染时您需要做的就是绑定(bind) VAO 并调用绘图函数。

但无论何时调用glVertexAttribPointer ,您应该在之前绑定(bind)相应的缓冲区(无论何时实际创建和填充),因为 glVertexAttribPointer函数设置当前绑定(bind)的GL_ARRAY_BUFFER作为此属性的源缓冲区(并存储此设置,因此之后您可以自由绑定(bind)另一个 VBO)。

因此,在使用 VAO(推荐)的现代 OpenGL 中,它通常类似于以下工作流程:

//initialization
glGenVertexArrays
glBindVertexArray

glGenBuffers
glBindBuffer
glBufferData

glVertexAttribPointer
glEnableVertexAttribArray

glBindVertexArray(0)

glDeleteBuffers //you can already delete it after the VAO is unbound, since the
                //VAO still references it, keeping it alive (see comments below).

...

//rendering
glBindVertexArray
glDrawWhatever

当不使用 VAO 时,它会是这样的:
//initialization
glGenBuffers
glBindBuffer
glBufferData

...

//rendering
glBindBuffer
glVertexAttribPointer
glEnableVertexAttribArray
glDrawWhatever

关于opengl - 什么时候应该调用 glVertexAttribPointer?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17149728/

相关文章:

c - 用 C 实现 OpenGL 中的绝对定位

Java OpenGL 三角形未显示

c++ - 从深度缓冲区重建位置 - 缺少 Z?

c - 什么更好 : a single BAO or multiple BAOs

c++ - 为什么我在包含加载程序 header 时无法使用 OpenGL 函数?

OpenGL 四边形条未显示

windows - 如何使用特定的图形驱动程序创建 OpenGL 上下文?

opengl - 有没有一种简单的方法可以在love2d中绘制渐变?

c++ - 使用 phong 照明的纹理映射

qt - QGLWidget - 发生失真