我的程序使用一个VAO,2个VBO和2个EBO。该程序非常奇怪地从VBO中抽取 这就是程序应该如何运作:
//cube
GLfloat vertices1[] = {
0.5f, 0.5f, 0.5f,
0.5f, 0.5f, -0.5f,
0.5f, -0.5f, 0.5f,
0.5f, -0.5f, -0.5f,
-0.5f, 0.5f, 0.5f,
-0.5f, 0.5f, -0.5f,
-0.5f, -0.5f, 0.5f,
-0.5f, -0.5f, -0.5f,
};
GLint indices1[]{
2, 0, 4,
4, 6, 2,
0, 2, 3,
3, 1, 0,
5, 1, 3,
3, 7, 5,
0, 1, 5,
4, 0, 5,
6, 4, 7,
4, 5, 7,
7, 3, 2,
7, 2, 6,
};
//loaded model
std::vector < GLfloat > teddy_vertices;
std::vector < GLuint > teddy_indices;
loadOBJ("teddy.obj", teddy_vertices, teddy_indices);
GLuint VAO, TEDDY, TEDDY_EBO, newVBO, newEBO;
glGenVertexArrays(1, & VAO);
glGenBuffers(1, & TEDDY);
glGenBuffers(1, & TEDDY_EBO);
glGenBuffers(1, & newVBO);
glGenBuffers(1, & newEBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, newVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices1), vertices1, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, newEBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices1), indices1, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid * ) 0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, TEDDY);
glBufferData(GL_ARRAY_BUFFER, teddy_vertices.size() * sizeof(GLfloat), & teddy_vertices.front(), GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid * ) 0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, TEDDY_EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, teddy_indices.size() * sizeof(GLuint), & teddy_indices.front(), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0); // Note that this is allowed, the call to glVertexAttribPointer registered VBO as the currently bound vertex buffer object so afterwards we can safely unbind
glBindVertexArray(0);
//...
while (!glfwWindowShouldClose(window)) {
glfwPollEvents();
glClearColor(0.2 f, 0.3 f, 0.3 f, 1.0 f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glm::mat4 model_matrix = glm::mat4(1.0 f);
glm::mat4 view;
glm::mat4 tilt_view;
glm::mat4 projection;
view = glm::lookAt(cameraPos, cameraPos + cameraFront, cameraUp); //cameraPos + cameraFront
projection = glm::perspective(fov, (GLfloat) WIDTH / (GLfloat) HEIGHT, 0.1 f, 100.0 f);
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model_matrix));
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));
glUniform4fv(color, 1, glm::value_ptr(glm::vec4(1, 1, 1, 1)));
glBindVertexArray(VAO);
if (!teddy_render) {
glBindBuffer(GL_ARRAY_BUFFER, TEDDY);
glDrawElements(
GL_TRIANGLES,
teddy_indices.size(),
GL_UNSIGNED_INT,
(void * ) 0
);
glBindBuffer(GL_ARRAY_BUFFER, 0);
} else {
glBindBuffer(GL_ARRAY_BUFFER, newVBO);
glDrawElements(
GL_TRIANGLES,
36,
GL_UNSIGNED_INT, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
glBindVertexArray(0);
glfwSwapBuffers(window);
}
glfwTerminate();
return 0;
}
此代码仅错误地绘制加载的对象,并且在需要时不从其他VBO中绘制。
如果在游戏循环中代码更改为:
glBindVertexArray(VAO);
//if (!teddy_render){
glBindBuffer(GL_ARRAY_BUFFER, TEDDY);
glDrawElements(
GL_TRIANGLES,
teddy_indices.size(),
GL_UNSIGNED_INT,
(void * ) 0
);
glBindBuffer(GL_ARRAY_BUFFER, 0);
//}
//else{
// glBindBuffer(GL_ARRAY_BUFFER, newVBO);
// glDrawElements(
// GL_TRIANGLES,
// 36,
// GL_UNSIGNED_INT, 0);
// glBindBuffer(GL_ARRAY_BUFFER, 0);
//}
然后加载的对象呈现。然后,如果在游戏循环上面的配置中,在对象之后配置了立方体,即使加载的对象在游戏循环中被绑定,立方体代码仍然被注释掉,立方体渲染:
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, TEDDY);
glBufferData(GL_ARRAY_BUFFER, teddy_vertices.size() * sizeof(GLfloat), & teddy_vertices.front(), GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid * ) 0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, TEDDY_EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, teddy_indices.size() * sizeof(GLuint), & teddy_indices.front(), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, newVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices1), vertices1, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, newEBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices1), indices1, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid * ) 0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
谢谢。
编辑: 这是使用许多带有1个VAO而没有EBO的VBO的工作代码:
std::vector<GLfloat> teddy_vertices;
loadOBJ("teddy.obj", teddy_vertices); //read the vertices from the teddy.obj file
GLuint VAO, VBO, VBO_AXIS, TEDDY;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &VBO_AXIS);
glGenBuffers(1, &TEDDY);
// Bind the Vertex Array Object first, then bind and set vertex buffer(s) and attribute pointer(s).
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, VBO_AXIS);
glBufferData(GL_ARRAY_BUFFER, sizeof(axis), axis, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, TEDDY);
glBufferData(GL_ARRAY_BUFFER, teddy_vertices.size()*sizeof(GLfloat), &teddy_vertices.front(), GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0); // Note that this is allowed, the call to glVertexAttribPointer registered VBO as the currently bound vertex buffer object so afterwards we can safely unbind
glBindVertexArray(0);
//... in game loop
glBindVertexArray(VAO);
if (!teddy_render){
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
glDrawArrays(render_mode, 0, 36);
}
else{
glBindBuffer(GL_ARRAY_BUFFER, TEDDY);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
glDrawArrays(render_mode, 0, teddy_vertices.size());
}
glBindVertexArray(0);
答案 0 :(得分:0)
每个VAO只分配 ONE 元素缓冲区。因此,只有glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, *)
的最后一次通话才会生效。
请参阅what VAOs are。