Question

I have this scene, some of the objects (tables, cabinet..) don't have correct color and I don't know why. I think the problem is in the front/back face of the objects, but don't know how to correct it.

Tables should be same material as chairs.

This is with glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); enter image description here

This is with glColorMaterial(GL_BACK, GL_AMBIENT_AND_DIFFUSE); enter image description here

I want the tables be same as the chairs, correct color is in the first picture.

my init:

void init(){
    glEnable(GL_COLOR_MATERIAL);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glShadeModel(GL_SMOOTH);

    GLfloat ambientColor[] = { 0, 0, 0, 1 };
    GLfloat diffuseColor[] = { 0.1, 0.1, 0.1, 1 };
    GLfloat specularColor[] = { 0.1, 0.1, 0.1, 1 };
    GLfloat lightPosition[] = { 1, 1, 0, 1};


    glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
    glLightfv(GL_LIGHT0, GL_AMBIENT, ambientColor);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseColor);
    glLightfv(GL_LIGHT0, GL_AMBIENT, specularColor);

    glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);

}

Chair and table material:

void setChairMaterial(){
    GLfloat ambientChair[] = { 0.1745,0.01175,0.01175 };
    GLfloat diffuseChair[] = { 0.61424,0.04136,0.04136 };
    GLfloat specularChair[] = { 0.727811,0.626959,0.626959 };
    glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambientChair);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuseChair);
    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specularChair);
    glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.6);
}

This function is called before every creation of chair and tables between glPushAttrib(GL_LIGHTING_BIT) and glPopAttrib()

Draw chair:

glPushMatrix();
glPushAttrib(GL_LIGHTING_BIT);
glTranslatef(8, 0, 8);
glRotatef(-90, 0, 1, 0);
glScalef(3, 3, 3);
setChairMaterial();
drawObj("chair.obj");
glPopAttrib();
glPopMatrix();

Draw table:

glPushMatrix();
glPushAttrib(GL_LIGHTING_BIT);
glTranslatef(5, 0, 18);
glScalef(0.05, 0.05, 0.05);
setChairMaterial();
drawObj("table.obj");
glPopAttrib();
glPopMatrix();

Function drawObj(const char* path) draws objects with GL_TRIANGLES and sets normals

Was it helpful?

Solution

glScalef(3, 3, 3);
...
glScalef(0.05, 0.05, 0.05);

Careful with those. Scaling applies to normals too:

The OpenGL specification needs normals to be unit length to achieve typical lighting results. The current ModelView matrix transforms normals. If that matrix contains a scale transformation, transformed normals might not be unit length, resulting in undesirable lighting problems.

OpenGL 1.1 lets you call glEnable(GL_NORMALIZE), which will make all normals unit length after they're transformed. This is often implemented with a square root and can be expensive for geometry limited applications.

Another solution, available in OpenGL 1.2 (and as an extension to many 1.1 implementations), is glEnable(GL_RESCALE_NORMAL). Rather than making normals unit length by computing a square root, GL_RESCALE_NORMAL multiplies the transformed normal by a scale factor. If the original normals are unit length, and the ModelView matrix contains uniform scaling, this multiplication will restore the normals to unit length.

If the ModelView matrix contains nonuniform scaling, GL_NORMALIZE is the preferred solution.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top