OpenGL中的对象绘制顺序

时间:2015-05-23 18:11:52

标签: opengl

我创造了一个浮在地面上的球体。球体以(0,0,0)为中心。我已经设置了一个具有扭曲,仰角,方位角的摄像机,以及离球体更近和更远的距离。我遇到的问题是球体总是在地面上绘制。例如,如果我将相机移到地面以下,我应该看到地面被绘制在球体顶部,但事实并非如此。这是我的基础和绘制功能。

void init_ground()
{
  GLfloat x = -static_cast<GLfloat>(NUM_GROUND_LINES/2);
  GLfloat z = -static_cast<GLfloat>(NUM_GROUND_LINES/2);
  for(int i=0; i<NUM_GROUND_LINES*2; i += 2)
  {
    GLfloat x = NUM_GROUND_LINES/2;
    glm::vec3 vertex1 = glm::vec3(-x, -4.0, z);
    glm::vec3 vertex2 = glm::vec3(x, -4.0, z);
    ground[i] = vertex1;
    ground[i+1] = vertex2;
    z += 1.0;
  }

  for(int i=NUM_GROUND_LINES*2; i<NUM_GROUND_LINES*4; i += 2)
  {
    GLfloat z = NUM_GROUND_LINES/2;
    glm::vec3 vertex1 = glm::vec3(x, -4.0, -z);
    glm::vec3 vertex2 = glm::vec3(x, -4.0, z);
    ground[i] = vertex1;
    ground[i+1] = vertex2;
    x += 1.0;
  }
}

glm::vec3 cameraPos   = glm::vec3(0.0, 0.0, 3.0);
glm::vec3 cameraFront = glm::vec3(0.0f, 0.0f, -1.0f);
glm::vec3 cameraUp    = glm::vec3(0.0f, 1.0f,  0.0f);

void draw()
{
  glm::mat4 view;
  glm::mat4 projection;
  glm::mat4 model;

  view = glm::lookAt(cameraPos, cameraPos + cameraFront, cameraUp);

  view = glm::rotate(view, glm::radians(GLfloat(twist)), glm::vec3(0.0, 0.0, 1.0));
  view = glm::rotate(view, glm::radians(GLfloat(elevation)), glm::vec3(1.0, 0.0, 0.0));
  view = glm::rotate(view, glm::radians(GLfloat(azimuth)), glm::vec3(0.0, 0.0, 1.0));

  projection = glm::perspective(45.0f, (GLfloat)WIDTH/(GLfloat)HEIGHT, 0.1f, 100.0f);

  glUseProgram(program_ground);

  GLint ground_proj_loc = glGetUniformLocation(program_ground, "projection");
  GLint ground_view_loc = glGetUniformLocation(program_ground, "view");
  GLint ground_model_loc = glGetUniformLocation(program_ground, "model");

  glUniformMatrix4fv(ground_proj_loc, 1, GL_FALSE, glm::value_ptr(projection));
  glUniformMatrix4fv(ground_view_loc, 1, GL_FALSE, glm::value_ptr(view));
  glUniformMatrix4fv(ground_model_loc, 1, GL_FALSE, glm::value_ptr(model));

  glBindVertexArray(vao_ground);

  glDrawArrays(GL_LINES, 0, NUM_GROUND_LINES*2*4);

  glBindVertexArray(0);

  glUseProgram(program_sphere);

  GLint sphere_model_loc = glGetUniformLocation(program_sphere, "model");    
  GLint sphere_view_loc = glGetUniformLocation(program_sphere, "view");
  GLint sphere_proj_loc = glGetUniformLocation(program_sphere, "projection");

  glUniformMatrix4fv(sphere_view_loc, 1, GL_FALSE, glm::value_ptr(view));
  glUniformMatrix4fv(sphere_proj_loc, 1, GL_FALSE, glm::value_ptr(projection));
  glUniformMatrix4fv(sphere_model_loc, 1, GL_FALSE, glm::value_ptr(model));

  glBindVertexArray(vao_sphere);

  glDrawArrays(GL_LINE_LOOP, 0, 342);

  glBindVertexArray(0);    

  glfwSwapBuffers(window); 
}

1 个答案:

答案 0 :(得分:0)

为了能够删除隐藏的地形,您需要启用深度测试。

要做到这一点,首先必须在上下文创建时询问缓冲区,以存储相对于摄像机的顶点的相对z位置值。如果您使用的是GLFW库,则会自动完成此创建。

第二步是启用深度测试本身。为此,您需要致电:

glEnable(GL_DEPTH_TEST);

在你调用绘图函数之前的某个地方。

最后,在每次抽奖时,你必须清除深度缓冲区,调用:

glClear(GL_DEPTH_BUFFER_BIT);

但通常称为:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

也可以清除颜色缓冲区。