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:
tree without normals
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:
enter image description here

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:
tree with normals Also this is the code for the OpenGL customization function.

+3


source share


2 answers


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.

0


source


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 = ' ';

      

0


source







All Articles