Opengl纹理问题

时间:2015-04-30 12:06:06

标签: c++ opengl texture-mapping

我想加载一个obj模型文件并用OpenGL显示它。它工作正常,直到我尝试加载纹理。我的obj加载器只能加载三角形。颜色看起来与纹理非常不同。有什么建议吗?

以下是C ++中模型的外观: http://s30.postimg.org/g6w0tla29/image.jpg

以下是混合器中模型的外观: http://s11.postimg.org/lvcalym0j/blender.jpg

继承我的代码objloader代码:

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);
                }
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

我在你的代码中发现了一个错误,你需要在glVertex3f之前调用glNormal3f和glTexCoord2f。 obj也可以包含不同的材质设置,它不仅仅是简单的纹理。

  

当前纹理坐标是与每个顶点和当前栅格位置关联的数据的一部分。 (关于glTexCoord)

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