我想加载一个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);
}
}
}
}
}
答案 0 :(得分:0)
我在你的代码中发现了一个错误,你需要在glVertex3f之前调用glNormal3f和glTexCoord2f。 obj也可以包含不同的材质设置,它不仅仅是简单的纹理。
当前纹理坐标是与每个顶点和当前栅格位置关联的数据的一部分。 (关于glTexCoord)