我遇到了一些关于顶点数组对象和顶点缓冲区对象的令人讨厌的事情。
代码如下:
float vertex_data[] =
{
0.f, 0.5f, 0.f, 0.f, 1.f,
0.5f, -0.5f, 0.f, 1.f, 0.f,
-0.5f, -0.5f, 1.f, 0.f, 0.f
};
float vertex_data_2[] =
{
0.f, 0.5f, 1.f, 0.f, 0.f,
0.5f, -0.5f, 1.f, 0.f, 0.f,
-0.5f, -0.5f, 1.f, 0.f, 0.f
};
unsigned int indices[] =
{
0, 1, 2
};
unsigned int vertex_array, vertex_array_2;
glGenVertexArrays(1, &vertex_array);
glGenVertexArrays(1, &vertex_array_2);
IndexBuffer index_buffer(3 * sizeof(unsigned int), 3, GL_UNSIGNED_INT, indices);
glBindVertexArray(vertex_array);
VertexBuffer vertex_buffer(3 * 5 * sizeof(float), vertex_data);
vertex_buffer.Bind();
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), reinterpret_cast<void*>(0));
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), reinterpret_cast<void*>(2 * sizeof(float)));
index_buffer.Bind();
glBindVertexArray(vertex_array_2);
VertexBuffer vertex_buffer_2(3 * 5 * sizeof(float), vertex_data_2);
vertex_buffer_2.Bind();
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), reinterpret_cast<void*>(0));
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), reinterpret_cast<void*>(2 * sizeof(float)));
index_buffer.Bind();
Shader shader(Shader::FromFile("rescources/shaders/basic.vs"),
Shader::FromFile("rescources/shaders/basic.fs"));
shader.Bind();
// main loop
while (!glfwWindowShouldClose(glfw_window))
{
glClear(GL_COLOR_BUFFER_BIT);
glClearColor(0.f, 0.f, 0.f, 1.f);
// problem is here
glBindVertexArray(vertex_array);
vertex_buffer_2.Bind();
glDrawElements(GL_TRIANGLES, index_buffer.GetCount(), index_buffer.GetType(), nullptr);
glfwSwapBuffers(glfw_window);
glfwPollEvents();
}
旁注:Bind()仅调用glBindBuffer()
因此,基本上,我绑定了第二个顶点缓冲区,但是无论出于何种原因,glDrawElements()仍在使用第一个顶点缓冲区。好像完全忽略绑定哪个顶点缓冲区,而只关心绑定哪个顶点数组。我发现这很奇怪,因为我印象中顶点数组对象不绑定顶点缓冲区。甚至更奇怪的是,即使顶点数组对象确实绑定了顶点缓冲区对象,在这种情况下也没有关系,因为在绑定vao之后我绑定了vbo。有任何帮助或澄清吗?
答案 0 :(得分:1)
着色器中的属性与要读取的缓冲区之间的绑定是在glVertexAttribPointer
处使用当前绑定缓冲区(即,在 yourBuffer.Bind()之后)完成的。
这些绑定(属性缓冲区)存储在VAO中。
因此,在调用glDrawXXX
之前,请调用glBindVertexArray
,并使用正确的缓冲区。绑定VAO后绑定缓冲区无效。