Loading OBJ file, using normals (#vertices <#normals)
I have an obj file and have successfully loaded an object into opengl without using the normals specified.
This is what it looks like:
File format:
v x y z vn x y z f x//x' y//y' z//z'
The grid display function is as follows:
glBegin(GL_TRIANGLES); for all faces { glVertex3f(.., .., ..); glVertex3f(.., .., ..); glVertex3f(.., .., ..); } glEnd();
And here's the result:
I read that an object may look flat due to the default standard vector that OpenGL uses for lighting equations.
This could be solved using normals. The available normals are 780 and vertices 155.
I tried to use glNorm before every glVertex3f call, but obj looks downright strange (lines, etc.).
What should I do?
REV. # 1: This is how I read the file:
void loader(class mesh &tree) { int vx1, vx2, vx3, vn1, vn2, vn3; ifstream file; string line; point vec, norm; face tempface; file.open("tree.obj"); if (file.is_open() == true) { while(getline(file, line) ) { if (line.substr(0,2) == "") continue; else if (line.substr(0, 2) == "v ") { istringstream numbers(line.substr(2)); numbers >> vec.x >> vec.y >> vec.z; tree.vectors.push_back(vec); } else if (line.substr(0,2) == "vn") { istringstream numbers(line.substr(2)); numbers >> norm.x >> norm.y >> norm.z; tree.normals.push_back(norm); } else if (line.substr(0,2) == "f ") { face f; line = line.substr(2,line.length()); for (string::iterator it = line.begin(); it != line.end(); ++it) { if (*it == '/') { //erase both of the "//" line.erase(it); line.erase(it); //add a space between the numbers line.insert(it, ' '); } } istringstream inp(line); inp >> f.vert_indices[0] >> f.norm_indices[0] >> f.vert_indices[1] >> f.norm_indices[1] >> f.vert_indices[2] >> f.norm_indices[2]; tree.faces.push_back(f); } else continue; } file.close(); } }
And this is how I display it:
void mesh::displayMesh() { glPushMatrix(); glBegin(GL_TRIANGLES); for(vector<face>::const_iterator it = faces.begin(); it != faces.end(); ++it) { //glVertex3f(normals[it->norm_indices[0] -1 ].x, normals[it->norm_indices[0] -1 ].y, normals[it->norm_indices[0] -1 ].z); glVertex3f(vectors[it->vert_indices[0] -1 ].x, vectors[it->vert_indices[0] -1 ].y, vectors[it->vert_indices[0] -1 ].z); //glVertex3f(normals[it->norm_indices[1] -1 ].x, normals[it->norm_indices[1] -1 ].y, normals[it->norm_indices[1] -1 ].z); glVertex3f(vectors[it->vert_indices[1] -1 ].x, vectors[it->vert_indices[1] -1 ].y, vectors[it->vert_indices[1] -1 ].z); //glVertex3f(normals[it->norm_indices[2] -1 ].x, normals[it->norm_indices[2] -1 ].y, normals[it->norm_indices[2] -1 ].z); glVertex3f(vectors[it->vert_indices[2] -1 ].x, vectors[it->vert_indices[2] -1 ].y, vectors[it->vert_indices[2] -1 ].z); } glEnd(); glPopMatrix(); }
The displayMesh function is called in the openGL Render function, and the loader function is called in the OpenGL Setup function, and the mesh tree object is a global variable.
EDIT # 2:
This is how the tree looks with normals:
Also this is the code for the OpenGL customization function.
source share
Otherwise, you have the following:
glNormal3f(normals[it->norm_indices[0] -1 ].x, normals[it->norm_indices[0] -1 ].y, normals[it->norm_indices[0] -1 ].z); glVertex3f(vectors[it->vert_indices[0] -1 ].x, vectors[it->vert_indices[0] -1 ].y, vectors[it->vert_indices[0] -1 ].z); glNormal3f(normals[it->norm_indices[1] -1 ].x, normals[it->norm_indices[1] -1 ].y, normals[it->norm_indices[1] -1 ].z); glVertex3f(vectors[it->vert_indices[1] -1 ].x, vectors[it->vert_indices[1] -1 ].y, vectors[it->vert_indices[1] -1 ].z); glNormal3f(normals[it->norm_indices[2] -1 ].x, normals[it->norm_indices[2] -1 ].y, normals[it->norm_indices[2] -1 ].z); glVertex3f(vectors[it->vert_indices[2] -1 ].x, vectors[it->vert_indices[2] -1 ].y, vectors[it->vert_indices[2] -1 ].z);
EDIT: oops, you get the idea that already
If you want to check if the normals are correct, paint each vertex according to the normal. Use glColor3f
but put normals.
source share
when you use delete it cancels the iterator
//erase both of the "//" it = line.erase(it); it = line.erase(it); //add a space between the numbers it = line.insert(it, ' ');
however you can erase once and then replace
//erase both of the "//" it = line.erase(it); //add a space between the numbers *it = ' ';
source share