Coloring Doesn't Work With Lighting?

EDIT: Solved my below problem after some working/reading documentation by making a glMaterialfv() call with a GLfloat array of color indices for the final argument just before I call the ‘drawCube’ function each time. Did the trick!

Hi there,

I am trying to create a simple 3D environment for a robot to move about in. I’ve already constructed the robot, environment, and given the camera basic movement abilities. My problem is, I’d like the obstacles (cubes) in this case to have different colors than the simple grey I’ve chosen to make the floor. Right now, all the objects are the same diffuse grey color.

I’ve followed some lighting tutorials to achieve the lighting effects, but I’m not really the most skilled in their usage. Looking through the documentation, it appears that a function called glColorMaterial that should help me achieve color in tandem with lighting, but enabling it in my init function or in the cube drawing function only causes my screen to black out, or go extremely dark and show only a faint scene image respectively. Can anyone direct me as to how I might achieve the desired coloring for my scene?

As another aside, is there a function/simple way for me to toggle a first person view? I’ve fiddled a bit with gluPerspective and mouse activating a flag, but just wanted to know if there was a more straightforward way.

Code below (It’s a little lengthy, but I plan to separate robot and scene into separate files once I figure this out):



#define GLUT_DISABLE_ATEXIT_HACK

#include <GL/glut.h>
#include <GL/gl.h>
#include <math.h>

#define TORSO_HEIGHT 5.0
#define UPPER_ARM_HEIGHT 3.0
#define LOWER_ARM_HEIGHT 2.0
#define UPPER_LEG_RADIUS  0.5
#define LOWER_LEG_RADIUS  0.5
#define LOWER_LEG_HEIGHT 2.0
#define UPPER_LEG_HEIGHT 3.0
#define UPPER_LEG_RADIUS  0.5
#define TORSO_RADIUS 1.0
#define UPPER_ARM_RADIUS  0.5
#define LOWER_ARM_RADIUS  0.5
#define FINGER_1_RADIUS 0.25
#define FINGER_1_HEIGHT 0.1
#define HEAD_HEIGHT 1.5
#define HEAD_RADIUS 1.0

double cubeX[] = { 5.0, 25.0, 55.0, 65.0};
double cubeY[] = { 3.0, 6.0, 9.0, 12.0};
double cubeZ[] = { 0.0, 25.0, 75.0, 49.0};
double cubeR[] = { 1.0, 0.0, 0.0, 0.0 };
double cubeG[] = { 0.0, 1.0, 0.0, 1.0 };
double cubeB[] = { 0.0, 0.0, 1.0, 1.0 };

double xPos = 2.0, zPos = 5.0;
double eyeHeight = 4.5;
double eyeIncline = -0.5;
double lookAngle = 0.0; //In rads

double posIncr = 0.25;
double thetaIncr = 0.1;

typedef float point[3];

static GLfloat theta[11] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,
            180.0,0.0,180.0,0.0}; /* initial joint angles */
static GLint angle = 2;

GLUquadricObj *t, *h, *lua, *lla, *rua, *rla, *lll, *rll, *rul, *lul, *lf1, *lf2;

double size=1.0;

void torso()
{
   glPushMatrix();
   glRotatef(-90.0, 1.0, 0.0, 0.0);
   gluCylinder(t,TORSO_RADIUS, TORSO_RADIUS, TORSO_HEIGHT,10,10);
   glPopMatrix();
}

void head()
{
   glPushMatrix();
   glTranslatef(0.0, 0.5*HEAD_HEIGHT,0.0);
   glScalef(HEAD_RADIUS, HEAD_HEIGHT, HEAD_RADIUS);
   gluSphere(h,1.0,10,10);
   glPopMatrix();
}

void left_upper_arm()
{
   glPushMatrix();
   glRotatef(-90.0, 1.0, 0.0, 0.0);
   gluCylinder(lua,UPPER_ARM_RADIUS, UPPER_ARM_RADIUS, UPPER_ARM_HEIGHT,10,10);
   glPopMatrix();
}

void left_lower_arm()
{
   glPushMatrix();
   glRotatef(-90.0, 1.0, 0.0, 0.0);
   gluCylinder(lla,LOWER_ARM_RADIUS, LOWER_ARM_RADIUS, LOWER_ARM_HEIGHT,10,10);
   glPopMatrix();
}

void left_finger1()
{
   glPushMatrix();
   glRotatef(-90.0, 1.0, 0.0, 0.0);
   gluCylinder(lf1,FINGER_1_RADIUS, FINGER_1_RADIUS, FINGER_1_HEIGHT,10,10);
   glPopMatrix();
}

void left_finger2()
{
   glPushMatrix();
   glRotatef(-90.0, 1.0, 0.0, 0.0);
   gluCylinder(lla,LOWER_ARM_RADIUS, LOWER_ARM_RADIUS, LOWER_ARM_HEIGHT,10,10);
   glPopMatrix();
}

void right_upper_arm()
{
   glPushMatrix();
   glRotatef(-90.0, 1.0, 0.0, 0.0);
   gluCylinder(rua,UPPER_ARM_RADIUS, UPPER_ARM_RADIUS, UPPER_ARM_HEIGHT,10,10);
   glPopMatrix();
}

void right_lower_arm()
{
   glPushMatrix();
   glRotatef(-90.0, 1.0, 0.0, 0.0);
   gluCylinder(rla,LOWER_ARM_RADIUS, LOWER_ARM_RADIUS, LOWER_ARM_HEIGHT,10,10);
   glPopMatrix();
}

void left_upper_leg()
{
   glPushMatrix();
   glRotatef(-90.0, 1.0, 0.0, 0.0);
   gluCylinder(lul,UPPER_LEG_RADIUS, UPPER_LEG_RADIUS, UPPER_LEG_HEIGHT,10,10);
   glPopMatrix();
}

void left_lower_leg()
{
   glPushMatrix();
   glRotatef(-90.0, 1.0, 0.0, 0.0);
   gluCylinder(lll,LOWER_LEG_RADIUS, LOWER_LEG_RADIUS, LOWER_LEG_HEIGHT,10,10);
   glPopMatrix();
}

void right_upper_leg()
{
   glPushMatrix();
   glRotatef(-90.0, 1.0, 0.0, 0.0);
   gluCylinder(rul,UPPER_LEG_RADIUS, UPPER_LEG_RADIUS, UPPER_LEG_HEIGHT,10,10);
   glPopMatrix();
}

void right_lower_leg()
{
   glPushMatrix();
   glRotatef(-90.0, 1.0, 0.0, 0.0);
   gluCylinder(rll,LOWER_LEG_RADIUS, LOWER_LEG_RADIUS, LOWER_LEG_HEIGHT,10,10);
   glPopMatrix();
}

void drawCube( int i )
{
   double x = cubeX[i];
   double y = cubeY[i];
   double z = cubeZ[i];


   glPushMatrix();
   glColor3i(1, 0, 0); //Red cube
   glTranslatef(x,y,z);
   glutSolidCube(5);
   glPopMatrix();

   glColor3i(0, 1, 0); //Green Cube
   glPushMatrix();
   glTranslatef(x,y,z);
   glutSolidCube(10);
   glPopMatrix();

   glColor3i(0, 0, 1); //Blue Cube
   glPushMatrix();
   glTranslatef(x,y,z);
   glutSolidCube(15);
   glPopMatrix();

   glColor3i(0, 1, 1); //Purple Cube
   glPushMatrix();
   glTranslatef(x,y,z);
   glutSolidCube(10);
   glPopMatrix();

}

void drawCubes(void)
{
   glPushMatrix();
   glLoadName(1);
   glTranslatef(0.0, -10.0, 0.0);
   drawCube(0);
   glPopMatrix();

   glPushMatrix();
   glLoadName(2);
   glTranslatef(0.0, -10.0, 0.0);
   drawCube(1);
   glPopMatrix();

   glPushMatrix();
   glLoadName(3);
   glTranslatef(0.0, -10.0, 0.0);
   drawCube(2);
   glPopMatrix();

   glPushMatrix();
   glLoadName(4);
   glTranslatef(0.0, -10.0, 0.0);
   drawCube(3);
   glPopMatrix();

 /* Set name back to '0' to indicate background. */
   glLoadName(0);
}

void drawFloor(void)
{
   GLfloat mat_diffuse[] = { 0.5, 0.5, 0.5, 1.0 };
   glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
   glPushMatrix();
   glTranslatef(0.0, -10.0, 0.0);
   glBegin(GL_POLYGON);
      glNormal3f(0.0, 1.0, 0.0);
      glVertex3f(-100.0, 0.0, -100.0);
      glVertex3f(100.0, 0.0, -100.0);
      glVertex3f(100.0, 0.0,  100.0);
      glVertex3f(-100.0, 0.0,  100.0);
   glEnd();
   glPopMatrix();
}

void doDrawing(void)
{
   drawCubes();

   drawFloor();

 /* Everything else is a lighter shade of grey. */
   GLfloat mat_diffuse[] = { 0.8, 0.8, 0.8, 1.0 };
   glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
}

void drawEnviro(void)
{
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
   double atx = xPos + cos(lookAngle);
   double atz = zPos + sin(lookAngle);
   double atHeight = eyeHeight + eyeIncline;
   gluLookAt(xPos, eyeHeight, zPos, atx, atHeight, atz, 0.0, 1.0, 0.0);

   glPushMatrix();
   doDrawing();
   glPopMatrix();
}

void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    drawEnviro();
    glLoadIdentity();
    gluLookAt(0, 0, -20, 0, 0, -1, 0, 1, 0);
    glColor3f(0.0, 0.0, 0.0);

    glRotatef(theta[0], 0.0, 1.0, 0.0);
    torso();
    glPushMatrix();

    glTranslatef(0.0, TORSO_HEIGHT+0.5*HEAD_HEIGHT, 0.0);
    glRotatef(theta[1], 1.0, 0.0, 0.0);
    glRotatef(theta[2], 0.0, 1.0, 0.0);
    glTranslatef(0.0, -0.5*HEAD_HEIGHT, 0.0);
    head();

    glPopMatrix();
    glPushMatrix();
    glTranslatef(-(TORSO_RADIUS + UPPER_ARM_RADIUS), 0.9 * TORSO_HEIGHT, 0.0);
    glRotatef(theta[3], 1.0, 0.0, 0.0);
    left_upper_arm();

    glTranslatef(0.0, UPPER_ARM_HEIGHT, 0.0);
    glRotatef(theta[4], 1.0, 0.0, 0.0);
    left_lower_arm();

    glTranslatef(0.0, LOWER_ARM_HEIGHT, 0.0);
    glRotatef(theta[11], 1.0, 0.0, 0.0);
    left_finger1();

    glPopMatrix();
    glPushMatrix();
    glTranslatef(TORSO_RADIUS+UPPER_ARM_RADIUS, 0.9*TORSO_HEIGHT, 0.0);
    glRotatef(theta[5], 1.0, 0.0, 0.0);
    right_upper_arm();

    glTranslatef(0.0, UPPER_ARM_HEIGHT, 0.0);
    glRotatef(theta[6], 1.0, 0.0, 0.0);
    right_lower_arm();

    glPopMatrix();
    glPushMatrix();
    glTranslatef(-(TORSO_RADIUS+UPPER_LEG_RADIUS), 0.1*UPPER_LEG_HEIGHT, 0.0);
    glRotatef(theta[7], 1.0, 0.0, 0.0);
    left_upper_leg();

    glTranslatef(0.0, UPPER_LEG_HEIGHT, 0.0);
    glRotatef(theta[8], 1.0, 0.0, 0.0);
    left_lower_leg();

    glPopMatrix();
    glPushMatrix();
    glTranslatef(TORSO_RADIUS+UPPER_LEG_RADIUS, 0.1*UPPER_LEG_HEIGHT, 0.0);
    glRotatef(theta[9], 1.0, 0.0, 0.0);
    right_upper_leg();

    glTranslatef(0.0, UPPER_LEG_HEIGHT, 0.0);
    glRotatef(theta[10], 1.0, 0.0, 0.0);
    right_lower_leg();

    glPopMatrix();

    glFlush();
    glutSwapBuffers();
}

void setProjection(void)
{
   gluPerspective(60.0, 1.0, 0.1, 100.0);
}

void mouse(int btn, int state, int x, int y)
{
      if(btn==GLUT_LEFT_BUTTON && state == GLUT_DOWN)
        {
        theta[angle] += 5.0;
        if( theta[angle] > 360.0 ) theta[angle] -= 360.0;
        }
      if(btn==GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
        {
        theta[angle] -= 5.0;
        if( theta[angle] < 360.0 ) theta[angle] += 360.0;
        }
        display();
}

void menu(int id)
{
   if (id < 11 ) angle = id;
   if (id == 11 ) exit(0);
}

void specialKey(int k, int x, int y)
{
 /* Accept commands to move the viewpoint. */
   switch (k) {
      case GLUT_KEY_UP:
         xPos += posIncr * cos(lookAngle);
         zPos += posIncr * sin(lookAngle);
         break;
      case GLUT_KEY_DOWN:
         xPos -= posIncr * cos(lookAngle);
         zPos -= posIncr * sin(lookAngle);
         break;
      case GLUT_KEY_LEFT:
         lookAngle -= thetaIncr;
         break;
      case GLUT_KEY_RIGHT:
         lookAngle += thetaIncr;
         break;
      case GLUT_KEY_PAGE_UP:
         eyeIncline += 0.5;
         break;
      case GLUT_KEY_PAGE_DOWN:
         eyeIncline -= 0.5;
         break;
      case GLUT_KEY_HOME:
         eyeHeight += 0.5;
         break;
      case GLUT_KEY_END:
         eyeHeight -= 0.5;
         break;
      default:
         return;
   }
   glutPostRedisplay();
}

void reshape(int w, int h)
{
  glViewport(0, 0, w, h);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluPerspective (65.0, w/h, 1, 1000.0);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
}

void init()
{
        GLfloat mat_specular[]={1.0, 1.0, 1.0, 1.0};
        GLfloat mat_diffuse[]={1.0, 1.0, 1.0, 1.0};
        GLfloat mat_ambient[]={1.0, 1.0, 1.0, 1.0};
        GLfloat mat_shininess={100.0};
        GLfloat light_ambient[]={0.0, 0.0, 0.0, 1.0};
        GLfloat light_diffuse[]={1.0, 1.0, 1.0, 1.0};
        GLfloat light_specular[]={1.0, 1.0, 1.0, 1.0};
        GLfloat light_position[]={10.0, 10.0, 10.0, 0.0};

        glLightfv(GL_LIGHT0, GL_POSITION, light_position);
        glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
        glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
        glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);

        glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
        glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
        glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
        glMaterialf(GL_FRONT, GL_SHININESS, mat_shininess);

        glShadeModel(GL_SMOOTH);
        glEnable(GL_LIGHTING);
        glEnable(GL_LIGHT0);
        glDepthFunc(GL_LEQUAL);
        glEnable(GL_DEPTH_TEST);

        glClearColor(0.0, 0.0, 0.0, 0.0);
        glMatrixMode(GL_PROJECTION);

        glLoadIdentity();
        setProjection();

        //Fill the body parts of the robot
        h=gluNewQuadric();
        gluQuadricDrawStyle(h, GLU_FILL);
        t=gluNewQuadric();
        gluQuadricDrawStyle(t, GLU_FILL);
        lua=gluNewQuadric();
        gluQuadricDrawStyle(lua, GLU_FILL);
        lla=gluNewQuadric();
        gluQuadricDrawStyle(lla, GLU_FILL);
        rua=gluNewQuadric();
        gluQuadricDrawStyle(rua, GLU_FILL);
        rla=gluNewQuadric();
        gluQuadricDrawStyle(rla, GLU_FILL);
        lul=gluNewQuadric();
        gluQuadricDrawStyle(lul, GLU_FILL);
        lll=gluNewQuadric();
        gluQuadricDrawStyle(lll, GLU_FILL);
        rul=gluNewQuadric();
        gluQuadricDrawStyle(rul, GLU_FILL);
        rll=gluNewQuadric();
        gluQuadricDrawStyle(rll, GLU_FILL);
        lf1=gluNewQuadric();
        gluQuadricDrawStyle(lf1, GLU_FILL);

}

int main(int argc, char **argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize(500, 500);
    glutCreateWindow("robot");
    init();
    glutReshapeFunc(reshape);
    glutDisplayFunc(display);
    glutMouseFunc(mouse);
    glutSpecialFunc(specialKey);

    glutCreateMenu(menu);
    glutAddMenuEntry("torso", 0);
    glutAddMenuEntry("head1", 1);
    glutAddMenuEntry("head2", 2);
    glutAddMenuEntry("right_upper_arm", 3);
    glutAddMenuEntry("right_lower_arm", 4);
    glutAddMenuEntry("left_upper_arm", 5);
    glutAddMenuEntry("left_lower_arm", 6);
    glutAddMenuEntry("right_upper_leg", 7);
    glutAddMenuEntry("right_lower_leg", 8);
    glutAddMenuEntry("left_upper_leg", 9);
    glutAddMenuEntry("left_lower_leg", 10);
    glutAddMenuEntry("quit", 11);
    glutAttachMenu(GLUT_MIDDLE_BUTTON);

    glutMainLoop();

    return 0;
}