1

所以,我之前使用了顶点数组缓冲区(Core Profile 3.3),设置如下:

int offset = 0;

glGenVertexArrays(1, &m_vba);
glBindVertexArray(m_vba);
glGenBuffers(1, &m_vbo);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);

glBufferData(GL_ARRAY_BUFFER, TOTAL_DATA_SIZE, nullptr, GL_STATIC_DRAW);

// Vertex data
glBufferSubData(GL_ARRAY_BUFFER, offset, VERTEX_DATA_SIZE, vertices);
offset += VERTEX_DATA_SIZE;

// Normal data
glBufferSubData(GL_ARRAY_BUFFER, offset, NORMAL_DATA_SIZE, normals);
offset += NORMAL_DATA_SIZE;

glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<GLvoid *>(VERTEX_DATA_SIZE));

我没有使用索引缓冲区。像这样渲染:

glBindVertexArray(m_vba);    
glDrawArrays(GL_TRIANGLES, 0, NUM_VERTICES);

这工作得很好。但是,我发现 glGenVertexArrays() 可能不可用,例如在 Android 上。因此我开始删除它。还有一个让我发疯的问题。

如果我像这样从数据初始化中删除 vba 内容:

int offset = 0;

glGenBuffers(1, &m_vbo);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);

glBufferData(GL_ARRAY_BUFFER, TOTAL_DATA_SIZE, nullptr, GL_STATIC_DRAW);

// Vertex data
glBufferSubData(GL_ARRAY_BUFFER, offset, VERTEX_DATA_SIZE, vertices);
offset += VERTEX_DATA_SIZE;

// Normal data
glBufferSubData(GL_ARRAY_BUFFER, offset, NORMAL_DATA_SIZE, normals);
offset += NORMAL_DATA_SIZE;

glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<GLvoid *>(VERTEX_DATA_SIZE));

..并像这样渲染:

glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<GLvoid *>(VERTEX_DATA_SIZE));

glDrawArrays(GL_TRIANGLES, 0, NUM_VERTICES);

..我只是黑屏。我不明白的是,如果我在代码中的某处添加,例如在数据设置之后:

GLuint foo;
glGenVertexArrays(1, &foo);
glBindVertexArray(foo);

然后一切都再次正确渲染。是否有一些副作用导致这种情况?设置后我不再绑定这个“foo”缓冲区,尽管多个对象使用它们自己的类似缓冲区顺序渲染,它仍然有效!

显然事情并没有像我预测的那样发展 :) 问题是,删除 glGenVertexArrays() 后我应该在我的代码中更改什么?我做错了什么?

4

1 回答 1

4

在 GL 3.x 核心配置文件中使用用户生成的 VAO 只是强制性的。从 3.3 核心规范中,E2.2 删除了以下特性:

客户端顶点和索引数组 - 所有顶点数组属性和元素数组索引指针必须引用缓冲区对象。默认的顶点数组对象(名称为零)也已弃用。在没有绑定缓冲区对象或没有绑定顶点数组对象 时调用 VertexAttribPointer会产生一个 INVALID_OPERATION 错误,当没有绑定顶点数组对象时调用任何数组绘制命令也会产生错误。

于 2013-04-27T18:28:08.577 回答