Why isn't my lighting working properly? Are my normals messed up?

Posted by Radek Slupik on Game Development See other posts from Game Development or by Radek Slupik
Published on 2012-05-09T13:37:06Z Indexed on 2012/07/10 15:26 UTC
Read the original article Hit count: 387

Filed under:
|
|
|

I'm relatively new to OpenGL and I am trying to draw a 3D model (loaded from a 3ds file using lib3ds) using OpenGL with lighting, but about half of it is drawn in black.

model

I set up the light as such:

glEnable(GL_LIGHTING);
glShadeModel(GL_SMOOTH);

GLfloat ambientColor[] = {0.2f, 0.2f, 0.2f, 1.0f};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientColor);

glEnable(GL_LIGHT0);
GLfloat lightColor0[] = {1.0f, 1.0f, 1.0f, 1.0f};
GLfloat lightPos0[] = {4.0f, 0.0f, 8.0f, 0.0f};
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor0);
glLightfv(GL_LIGHT0, GL_POSITION, lightPos0);

The model is in a VBO and drawn using glDrawArrays. The normals are in a separate VBO, and the normals are calculated using lib3ds_mesh_calculate_vertex_normals:

std::vector<std::array<float, 3>> normals;
for (std::size_t i = 0; i < model->nmeshes; ++i) {
  auto& mesh = *model->meshes[i];
  std::vector<float[3]> vertex_normals(mesh.nfaces * 3);
  lib3ds_mesh_calculate_vertex_normals(&mesh, vertex_normals.data());
  for (std::size_t j = 0; j < mesh.nfaces; ++j) {
    auto& face = mesh.faces[j];
    normals.push_back(make_array(vertex_normals[j]));
  }
}
glBindBuffer(GL_ARRAY_BUFFER, normal_vbo_);
glBufferData(GL_ARRAY_BUFFER,
             normals.size() * sizeof(decltype(normals)::value_type),
             normals.data(),
             GL_STATIC_DRAW);

The problem isn't the vertices; the model is drawn correctly when drawing it as a wireframe. I also fixed the normals in Blender using controlN. What could be the problem? Should I store the normals in a different order?

© Game Development or respective owner

Related posts about c++

Related posts about opengl