Nick
2005.04.12, 01:27 AM
I'm trying to implement the use of .mtl files along with my .obj files but it doesn't seem to wish to work. Can someone point out anything obvious in this code that is wrong or causing my cube to light up grey rather than being red (it should be clear but I haven't figured out how to include the transparency)?
Here's all the code one should need to assist me. Or if you know where I can find a very thorough definition of the .mtl file, I'd appreciate it. Today on Google I found 5 separate definitions of the same file. Interesting.
In the Mesh::CreateList() function, the default material works fine (as that is applied to my textured items and they show up just as usual, but the cube is set to not use the default material and instead use the parsed one.
If anyone can help me with this, you'll be my new best friend. It's too late for me to continue coding. I owe the world to anyone who can help me solve this. Thanks in advance.
class Material
{
public:
Texture ambientTexture;
Texture diffuseTexture;
Texture specularTexture;
GLfloat ambient[3];
GLfloat diffuse[3];
GLfloat specular[3];
GLfloat opacity[1];
GLfloat shiny[1];
const char *name;
const char *filename;
};
(here's the text from the .mtl file itself)
newmtl clearRed
illum 4
Kd 1.00 0.00 0.00
Ka 1.00 1.00 1.00
Tf 0.60 0.60 0.60
Ni 1.00
Ks 0.50 0.50 0.50
bool LoadMaterial(Mesh &m, const char *f)
{
FILE *materialFile;
Material mat[MAX_MATERIALS];
int curMat = -1;
char line[255] = {};
char tempChar[255] = {};
float a,b,c;
strcat(tempChar,"Stranded.app/Contents/Resources/Models/");
strcat(tempChar,f);
if((materialFile = fopen(tempChar, "rt")) == NULL)
{
cout << "Failed to load " << f << endl;
return false;
}
cout << "Loading " << f << "..." << endl;
m.SetUseDefaultMaterial(false);
for(int i=0; i<MAX_MATERIALS; i++) { mat[i].filename = f; }
while(!feof(materialFile))
{
fgets(line,100,materialFile);
if(sscanf(line,"newmtl %s",tempChar)==1)
{
if(curMat!=-1) { m.SetMaterial(curMat,mat[curMat]); }
curMat++;
mat[curMat].name = tempChar;
}
else if(sscanf(line,"Kd %f %f %f",&a,&b,&c)==3)
{
mat[curMat].diffuse[0] = a;
mat[curMat].diffuse[1] = b;
mat[curMat].diffuse[2] = c;
}
else if(sscanf(line,"Ka %f %f %f",&a,&b,&c)==3)
{
mat[curMat].ambient[0] = a;
mat[curMat].ambient[1] = b;
mat[curMat].ambient[2] = c;
}
else if(sscanf(line,"Ks %f %f %f",&a,&b,&c)==3)
{
mat[curMat].specular[0] = a;
mat[curMat].specular[1] = b;
mat[curMat].specular[2] = c;
}
}
fclose(materialFile);
return true;
}
(the following is just set out for every mesh to use as a default)
defaultMaterial.diffuse[0] = 0;
defaultMaterial.diffuse[1] = 0;
defaultMaterial.diffuse[2] = 0;
defaultMaterial.shiny[0] = 50;
void Mesh::CreateList()
{
glNewList(list,GL_COMPILE);
glColor4f(1,1,1,1);
if(useDefaultMaterial)
{
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, defaultMaterial.diffuse);
glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, defaultMaterial.shiny);
}
else
{
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat[0].ambient);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat[0].diffuse);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat[0].specular);
glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat[0].shiny);
}
if(useTexture) { glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D,mat[0].ambientTexture.texID); }
else { glDisable(GL_TEXTURE_2D); }
for(int i=0; i<fCount; i++)
{
if(f[i].type == TRIFACE)
{
glBegin(GL_TRIANGLES);
for(int j=0; j<3; j++)
{
glNormal3f(vn[f[i].v[j]].x,vn[f[i].v[j]].y,vn[f[i].v[j]].z);
glTexCoord2f(vt[f[i].vt[j]].u,vt[f[i].vt[j]].v);
glVertex3f(v[f[i].v[j]].x,v[f[i].v[j]].y,v[f[i].v[j]].z);
}
glEnd();
}
else if(f[i].type == QUADFACE)
{
glBegin(GL_QUADS);
for(int j=0; j<4; j++)
{
glNormal3f(vn[f[i].v[j]].x,vn[f[i].v[j]].y,vn[f[i].v[j]].z);
glTexCoord2f(vt[f[i].vt[j]].u,vt[f[i].vt[j]].v);
glVertex3f(v[f[i].v[j]].x,v[f[i].v[j]].y,v[f[i].v[j]].z);
}
glEnd();
}
else
{
cout << "Face " << i << "out of " << fCount << " of unknown type." << endl;
i = fCount;
}
}
glEndList();
}
Here's all the code one should need to assist me. Or if you know where I can find a very thorough definition of the .mtl file, I'd appreciate it. Today on Google I found 5 separate definitions of the same file. Interesting.
In the Mesh::CreateList() function, the default material works fine (as that is applied to my textured items and they show up just as usual, but the cube is set to not use the default material and instead use the parsed one.
If anyone can help me with this, you'll be my new best friend. It's too late for me to continue coding. I owe the world to anyone who can help me solve this. Thanks in advance.
class Material
{
public:
Texture ambientTexture;
Texture diffuseTexture;
Texture specularTexture;
GLfloat ambient[3];
GLfloat diffuse[3];
GLfloat specular[3];
GLfloat opacity[1];
GLfloat shiny[1];
const char *name;
const char *filename;
};
(here's the text from the .mtl file itself)
newmtl clearRed
illum 4
Kd 1.00 0.00 0.00
Ka 1.00 1.00 1.00
Tf 0.60 0.60 0.60
Ni 1.00
Ks 0.50 0.50 0.50
bool LoadMaterial(Mesh &m, const char *f)
{
FILE *materialFile;
Material mat[MAX_MATERIALS];
int curMat = -1;
char line[255] = {};
char tempChar[255] = {};
float a,b,c;
strcat(tempChar,"Stranded.app/Contents/Resources/Models/");
strcat(tempChar,f);
if((materialFile = fopen(tempChar, "rt")) == NULL)
{
cout << "Failed to load " << f << endl;
return false;
}
cout << "Loading " << f << "..." << endl;
m.SetUseDefaultMaterial(false);
for(int i=0; i<MAX_MATERIALS; i++) { mat[i].filename = f; }
while(!feof(materialFile))
{
fgets(line,100,materialFile);
if(sscanf(line,"newmtl %s",tempChar)==1)
{
if(curMat!=-1) { m.SetMaterial(curMat,mat[curMat]); }
curMat++;
mat[curMat].name = tempChar;
}
else if(sscanf(line,"Kd %f %f %f",&a,&b,&c)==3)
{
mat[curMat].diffuse[0] = a;
mat[curMat].diffuse[1] = b;
mat[curMat].diffuse[2] = c;
}
else if(sscanf(line,"Ka %f %f %f",&a,&b,&c)==3)
{
mat[curMat].ambient[0] = a;
mat[curMat].ambient[1] = b;
mat[curMat].ambient[2] = c;
}
else if(sscanf(line,"Ks %f %f %f",&a,&b,&c)==3)
{
mat[curMat].specular[0] = a;
mat[curMat].specular[1] = b;
mat[curMat].specular[2] = c;
}
}
fclose(materialFile);
return true;
}
(the following is just set out for every mesh to use as a default)
defaultMaterial.diffuse[0] = 0;
defaultMaterial.diffuse[1] = 0;
defaultMaterial.diffuse[2] = 0;
defaultMaterial.shiny[0] = 50;
void Mesh::CreateList()
{
glNewList(list,GL_COMPILE);
glColor4f(1,1,1,1);
if(useDefaultMaterial)
{
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, defaultMaterial.diffuse);
glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, defaultMaterial.shiny);
}
else
{
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat[0].ambient);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat[0].diffuse);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat[0].specular);
glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat[0].shiny);
}
if(useTexture) { glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D,mat[0].ambientTexture.texID); }
else { glDisable(GL_TEXTURE_2D); }
for(int i=0; i<fCount; i++)
{
if(f[i].type == TRIFACE)
{
glBegin(GL_TRIANGLES);
for(int j=0; j<3; j++)
{
glNormal3f(vn[f[i].v[j]].x,vn[f[i].v[j]].y,vn[f[i].v[j]].z);
glTexCoord2f(vt[f[i].vt[j]].u,vt[f[i].vt[j]].v);
glVertex3f(v[f[i].v[j]].x,v[f[i].v[j]].y,v[f[i].v[j]].z);
}
glEnd();
}
else if(f[i].type == QUADFACE)
{
glBegin(GL_QUADS);
for(int j=0; j<4; j++)
{
glNormal3f(vn[f[i].v[j]].x,vn[f[i].v[j]].y,vn[f[i].v[j]].z);
glTexCoord2f(vt[f[i].vt[j]].u,vt[f[i].vt[j]].v);
glVertex3f(v[f[i].v[j]].x,v[f[i].v[j]].y,v[f[i].v[j]].z);
}
glEnd();
}
else
{
cout << "Face " << i << "out of " << fCount << " of unknown type." << endl;
i = fCount;
}
}
glEndList();
}