OBJ文件,读完mtl后无法显示颜色

时间:2018-03-27 10:11:15

标签: opengl 3d light

我使用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文件。你可以看到一些脸有颜色。问题是什么?我需要改变光吗?

这是我的Light代码:

//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);

1 个答案:

答案 0 :(得分:1)

光的值很高。请注意,在标准灯光模型中,灯光的环境,漫反射和镜面反射部分会相加。

标准的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};

使用强烈的朗伯漫反射光成分,它可以很好地反射光线的方向。 见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};