I’m trying to compile robotic hand using model.h prepared by Eric Tatham. There is 1 error occur and I didn’t know how to fix it since I’m still beginner in this language. Can someone show me how should i change the code a bit in order to work?
/////////////////////////////////////////////////////////
//// /////
//// /////
//// Basic model class implementation /////
//// /////
//// Eric Tatham /////
//// /////
//// /////
/////////////////////////////////////////////////////////
#include "model.h"
//Constructor
model::model()
{
//Initialise id to 0
modelId = 0;
hasParent = false;
}
model::model(string filename)
{
modelId = 0;
hasParent = false;
loadModel(filename);
this->filename = filename;
}
//Load a model using given filename and return the model id
int model::loadModel(string filename)
{
this->filename = filename;
ifstream in(filename.c_str()); //Open the model file
if(!in.is_open()) //if not opened, exit with -1
{
cout << "File not opened: " << filename << std::endl;
return -1;
}
cout << "Loading " << filename;
// String to store line on temporarily
string buf = "";
//Read input file text to end of file and push onto lines list
while(!in.eof())
{
getline(in, buf);
if (!buf.empty()) { lines.push_back(buf); }
}
in.close();
cout << ": " << lines.size() << " OBJ lines";
//Now the file contents are in memory, parse the file's lines
ParseOBJFile();
//Check if the OBJ file has a linked material file
if (hasMaterialFile())
{
ifstream in(GetMatFileName()); //Open the model file
if(!in.is_open()) //if not opened, exit with -1
{
std::cout << "File not opened: " << GetMatFileName() << std::endl;
return -1;
}
cout << " - opening MTL " << GetMatFileName();
//Read input file text to end of file and push onto matLines list
while(!in.eof())
{
getline(in,buf);
if (!buf.empty()) { matLines.push_back(buf); }
}
in.close();
cout << ": " << matLines.size() << " MTL lines";
//Now we have a material file in memory, parse the lines of the file
ParseMTLFile();
}
cout << endl;
//Now build the OpenGL List and get a model id
modelId = BuildOpenGL();
matLines.clear();
lines.clear();
faces.clear();
manager.clear();
return modelId;
}
//Destructor
model::~model()
{
//delete everything to avoid memory leaks
lines.clear();
matLines.clear();
faces.clear();
}
//Parse the OBJ file once it has been opened and loaded into memory
void model::ParseOBJFile()
{
//There may be a material file name: mtllib
//and each face may have a usemtl proceeding it
char matFileName[32];
char usemtlName[32];
hasMaterialFile(false);
bool usemtl = false; //No valid usemtl name
//Go through each of the input text lines in the lines list, and decide what kind of element it is
for(unsigned int i = 0; i < lines.size(); i++)
{
//Check for material file and, if found, get its file name
if(lines[i].find("mtllib") != string::npos)
{
sscanf_s(lines[i].c_str(),"%*s %s",matFileName,32);
hasMaterialFile(true);
SetMatFileName( string(matFileName));
}
//Check for use material
if(lines[i].find("usemtl") != string::npos)
{
sscanf_s(lines[i].c_str(),"%*s %s",usemtlName,32);
usemtl = true;
}
//if first character is 'v' and second is ' ' then we have a vertex
//so get it and add it to the vertManager list
if(lines[i].find("v ") != string::npos)
{
float tmpx,tmpy,tmpz;
//read in the 3 float coordinates to tmpx,tmpy,tmpz
sscanf_s(lines[i].c_str(),"v %f %f %f",&tmpx,&tmpy,&tmpz);
//and then make a point3D and push onto the model's vertices list
Point3D pt=Point3D(tmpx,tmpy,tmpz);
manager.AddVertex(pt);
//else if first character is 'v' and second is 'n' then we have a normal
//so get it and add it to the normManager list
}
else if(lines[i].find("vn") != string::npos)
{
float tmpx,tmpy,tmpz;
//read in the 3 float coordinates to tmpx,tmpy,tmpz
sscanf_s(lines[i].c_str(),"vn %f %f %f",&tmpx,&tmpy,&tmpz);
//and then make a point3D to represent the normal vector and push onto the model's normals list
Normal norm=Normal(tmpx,tmpy,tmpz);
manager.AddNormal(norm);
//else if first character is 'v' and second is 't' then we have a UV
//so get it and add it to the uvManager list
}
else if(lines[i].c_str()[0]=='v' && lines[i].c_str()[1]=='t')
{
float tmpx,tmpy;
//read in the 2 float coordinates to tmpx,tmpy
sscanf_s(lines[i].c_str(),"vt %f %f",&tmpx,&tmpy);
//and then make a UV and push onto the model's texCoords list
UV uv=UV(tmpx,tmpy);
manager.AddUV(uv);
//else if first character is 'f' then we have a face
}
else if(lines[i].c_str()[0]=='f')
{
vector<int> v;
vector<int> t;
vector<int> n;
string value = "";
for (unsigned int j = 2; j < lines[i].size(); j++)
{
while (j < lines[i].size() && lines[i].c_str()[j] != '/')
{
value.push_back(lines[i].c_str()[j]);
j++;
}
j++;
v.push_back(atoi(value.c_str()));
value.clear();
while (j < lines[i].size() && lines[i].c_str()[j] != '/')
{
value.push_back(lines[i].c_str()[j]);
j++;
}
j++;
t.push_back(atoi(value.c_str()));
value.clear();
while (j < lines[i].size() && lines[i].c_str()[j] != ' ')
{
value.push_back(lines[i].c_str()[j]);
j++;
}
n.push_back(atoi(value.c_str()));
value.clear();
}
Face face= Face(usemtl, usemtlName, v, n, t);
faces.push_back(face);
}
}
}
//Parse the MTL file
void model:: ParseMTLFile()
{
Material material = Material();
string newmtlName = "";
for (unsigned int i = 0; i < matLines.size(); i++)
{
if (matLines[i].find("newmtl") != string::npos)
{
// Add the last material
if(newmtlName != "") { manager.AddMaterial(newmtlName, material); }
// we've got a new material
material = Material();
newmtlName = matLines[i].substr(7);
material.SetName(newmtlName);
}
else if (matLines[i].find("illum") != string::npos)
{
// we've got the illumination
int illum;
sscanf_s(matLines[i].c_str(),"illum %d", &illum);
material.SetIllum(illum);
}
else if (matLines[i].find("Kd") != string::npos)
{
if (matLines[i].find("map_") != string::npos)
{
// we've got the name of a texture
string tex = matLines[i].substr(7);
material.SetUpTexture(tex);
}
else
{
// we've got the diffuse
float red, green, blue;
sscanf_s(matLines[i].c_str(),"Kd %f %f %f", &red, &green, &blue);
material.SetDiffuse(Colour(red, green, blue));
}
}
else if (matLines[i].find("Ka") != string::npos)
{
// we've got the ambient
float red, green, blue;
sscanf_s(matLines[i].c_str(),"Ka %f %f %f", &red, &green, &blue);
material.SetAmbient(Colour(red, green, blue));
}
else if (matLines[i].find("Tf") != string::npos)
{
// we've got something else
float red, green, blue;
sscanf_s(matLines[i].c_str(),"Tf %f %f %f", &red, &green, &blue);
material.SetTf(Colour(red, green, blue));
}
else if (matLines[i].find("Ni") != string::npos)
{
// we've got another thing
float ni;
sscanf_s(matLines[i].c_str(),"Ni %f", &ni);
material.SetNi(ni);
}
else if (matLines[i].find("Ks") != string::npos)
{
// we've got the specular
float red, green, blue;
sscanf_s(matLines[i].c_str(),"Ks %f %f %f", &red, &green, &blue);
material.SetSpecular(Colour(red, green, blue));
}
}
}
//Build the OpenGL for the model
GLuint model::BuildOpenGL()
{
GLuint modId = glGenLists(1);
//Set up some temporary variables
float ambient[4];
float diffuse[4];
float specular[4];
float white[4] = { 1, 1, 1, 1 };
//Create the OpenGL list
glNewList(modId,GL_COMPILE);
//for each face in the model
for(int i = 0; i < (int)faces.size(); i++)
{
if (faces[i].HasMaterial())
{
// set up the texture
if (manager.HasTexture(faces[i].GetMaterialName()))
{
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, manager.GetTextureId(faces[i].GetMaterialName()));
}
// set up the material
else
{
glDisable(GL_TEXTURE_2D);
manager.GetDiffuse(faces[i].GetMaterialName()).GetArray(diffuse);
glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);
manager.GetAmbient(faces[i].GetMaterialName()).GetArray(ambient);
glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);
manager.GetSpecular(faces[i].GetMaterialName()).GetArray(specular);
glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
glMaterialf(GL_FRONT, GL_SHININESS, manager.GetShininess(faces[i].GetMaterialName()));
}
}
glBegin(GL_POLYGON);
//Recover the vertex, normal and UV and loop through to create the polys
for (unsigned int j = 0; j < faces[i].GetVertexSize(); j++)
{
Point3D vert = manager.GetVertex(faces[i].GetVertexAt(j)-1);
Normal norm = manager.GetNormal(faces[i].GetNormalAt(j)-1);
UV tex = manager.GetUV(faces[i].GetUVAt(j)-1);
glNormal3f(norm.GetX(),norm.GetY(),norm.GetZ());
glTexCoord2f(tex.GetU(),tex.GetV());
glVertex3f(vert.GetX(),vert.GetY(),vert.GetZ());
}
glEnd();
}
glEndList();
return modId;
}
The error is in
ifstream in(GetMatFileName());
as it detected error c2664.
Error code :
error C2664: ‘std::basic_ifstream<_Elem,_Traits>::basic_ifstream(const char *,std::ios_base::openmode,int)’ : cannot convert parameter 1 from ‘std::string’ to ‘const char *’
with
[
_Elem=char,
_Traits=std::char_traits<char>
]
No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called