-1

I want to load an obj model file and display it with OpenGL. It works fine until I try to load the texture. My obj loader can load only triangles. Also the colors look very different from the texture. Any advices?

Here is how the model looks like in C++: http://s30.postimg.org/g6w0tla29/image.jpg

Here is how the model looks like in blender: http://s11.postimg.org/lvcalym0j/blender.jpg

Heres my code objloader code:

void Model::drawModel()
{
    unsigned int i;
    for(i=0;i<faces.size();i++)
    {
        glBindTexture(GL_TEXTURE_2D,IDtexture[0]);

        glBegin(GL_TRIANGLES);
            glVertex3f(vertices[faces[i].v1-1].x,vertices[faces[i].v1-1].y,vertices[faces[i].v1-1].z);
            glNormal3f(normals[faces[i].nn1-1].x,normals[faces[i].nn1-1].y,normals[faces[i].nn1-1].z);
            glTexCoord2f(textureCoordinates[faces[i].tn1-1].x,textureCoordinates[faces[i].tn1-1].y);

            glVertex3f(vertices[faces[i].v2-1].x,vertices[faces[i].v2-1].y,vertices[faces[i].v2-1].z);
            glNormal3f(normals[faces[i].nn2-1].x,normals[faces[i].nn2-1].y,normals[faces[i].nn2-1].z);
            glTexCoord2f(textureCoordinates[faces[i].tn2-1].x,textureCoordinates[faces[i].tn2-1].y);

            glVertex3f(vertices[faces[i].v3-1].x,vertices[faces[i].v3-1].y,vertices[faces[i].v3-1].z);
            glNormal3f(normals[faces[i].nn3-1].x,normals[faces[i].nn3-1].y,normals[faces[i].nn3-1].z);
            glTexCoord2f(textureCoordinates[faces[i].tn3-1].x,textureCoordinates[faces[i].tn3-1].y);
        glEnd();
    }
}

void Model::loadTexture(const char* filename,unsigned int &ID)
{
    sf::Image image;
    image.loadFromFile(filename);
    glGenTextures(1,&ID);
    glBindTexture(GL_TEXTURE_2D,ID);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.getSize().x, image.getSize().y, 0, GL_RGBA, GL_UNSIGNED_BYTE, image.getPixelsPtr());
}

Model::Model(string file)
{
    vector<string>line;
    string obj,mat;
    char buffer[256];
    const char* filename;
    unsigned int ID=0;
    coordinate v;
    face f;
    uv t;
    material M;
    obj="models/"+file+'/'+file+".obj";
    mat="models/"+file+'/'+file+".mtl";
    filename=obj.c_str();

    ifstream fin(filename);
    if(!fin.is_open())
        cout<<"Model's file doesnt exist"<<endl;

    while(!fin.eof())
    {
        fin.getline(buffer,256);
        line.push_back(buffer);
    }
    for(unsigned int i=0;i<line.size();i++)
    {
        if(line[i][0]=='v'&&line[i][1]==' ')
        {
            sscanf(line[i].c_str(),"v %f %f %f",&v.x,&v.y,&v.z);
            vertices.push_back(v);
        }
        if(line[i][0]=='v'&&line[i][1]=='n')
        {
            sscanf(line[i].c_str(),"vn %f %f %f",&v.x,&v.y,&v.z);
            normals.push_back(v);
        }
        if(line[i][0]=='v'&&line[i][1]=='t')
        {
            sscanf(line[i].c_str(),"vt %f %f",&t.x,&t.y);
            textureCoordinates.push_back(t);
        }
        if(line[i][0]=='f'&&line[i][1]==' ')
        {
            if(line[i].find("/")!=std::string::npos)
            {
                sscanf(line[i].c_str(),"f %d/%d/%d %d/%d/%d %d/%d/%d ",&f.v1,&f.tn1,&f.nn1,&f.v2,&f.tn2,&f.nn2,&f.v3,&f.tn3,&f.nn3);
                faces.push_back(f);
            }
        }
        if(line[i][0]=='m'&&line[i][1]=='t'&&line[i][2]=='l'&&line[i][3]=='l')
        {
            std::vector<std::string> tmp;
            char c[200];
            ifstream FIN(mat.c_str());
            if(fin.is_open())
                while(!FIN.eof())
                {
                    FIN.getline(c,200);
                    tmp.push_back(c);
                }
            else cout<<"Material file not opened";

            for(unsigned int j=0;j<tmp.size();j++)
            {
                if(tmp[j][0]=='#')
                    continue;
                if(tmp[j][0]=='n'&&tmp[j][1]=='e'&&tmp[j][2]=='w')
                {
                    sscanf(tmp[j+1].c_str(),"Ns %f",&M.ns);
                    sscanf(tmp[j+2].c_str(),"Ka %f %f %f",&M.amb[0],&M.amb[1],&M.amb[2]);
                    sscanf(tmp[j+3].c_str(),"Kd %f %f %f",&M.dif[0],&M.dif[1],&M.dif[2]);
                    sscanf(tmp[j+4].c_str(),"Ks %f %f %f",&M.spec[0],&M.spec[1],&M.spec[2]);
                    sscanf(tmp[j+5].c_str(),"Ni %f",&M.ni);
                    sscanf(tmp[j+6].c_str(),"d %f",&M.alpha);
                    sscanf(tmp[j+7].c_str(),"illum %f",&M.illum);
                    sscanf(tmp[j+8].c_str(),"map_Kd %s",&M.tname);
                    ID=0;
                    if(M.tname!=0)
                        loadTexture(M.tname,ID);
                    IDtexture.push_back(ID);
                    materials.push_back(M);
                }
            }
        }
    }
}
  • Just a general note. Once you figure out the basics of drawing and stuff go and look up Vertex Buffer Objects. The glBegin(x); and glEnd(); drawing is deprecated and it's very bad performance wise. – new Objekt Apr 30 '15 at 14:06

1 Answers1

0

I found one bug in your code, you need to call glNormal3f and glTexCoord2f before glVertex3f. Also obj can contains different settings for material, it is not simple texture only.

The current texture coordinates are part of the data that is associated with each vertex and with the current raster position. (About glTexCoord)

From https://www.opengl.org/sdk/docs/man2/xhtml/glTexCoord.xml

Unick
  • 644
  • 9
  • 23