为什么在调用 glDrawArray 之前不需要绑定顶点缓冲区对象?

Why don't I need to bind my vertex buffer object before calling glDrawArrays?

本文关键字:顶点 绑定 缓冲区 对象 不需要 调用 glDrawArray 为什么      更新时间:2023-10-16

我有点困惑为什么这仍然呈现。我认为您需要绑定一个顶点缓冲区对象,以便glDrawArrays知道要使用哪个顶点缓冲区。

这是我的初始化代码。

// Create and bind vertex array to store vertex attribute states.
glGenVertexArraysOES(NUM_VERTEX_ARRAYS, &m_vertexArray);
glBindVertexArrayOES(m_vertexArray);
// Create and bind vertex buffer to store vertex data.
glGenBuffers(NUM_VERTEX_BUFFERS, &m_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * 36, &m_vertices[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(VertexAttribPosition);
glVertexAttribPointer(VertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
glEnableVertexAttribArray(VertexAttribNormal);
glVertexAttribPointer(VertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArrayOES(0);

这是我的渲染代码。我很困惑为什么当我将 0 绑定到 GL_ARRAY_BUFFER 时 glDrawArrays 仍然有效。

glBindVertexArrayOES(m_vertexArray);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDrawArrays(GL_TRIANGLES, 0, 36);
glBindVertexArrayOES(0);

我认为您需要绑定一个顶点缓冲区对象,以便glDrawArrays知道要使用哪个顶点缓冲区。

调用glDraw…时,它使用最近调用gl…Pointer(或等效)调用并由glEnableVertexAttribArray激活的数据。当你这样做时

glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
glVertexAttribPointer(VertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
glVertexAttribPointer(VertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));

在(活动)顶点属性和缓冲区对象之间形成关联。或者换句话说: glBindBuffer仅与glBuffer…gl…Pointer呼叫的调用相关。因此,您可以在调用 gl…Pointer 函数后安全地绑定不同的缓冲区对象。事实上,以下内容也可以工作:

glBindBuffer(GL_ARRAY_BUFFER, m_vertexPositionBuffer);    
glVertexAttribPointer(VertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
glBindBuffer(GL_ARRAY_BUFFER, m_vertexNormalBuffer);    
glVertexAttribPointer(VertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));

即,每个顶点属性数组使用不同的缓冲区对象。

更新

顶点数组对象为此添加了一些糖衣,方法是将绑定→指针/偏移关联保留在对象中,而对象本身可以绑定。因此,切换到新的(一组)缓冲区对象变得工作量更少。

您使用的是顶点数组对象,因此所有数据都已记录到 VAO 中。以下是VAO保存哪些数据的良好解释 http://www.altdevblogaday.com/2013/10/18/ios-open-gl-es-2-multiple-objects-at-once/