我想绘制立方体和球体,但是openGl仅绘制立方体。我制作了2个VAO:第一个VAO包含VBO(带有坐标立方体),其他VAO包含坐标球。如果我只想绘制球体,那么它也不起作用。也许是由于VBO绑定不正确而发生的...但是我不完全了解如何处理它。
下面的代码(构成范围):
GLuint sphere(float radius, int slices, int stacks) {
GLuint vbo;
int n = 2 * (slices + 1) * stacks;
int i = 0;
vec3 *points = new vec3[n];
for (float theta = -M_PI / 2; theta < M_PI / 2 - 0.0001; theta += M_PI / stacks) {
for (float phi = -M_PI; phi <= M_PI + 0.0001; phi += 2 * M_PI / slices) {
points[i++] = vec3(cos(theta) * sin(phi), -sin(theta), cos(theta) * cos(phi));
points[i++] = vec3(cos(theta + M_PI / stacks) * sin(phi), -sin(theta + M_PI / stacks), cos(theta + M_PI / stacks) * cos(phi));
}
}
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW);
return vbo;}
主要(我在代码中删除了立方体坐标,因为它太长了):
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "Laba5", nullptr, nullptr);
glfwMakeContextCurrent(window);
glfwSetKeyCallback(window, key_callback);
glfwSetMouseButtonCallback(window, mouse_button_callback);
glewExperimental = GL_TRUE;
glewInit();
glViewport(0, 0, WIDTH, HEIGHT);
glEnable(GL_DEPTH_TEST);
Shader ourShader("shader.vs", "shader.frag");
GLuint VBO, VAO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
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);
glBindVertexArray(0); // Unbind VAO
//-----------------------------------------------------------2
GLuint VAO2;
glGenVertexArrays(1, &VAO2);
glBindVertexArray(VAO2);
glBindBuffer(GL_ARRAY_BUFFER, sphere(1, 30, 30));
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
glBindVertexArray(0); // Unbind VAO
while (!glfwWindowShouldClose(window))
{
// Check if any events have been activiated (key pressed, mouse moved etc.) and call corresponding response functions
glfwPollEvents();
glClearColor(0.32f, 0.31f, 0.30f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
ourShader.Use();
mat4 view = mat4(1.0);
mat4 projection = mat4(1.0);
view = translate(view, vec3(1.0f, 1.0f, -4.8f));
projection = perspective(45.0f, (GLfloat)WIDTH / (GLfloat)HEIGHT, 0.1f, 100.0f);
GLint modelLoc = glGetUniformLocation(ourShader.Program, "model");
GLint viewLoc = glGetUniformLocation(ourShader.Program, "view");
GLint projLoc = glGetUniformLocation(ourShader.Program, "projection");
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));
if (lbutton_down)
{
double cur_mx, cur_my;
glfwGetCursorPos(window, &cur_mx, &cur_my);
if (cur_mx != last_mx || cur_my != last_my)
{
vec3 va = get_arcball_vector(last_mx, last_my);
vec3 vb = get_arcball_vector(cur_mx, cur_my);
float angle = acos(min(1.0f, dot(va, vb)));
vec3 axis_in_camera_coord = cross(va, vb);
mat3 camera2object = inverse(model);
vec3 axis_in_object_coord = camera2object * axis_in_camera_coord;
model = rotate(model, degrees(angle)*0.05f, axis_in_object_coord);
last_mx = cur_mx;
last_my = cur_my;
}
}
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 36);
glBindVertexArray(0);
glBindVertexArray(VAO2);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 2 * 31 * 30);
glBindVertexArray(0);
glfwSwapBuffers(window);
}
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteVertexArrays(1, &VAO2);
glfwTerminate();
return 0;
答案 0 :(得分:0)
您的sphere
函数在内部创建一个新的GL缓冲区对象并返回其名称,因此:
GLuint sphereVBO = sphere(1, 30, 30);
您现在有sphereVBO
包含该缓冲区的名称。
glGenVertexArrays(1, &VAO2); glGenBuffers(1, &sphereVBO);
但是现在,您创建了一个新的缓冲区对象,并使用新名称覆盖了sphereVBO
。结果,您试图从一个空的缓冲区对象中进行绘制(没有调用glBufferData
来为其实际创建数据存储),并且您完全失去了使用球体数据跟踪原始VBO的信息。 / p>