在 VAO 中使用多个 VBO
Using multiple VBO in a VAO
我尝试在 VAO 中使用 2 个 VBO,但最终崩溃(远远超出了我的应用程序)。
我们的想法是制作第一个 VBO(以及可选的 IBO)来构造几何体。
这很有效,直到我想到为模型矩阵添加第二个 VBO 作为顶点属性而不是统一。
所以,当我声明我的网格时,我会按照以下步骤操作(简化代码):
GLuint vao = 0;
glCreateVertexArrays(1, &vao);
glBindVertexArray(vao);
GLuint vbo = 0;
glCreateBuffers(1, &vbo);
glNamedBufferStorage(vbo, ...); // Fill the right data ...
for ( ... my attributes ) // Position, normal, texcoords ...
{
glVertexArrayAttribFormat(vao, attribIndex, size, GL_FLOAT, GL_FALSE, relativeOffset);
glVertexArrayAttribBinding(vao, attribIndex, bindingIndex);
glEnableVertexArrayAttrib(vao, attribIndex);
} -> this gives me the "stride" parameter for below.
glVertexArrayVertexBuffer(vao, 0/*bindingindex*/, vbo, 0, stride/*Size of one element in vbo in bytes*/);
GLuint ibo = 0;
glCreateBuffers(1, &ibo);
glNamedBufferStorage(ibo, ...); // Fill the right data ...
glVertexArrayElementBuffer(vao, ibo);
直到那里,一切都很好,我所要做的就是调用 glBindVertexArray() 和 glDrawXXX() 命令,我在屏幕上有完美的东西。
所以,我决定从着色器中删除 modelMatrix 制服以使用 mat4 属性,
我本可以选择 UBO,但我想通过提供多个矩阵将想法扩展到实例化渲染。
因此,我在 VBO 中使用一个模型矩阵进行了测试,在渲染之前,我按照以下步骤操作(VBO 的构建方式与之前相同,我只是为单位矩阵放置了 16 个浮点数):
glBindVertexArray(theObjectVAOBuiltBefore);
const auto bindingIndex = static_cast< GLuint >(1); // Here next binding point for the VBO, I guess...
const auto stride = static_cast< GLsizei >(16 * sizeof(GLfloat)); // The stride is the size in bytes of a matrix
glVertexArrayVertexBuffer(theObjectVAOBuiltBefore, bindingIndex, m_vertexBufferObject.identifier(), 0, stride); // I add the new VBO to the currentle VAO which have already a VBO (bindingindex 0) and an IBO
// Then I describe my new VBO as a matrix of 4 vec4.
const auto size = static_cast< GLint >(4);
for ( auto columnIndex = 0U; columnIndex < 4U; columnIndex++ )
{
const auto attribIndex = static_cast< unsigned int >(VertexAttributes::Type::ModelMatrix) + columnIndex;
glVertexArrayAttribFormat(theObjectVAOBuiltBefore, attribIndex, size, GL_FLOAT, GL_FALSE, 0);
glVertexArrayAttribBinding(theObjectVAOBuiltBefore, attribIndex, bindingIndex);
glEnableVertexArrayAttrib(theObjectVAOBuiltBefore, attribIndex);
glVertexAttribDivisor(attribIndex, 1); // Here I want this attribute per instance.
}
glDrawElementsInstanced(GL_TRIANGLES, count, GL_UNSIGNED_INT, nullptr, 1);
结果是一个漂亮的崩溃,我没有任何线索,因为崩溃发生在我无法获得调试输出的驱动程序中。
我的想法完全是垃圾吗?或者我错过了什么?
我发现错误 glVertexAttribDivisor() 是旧方法的一部分(如 glVertexAttribPointer(), ...),我切换到 glVertexBindingDivisor()/glVertexArrayBindingDivisor() 现在完全没有崩溃。
那里有答案:https://www.khronos.org/opengl/wiki/Vertex_Specification#Separate_attribute_format
我尝试在 VAO 中使用 2 个 VBO,但最终崩溃(远远超出了我的应用程序)。
我们的想法是制作第一个 VBO(以及可选的 IBO)来构造几何体。
这很有效,直到我想到为模型矩阵添加第二个 VBO 作为顶点属性而不是统一。
所以,当我声明我的网格时,我会按照以下步骤操作(简化代码):
GLuint vao = 0;
glCreateVertexArrays(1, &vao);
glBindVertexArray(vao);
GLuint vbo = 0;
glCreateBuffers(1, &vbo);
glNamedBufferStorage(vbo, ...); // Fill the right data ...
for ( ... my attributes ) // Position, normal, texcoords ...
{
glVertexArrayAttribFormat(vao, attribIndex, size, GL_FLOAT, GL_FALSE, relativeOffset);
glVertexArrayAttribBinding(vao, attribIndex, bindingIndex);
glEnableVertexArrayAttrib(vao, attribIndex);
} -> this gives me the "stride" parameter for below.
glVertexArrayVertexBuffer(vao, 0/*bindingindex*/, vbo, 0, stride/*Size of one element in vbo in bytes*/);
GLuint ibo = 0;
glCreateBuffers(1, &ibo);
glNamedBufferStorage(ibo, ...); // Fill the right data ...
glVertexArrayElementBuffer(vao, ibo);
直到那里,一切都很好,我所要做的就是调用 glBindVertexArray() 和 glDrawXXX() 命令,我在屏幕上有完美的东西。
所以,我决定从着色器中删除 modelMatrix 制服以使用 mat4 属性, 我本可以选择 UBO,但我想通过提供多个矩阵将想法扩展到实例化渲染。
因此,我在 VBO 中使用一个模型矩阵进行了测试,在渲染之前,我按照以下步骤操作(VBO 的构建方式与之前相同,我只是为单位矩阵放置了 16 个浮点数):
glBindVertexArray(theObjectVAOBuiltBefore);
const auto bindingIndex = static_cast< GLuint >(1); // Here next binding point for the VBO, I guess...
const auto stride = static_cast< GLsizei >(16 * sizeof(GLfloat)); // The stride is the size in bytes of a matrix
glVertexArrayVertexBuffer(theObjectVAOBuiltBefore, bindingIndex, m_vertexBufferObject.identifier(), 0, stride); // I add the new VBO to the currentle VAO which have already a VBO (bindingindex 0) and an IBO
// Then I describe my new VBO as a matrix of 4 vec4.
const auto size = static_cast< GLint >(4);
for ( auto columnIndex = 0U; columnIndex < 4U; columnIndex++ )
{
const auto attribIndex = static_cast< unsigned int >(VertexAttributes::Type::ModelMatrix) + columnIndex;
glVertexArrayAttribFormat(theObjectVAOBuiltBefore, attribIndex, size, GL_FLOAT, GL_FALSE, 0);
glVertexArrayAttribBinding(theObjectVAOBuiltBefore, attribIndex, bindingIndex);
glEnableVertexArrayAttrib(theObjectVAOBuiltBefore, attribIndex);
glVertexAttribDivisor(attribIndex, 1); // Here I want this attribute per instance.
}
glDrawElementsInstanced(GL_TRIANGLES, count, GL_UNSIGNED_INT, nullptr, 1);
结果是一个漂亮的崩溃,我没有任何线索,因为崩溃发生在我无法获得调试输出的驱动程序中。
我的想法完全是垃圾吗?或者我错过了什么?
我发现错误 glVertexAttribDivisor() 是旧方法的一部分(如 glVertexAttribPointer(), ...),我切换到 glVertexBindingDivisor()/glVertexArrayBindingDivisor() 现在完全没有崩溃。
那里有答案:https://www.khronos.org/opengl/wiki/Vertex_Specification#Separate_attribute_format