我应该使用相同的 VBO 来传递不同的顶点属性吗?还是我应该使用 2?

Posted

技术标签:

【中文标题】我应该使用相同的 VBO 来传递不同的顶点属性吗?还是我应该使用 2?【英文标题】:Should I use the same VBO for passing different vertex attributes? Or should I use 2? 【发布时间】:2015-05-25 17:19:09 【问题描述】:

我知道glVertexAttribPointer 将使用调用时绑定的 VBO 中的值。但是你能在同一个对象上缓冲两次吗?它会取代里面的东西吗?或者你能清除缓冲区吗?不知道这种做法对不对:

glBindVertexArray(VAO);

glBindBuffer(GL_ARRAY_BUFFER, VBO); // shared VBO

glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(posLoc);
glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 3*sizeof(GLfloat),(GLvoid*)0);


glBufferData(GL_ARRAY_BUFFER,  sizeof(colours),  colours, GL_STATIC_DRAW);
glEnableVertexAttribArray(colLoc);
glVertexAttribPointer(colLoc, 4, GL_FLOAT, GL_FALSE, 4*sizeof(GLfloat),(GLvoid*)0);

glBindBuffer(GL_ARRAY_VERTEX, 0);
glBindVertexArray(0);

或者如果我应该使用 2 个 VBO 来缓冲数据。如果对同一个绑定的顶点数组对象调用两次glBufferData 函数会发生什么?这是我会想到的另一种方法:

glBindVertexArray(VAO);

glBindBuffer(GL_ARRAY_BUFFER, VBO1); // VBO for vertices

glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(posLoc);
glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 3*sizeof(GLfloat),(GLvoid*)0);

glBindBuffer(GL_ARRAY_BUFFER, VBO2); // VBO for colours

glBufferData(GL_ARRAY_BUFFER,  sizeof(colours),  colours, GL_STATIC_DRAW);
glEnableVertexAttribArray(colLoc);
glVertexAttribPointer(colLoc, 4, GL_FLOAT, GL_FALSE, 4*sizeof(GLfloat),(GLvoid*)0);

glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);

【问题讨论】:

【参考方案1】:

上面的示例不起作用,因为第二个 glBufferData 调用将覆盖第二个中的所有缓冲区空间。要正确执行此操作,您必须正确使用跨步和指针参数,以便数据交错。拥有多个 VBO 会更容易(并且更简洁),每个 VBO 都存储一组单独的数据。

【讨论】:

感谢您的回答。我知道你的意思,但我在想我们是否可以使用多个 VBO。那么每个 VAO 是否只有 1 个 VBO?我也听说过glBufferSubData 我也可以使用它。问题是我想将顶点属性保存在单独的 C++ 数组中并单独缓冲它们。所以我想我需要使用glBufferSubData? 多个 VBO 用于 VAO 是我的建议(也许我的回答没有说​​清楚,我会更新它),这就是您在第二个示例中所做的。 glBufferSubData用于更新VBO的一部分,对于更新现有的VBO非常有用,但一般不用于初始化(除非数据非常大,可能要增量发送) 好的,我明白了:D 谢谢。但是第二个例子呢?我看到了其他人的方法,我认为它也会起作用。我在这个文件里看到了github.com/BennyQBD/ModernOpenGLTutorial/blob/master/mesh.cpp 是的,你的第二个例子就是我的建议:)

以上是关于我应该使用相同的 VBO 来传递不同的顶点属性吗?还是我应该使用 2?的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL Instancing VBO - 每个顶点,每个实例的属性

使用 VBO 在 OpenGL 中渲染人群

一个 VBO 可以绑定多个 VAO 吗?

配置VAO和VBO时,顶点数据数组是不是应该使用相同的方法? (OpenGL)[重复]

将两个不同的网格放在同一个顶点 VBO 中的 OpenGL 最佳实践

在不同的 VBO 中存储不同的顶点属性