OBJ文件,读取mtl后无法显示颜色
OBJ file, after read mtl can not show the colors
我使用 opengl 来显示 .obj 3D 模型。我发现模型的颜色不对。像这样:
From 3D Model Viewer software
From my program
这是我的代码:
void ObjLoader::renderObj()
{
glEnableClientState( GL_VERTEX_ARRAY );
glEnableClientState( GL_NORMAL_ARRAY );
for(int i=0; i<m_mtls.size();i++)
{
if(m_mtls[i]->hasTexture)
{
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,m_mtls[i]->texture);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
//glColor3f(1.0f,1.0f,1.0f);
}
else
{
glDisable(GL_TEXTURE_2D);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
//glColor3fv(m_mtls[i]->Kd);
}
glEnable(GL_COLOR_MATERIAL);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, m_mtls[i]->Ka);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, m_mtls[i]->Kd);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, m_mtls[i]->Ks);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, m_mtls[i]->Ns);
glColor3fv(m_mtls[i]->Kd);
glVertexPointer(3,GL_DOUBLE,0,m_mtls[i]->triVertexs);
glNormalPointer(GL_DOUBLE,0,m_mtls[i]->triNormals);
glTexCoordPointer(3,GL_DOUBLE,0,m_mtls[i]->triTextures);
glDrawArrays(GL_TRIANGLES,0,m_mtls[i]->triNum*3);
glVertexPointer(3,GL_DOUBLE,0,m_mtls[i]->quadVertexs);
glNormalPointer(GL_DOUBLE,0,m_mtls[i]->quadNormals);
glTexCoordPointer(3,GL_DOUBLE,0,m_mtls[i]->quadTextures);
glDrawArrays(GL_QUADS,0,m_mtls[i]->quadNum*4);
}
glDisableClientState( GL_VERTEX_ARRAY );
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
}
我已经分析了mtl文件。你可以看到一些脸有颜色。问题是什么?我需要换灯吗?
这是我的灯光代码:
//set lights
GLfloat mat_specular[] = {1.0,1.0,1.0,1.0};
GLfloat mat_shiniess[] = {100.0};
GLfloat light_ambient [4] = {1.0,1.0,1.0,1.0};
GLfloat light_diffuse [4] = {1.0,1.0,1.0,1.0};
GLfloat light_specular[4] = {1.0,1.0,1.0,1.0};
GLfloat light_position[4] = {1500.0,1500.0,1500.0,0.0};
GLfloat lmodel_ambient [] = {1.0,1.0,1.0,1.0};
//create light
glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);
glMaterialfv(GL_FRONT,GL_SHININESS,mat_shiniess);
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR,light_specular);
glLightfv(GL_LIGHT0, GL_POSITION,light_position);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT,lmodel_ambient);
glLightModeli( GL_FRONT, GL_AMBIENT_AND_DIFFUSE );
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
光的值太高了。请注意,在标准光模型中,光的环境光、漫反射和镜面反射部分相加。
标准 OpenGL Blinn-Phong 光照模型是这样计算的:
Ka ... ambient material
Kd ... difusse material
Ks ... specular material
La ... ambient light
Ld ... diffuse light
Ls ... specular light
sh ... shininess
N ... norlmal vector
L ... light vector (from the vertex postion to the light)
V ... view vector (from the vertex psotion to the eye)
Id = max(dot(N, L), 0.0);
H = normalize(V + L);
NdotH = max(dot(N, H), 0.0);
Is = (sh + 2.0) * pow(NdotH, sh) / (2.0 * 3.14159265);
fs = Ka*La + Id*Kd*Ld + Is*Ks*Ls;
由于您所有的光值都由 {1.0,1.0,1.0,1.0}
初始化,因此在大多数情况下总和大于 1.0,并且渲染的对象几乎是白色的。
我推荐使用小的环境光部分,因为它独立于入射光添加到整个物体。
GLfloat light_ambient[] = {0.2f, 0.2f, 0.2f, 1.0f};
使用很强的lambertian漫反射光分量,可以很好的反射光的方向。
参见 How does this faking the light work on aerotwist?
GLfloat light_diffuse[] = {0.8f, 0.8f, 0.8f, 1.0f};
对于镜面光组件,您必须进行试验。它的效果在很大程度上取决于光泽度参数。
GLfloat mat_shiniess[] = {20.0f};
GLfloat light_specular[] = {0.5f, 0.5f, 0.5f, 1.0f};
我使用 opengl 来显示 .obj 3D 模型。我发现模型的颜色不对。像这样: From 3D Model Viewer software
From my program 这是我的代码:
void ObjLoader::renderObj()
{
glEnableClientState( GL_VERTEX_ARRAY );
glEnableClientState( GL_NORMAL_ARRAY );
for(int i=0; i<m_mtls.size();i++)
{
if(m_mtls[i]->hasTexture)
{
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,m_mtls[i]->texture);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
//glColor3f(1.0f,1.0f,1.0f);
}
else
{
glDisable(GL_TEXTURE_2D);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
//glColor3fv(m_mtls[i]->Kd);
}
glEnable(GL_COLOR_MATERIAL);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, m_mtls[i]->Ka);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, m_mtls[i]->Kd);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, m_mtls[i]->Ks);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, m_mtls[i]->Ns);
glColor3fv(m_mtls[i]->Kd);
glVertexPointer(3,GL_DOUBLE,0,m_mtls[i]->triVertexs);
glNormalPointer(GL_DOUBLE,0,m_mtls[i]->triNormals);
glTexCoordPointer(3,GL_DOUBLE,0,m_mtls[i]->triTextures);
glDrawArrays(GL_TRIANGLES,0,m_mtls[i]->triNum*3);
glVertexPointer(3,GL_DOUBLE,0,m_mtls[i]->quadVertexs);
glNormalPointer(GL_DOUBLE,0,m_mtls[i]->quadNormals);
glTexCoordPointer(3,GL_DOUBLE,0,m_mtls[i]->quadTextures);
glDrawArrays(GL_QUADS,0,m_mtls[i]->quadNum*4);
}
glDisableClientState( GL_VERTEX_ARRAY );
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
}
我已经分析了mtl文件。你可以看到一些脸有颜色。问题是什么?我需要换灯吗?
这是我的灯光代码:
//set lights
GLfloat mat_specular[] = {1.0,1.0,1.0,1.0};
GLfloat mat_shiniess[] = {100.0};
GLfloat light_ambient [4] = {1.0,1.0,1.0,1.0};
GLfloat light_diffuse [4] = {1.0,1.0,1.0,1.0};
GLfloat light_specular[4] = {1.0,1.0,1.0,1.0};
GLfloat light_position[4] = {1500.0,1500.0,1500.0,0.0};
GLfloat lmodel_ambient [] = {1.0,1.0,1.0,1.0};
//create light
glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);
glMaterialfv(GL_FRONT,GL_SHININESS,mat_shiniess);
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR,light_specular);
glLightfv(GL_LIGHT0, GL_POSITION,light_position);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT,lmodel_ambient);
glLightModeli( GL_FRONT, GL_AMBIENT_AND_DIFFUSE );
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
光的值太高了。请注意,在标准光模型中,光的环境光、漫反射和镜面反射部分相加。
标准 OpenGL Blinn-Phong 光照模型是这样计算的:
Ka ... ambient material
Kd ... difusse material
Ks ... specular material
La ... ambient light
Ld ... diffuse light
Ls ... specular light
sh ... shininess
N ... norlmal vector
L ... light vector (from the vertex postion to the light)
V ... view vector (from the vertex psotion to the eye)
Id = max(dot(N, L), 0.0);
H = normalize(V + L);
NdotH = max(dot(N, H), 0.0);
Is = (sh + 2.0) * pow(NdotH, sh) / (2.0 * 3.14159265);
fs = Ka*La + Id*Kd*Ld + Is*Ks*Ls;
由于您所有的光值都由 {1.0,1.0,1.0,1.0}
初始化,因此在大多数情况下总和大于 1.0,并且渲染的对象几乎是白色的。
我推荐使用小的环境光部分,因为它独立于入射光添加到整个物体。
GLfloat light_ambient[] = {0.2f, 0.2f, 0.2f, 1.0f};
使用很强的lambertian漫反射光分量,可以很好的反射光的方向。 参见 How does this faking the light work on aerotwist?
GLfloat light_diffuse[] = {0.8f, 0.8f, 0.8f, 1.0f};
对于镜面光组件,您必须进行试验。它的效果在很大程度上取决于光泽度参数。
GLfloat mat_shiniess[] = {20.0f};
GLfloat light_specular[] = {0.5f, 0.5f, 0.5f, 1.0f};