0
我的计划使用一个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代码而不EBOS:
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);
我有一个程序使用许多VBO2与1 VAO。请参阅编辑。在使用EBO的程序中,绑定数组缓冲区不起作用后,为什么会在游戏循环中绑定元素数组缓冲区? – rur2641
@ rur2641:答案依然如此。你可以有许多VBO,但只有** ONE **元素缓冲区。否则,你的代码不会。 – ybungalobill