PDA

View Full Version : obj loader problem



Vincent22
04-22-2012, 10:13 AM
Hi everyone.
I'm trying to load an obj 3D model. I wrote an obj loader but the program seems draw onyl some faces. I don't know if it's a vertex or normal problem.

Here is the loader code:


void objLoader::readData(void)
{
ifstream input(fileName->c_str());
string buffer;

if( !input.is_open() ) {
cout << "Errore read fileName" << endl;
return;
}

while(!input.eof()) {
getline(input, buffer);
if(buffer.substr(0,2)== "vn")
theObj->NumNormal++;
else if(buffer.substr(0,2) == "vt")
theObj->NumTexCoord++;
else if(buffer.substr(0,1) == "v")
theObj->NumVertex++;
else if(buffer.substr(0,1) == "f")
theObj->NumTriangle++;
}

theObj->NormalArray = new objNormal[theObj->NumNormal];
theObj->TexCoordArray = new objTexCoord[theObj->NumTexCoord];
theObj->TriangleArray = new objTriangle[theObj->NumTriangle];
theObj->VertexArray = new objVertex[theObj->NumVertex];

input.close();



input.open(fileName->c_str());

input.clear();

if( !input.is_open() ) {
cout << "Errore read fileName" << endl;
return;
}

//contatori
int nC, vC, tC, fC;
nC = vC = tC = fC = 0;
string currMaterial;
//get the hard data, and load up our arrays...
//read one line at a time of the file...
while( !input.eof() ) {
getline(input, buffer);
istringstream line(buffer);
string temp;
string f1, f2, f3;

if(buffer.substr(0,2) == "vn") {
line >> temp >> f1 >> f2 >> f3;
theObj->NormalArray[nC].X = atof(f1.c_str());
theObj->NormalArray[nC].Y = atof(f2.c_str());
theObj->NormalArray[nC].Z = atof(f3.c_str());
nC++;
}

else if(buffer.substr(0,2) == "vt") {
line >> temp >> f1 >> f2;
theObj->TexCoordArray[tC].U = atof(f1.c_str());
theObj->TexCoordArray[tC].V = atof(f2.c_str());
tC++;
}

else if(buffer.substr(0,1) == "v") {
line >> temp >> f1 >> f2 >> f3;
theObj->VertexArray[vC].X = atof(f1.c_str());
theObj->VertexArray[vC].Y = atof(f2.c_str());
theObj->VertexArray[vC].Z = atof(f3.c_str());
vC++;
}

else if(buffer.substr(0,6) == "mtllib") {
line >> temp >> f1;
mtlL = new MtlLoader("models/"+f1);
// cout << f1 << endl;
// theObj->TriangleArray[fC].MaterialName = f1;
}

else if(buffer.substr(0,6) == "usemtl") {
line >> temp >> f1;
currMaterial = f1;
}

else if(buffer.substr(0,1) == "f") {
line >> temp >> f1 >> f2 >> f3;

int sPos = 0;
int ePos = sPos;
string temp;
ePos = f1.find_first_of("/");

//cout << currMaterial << endl;
theObj->TriangleArray[fC].MaterialName = currMaterial;

if(ePos !=string::npos) {
temp = f1.substr(sPos, ePos - sPos);
theObj->TriangleArray[fC].Vertex[0] = atoi(temp.c_str()) - 1;
// cout << temp.c_str() << endl;
sPos = ePos+1;
ePos = f1.find("/", sPos);
temp = f1.substr(sPos, ePos - sPos);
theObj->TriangleArray[fC].TexCoord[0] = atoi(temp.c_str()) -1;
// cout << temp.c_str() << endl;
sPos = ePos+1;
ePos = f1.length();
temp = f1.substr(sPos, ePos - sPos);
theObj->TriangleArray[fC].Normal[0] = atoi(temp.c_str()) -1;
// cout << temp.c_str() << endl;
}



sPos = 0;
ePos = f2.find_first_of("/");
if(ePos !=string::npos) {
temp = f2.substr(sPos, ePos - sPos);
theObj->TriangleArray[fC].Vertex[1] = atoi(temp.c_str()) - 1;
sPos = ePos +1;
ePos = f2.find("/", sPos+1);
temp = f2.substr(sPos, ePos - sPos);
theObj->TriangleArray[fC].TexCoord[1] = atoi(temp.c_str()) - 1;
sPos = ePos+1;
ePos = f2.length();
temp = f2.substr(sPos, ePos - sPos);
theObj->TriangleArray[fC].Normal[1] = atoi(temp.c_str()) - 1;
}


sPos = 0;
ePos = f3.find_first_of("/");
if(ePos !=string::npos) {
temp = f3.substr(sPos, ePos - sPos);
theObj->TriangleArray[fC].Vertex[2] = atoi(temp.c_str()) - 1;

sPos = ePos +1;
ePos = f3.find("/", sPos+1);
temp = f3.substr(sPos, ePos - sPos);
theObj->TriangleArray[fC].TexCoord[2] = atoi(temp.c_str()) - 1;

sPos = ePos+1;
ePos = f3.length();
temp = f3.substr(sPos, ePos - sPos);
theObj->TriangleArray[fC].Normal[2] = atoi(temp.c_str()) - 1;
}

fC++;

}
}

input.close();
}

the draw func:


void ObjModel::drawFace(objTriangle triangle)
{
glPushAttrib(GL_ALL_ATTRIB_BITS);
glPushMatrix();
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

//cout << triangle.MaterialName << endl;

glBegin(GL_TRIANGLES);
for(int i = 0; i< 3; ++i) {
//glColor3f(1.0f, 0.0f, 0.0f);
//std::cout << triangle.Normal[i] << ": " << NormalArray[triangle.Normal[i]].X << " " << NormalArray[triangle.Normal[i]].Y << endl;

glNormal3f(NormalArray[triangle.Normal[i]].X, NormalArray[triangle.Normal[i]].Y, NormalArray[triangle.Normal[i]].Z);
glTexCoord2f(TexCoordArray[triangle.TexCoord[i]].U, TexCoordArray[triangle.TexCoord[i]].V);
applyMaterial(triangle);
glVertex3f(VertexArray[triangle.Vertex[i]].X, VertexArray[triangle.Vertex[i]].Y, VertexArray[triangle.Vertex[i]].Z);

std::cout << VertexArray[triangle.Vertex[i]].X << " " << VertexArray[triangle.Vertex[i]].Y << " " << VertexArray[triangle.Vertex[i]].Z << endl;
}
glEnd();

glPopMatrix();
glPopAttrib();
}

void ObjModel::applyMaterial(objTriangle triangle)
{
Material *mat = getMaterialByName(triangle.MaterialName, Materials, numMaterial);

/*for(int i = 0; i < numMaterial; ++i) {
cout << "mat: " << Materials[i].name << endl;
}*/

if(mat != NULL) {
// cout << mat->name << ": " << mat->Kd[0] << " " << mat->Kd[1] << " " << mat->Kd[2] << endl;
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat->Ka);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat->Kd);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat->Ks);

glColor4f(mat->Kd[0], mat->Kd[1], mat->Kd[2], 1.0f);
//glColor3f(mat->Kd[0], mat->Kd[1], mat->Kd[2]);
}
}


The loader works only with triangles so I triangolated my 3D object (I use Maya). I print some loaded values and it seems correct.
I print

Vincent22
04-24-2012, 07:09 AM
I solved my problem setting normal (glnormal) no more.

But the loader don't load my material for complex 3d model. If I load a simple cube I see material (Kd applied as color), if I load more complex model I can't see any material

some suggests?

BionicBytes
04-24-2012, 09:44 AM
You'll need to debug the code whilst loading the model and see what you need to do to support these more complex cases. You're probably not handling all you think you are.

Vincent22
04-25-2012, 02:59 AM
Loaded data are correct.

I fix my problem, it was something wrong in 3D models. I fix them using Maya and now materials work fine!
Now drawing is also faster than before. Maybe I made something wrong during triangulation or .obj export
thank you : )