Problems when dealing with lighting and shadowing

I am trying to put lights, materials and shadows to my robot arm but unfortunately something weird happens (please compile or see the below picture), now I am still annoying by

  1. Not showing correct lighting and reflection properties as well as material properties

  2. No shadow painted, although I have done the shadow casting in function “void showobj(void)”

I appreciate if anyone can help, I have already working for it 2 days with no progress :frowning:

The following is my code


//Import library
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <math.h>
#include <GL/glut.h>
#include "gsrc.h"	
#include <Windows.h>

const double PI = 3.14159265;
// angles to rotate the base, lower and upper arms of the robot arm
static GLfloat theta, phi, psi = 0.0;
//Starting time
double startT;
//Time Diff variable
double dif,startTime,endTime,deltaT;
//define n
double n = 3;
//Set the parameters of the light number one
GLfloat Xs = 35.0;
GLfloat Ys = 35.0;
GLfloat Zs = 35.0;
//Shadow color
GLfloat shadowcolor[] = {0.0,0.0,0.0};

//initialize the window and everything to prepare for display
void init_gl() {
	//set display color to white
	glClearColor(1,1,1,0);
	//clear and enable z-buffer 
    glClear (GL_DEPTH_BUFFER_BIT);
    glEnable (GL_DEPTH_TEST);
	//clear display window
	glClear(GL_COLOR_BUFFER_BIT);
}

//Draw the base of the robot arm
void draw_base(){
	glPushMatrix();
		//to create the quadric objects
		GLUquadric *qobj,*qobjl,*qobju;
		qobj = gluNewQuadric(); 
		qobjl = gluNewQuadric(); 
		qobju = gluNewQuadric(); 

		//set the color of the cylinder
		glColor3f(1.0,0.0,0.0); 
		//Re-position the cylinder (x-z plane is the base)
		glRotatef(-90,1.0,0.0,0.0);
		//Draw the cylinder
		gluCylinder(qobj, 30.0, 30.0, 40.0, 40.0, 40.0);
		//Draw the upper disk of the base
		gluDisk(qobju,0,30,40,40);

		glPushMatrix();
			//Change the M(lowdisk<updisk)
			glTranslatef(0,0,40);
			glColor3f(0,0,0); 
			//Draw the lower disk of the base
			gluDisk(qobjl,0,30,40,40);
		glPopMatrix();
   glPopMatrix();
}

/****************************Texture Work Starts***************************************/
//Load the raw file for texture
/* Global Declarations */
#define IW	256				// Image Width    
#define IH	256				// Image Height

//3D array to store image data
unsigned char InputImage     [IW][IH][4];  

// Read an input image from a .raw file with double
void ReadRawImage ( unsigned char Image[][IH][4] )
{
	FILE *fp;
	int  i, j, k;
	char* filename;
	unsigned char temp;

	filename = "floor.raw";

	if ((fp = fopen (filename, "rb")) == NULL)
	{
		printf("Error (ReadImage) : Cannot read the file!!
");
		exit(1);
	}

	for ( i=0; i<IW; i++)
	{
		for ( j=0; j<IH; j++)
		{
			for (k = 0; k < 3; k++)       // k = 0 is Red  k = 1 is Green K = 2 is Blue
			{
				fscanf(fp, "%c", &temp);
				Image[i][j][k] = (unsigned char) temp;
			}
			Image[i][j][3] = (unsigned char) 0;         // alpha = 0.0
		}
	}
	fclose(fp);

}

/****************************Texture Work Ends***************************************/

/****************************Light and Shadows***************************************/
void lightsrc(){
	GLfloat light1PosType [] = {Xs, Ys, Zs, 1.0};
	//GLfloat light2PosType [] = {0.0, 100.0, 0.0, 0.0};

	glLightfv(GL_LIGHT1, GL_POSITION, light1PosType);
	//glEnable(GL_LIGHT1);
	//glLightfv(GL_LIGHT2, GL_POSITION, light2PosType);
	//glEnable(GL_LIGHT2);

	GLfloat whiteColor[] = {1.0, 1.0, 1.0, 1.0};
	GLfloat blackColor[] = {0.0, 0.0, 0.0, 1.0};
    glLightfv(GL_LIGHT1, GL_AMBIENT, blackColor);
	glLightfv(GL_LIGHT1, GL_DIFFUSE, whiteColor);
	glLightfv(GL_LIGHT1, GL_SPECULAR, whiteColor);
	glEnable(GL_LIGHT1);

	glEnable( GL_LIGHTING );
}

/****************************Light and Shadows work ends***************************************/

//Draw the 2x2x2 cube with center (0,1,0)
void cube(){ 
	glPushMatrix();
		glTranslatef(0,1,0);
		glutSolidCube(2);
	glPopMatrix();	
}

//Draw the lower arm
void draw_lower_arm(){
	glPushMatrix();
	glScalef(15.0/2.0,70.0/2.0,15.0/2.0);//scale half is enough (some part is in the negative side)
	cube();
	glPopMatrix();
}

//Draw the upper arm
void draw_upper_arm(){
	glPushMatrix();
	glScalef(15.0/2.0,40.0/2.0,15.0/2.0);//scale half is enough (some part is in the negative side)
	cube();
	glPopMatrix();
}

void drawCoordinates(){
	glBegin (GL_LINES);
		glColor3f (1,0,0);
		glVertex3f (0,0,0);
		glVertex3f (600,0,0);

		glColor3f (0,1,0);
		glVertex3f (0,0,0);
		glVertex3f (0,600,0);

		glColor3f (0,0,1);
		glVertex3f (0,0,0);
		glVertex3f (0,0,600);
	glEnd();		
}

//To draw the whole robot arm
void drawRobot(){
	//Robot Drawing Starts
	  //Rotate the base by theta degrees
	  glRotatef(theta,0.0,1.0,0.0); 
	  //Draw the base
	  draw_base();
	  //M(B<La)
	  glTranslatef(0.0,40.0,0.0);
	  //Rotate the lower arm by phi degree
	  glRotatef(phi,0.0,0.0,1.0);
	  //change the color of the lower arm
	  glColor3f(0.0,0.0,1.0);
	  //Draw the lower arm
	  draw_lower_arm();
	  //M(La<Ua)
	  glTranslatef(0.0,70.0,0.0);
	  //Rotate the upper arm by psi degree
	  glRotatef(psi,0.0,0.0,1.0);
	  //change the color of the upper arm
	  glColor3f(0.0,1.0,0.0);
	  //Draw the upper arm
	  draw_upper_arm();
	  //Drawing Finish
	  glutSwapBuffers();
}

void showobj(void) {
   //set the projection and perspective parameters/arguments
    GLint viewport[4];
    glGetIntegerv( GL_VIEWPORT, viewport );
    glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      gluPerspective( 45, double(viewport[2])/viewport[3], 0.1, 1000 );
      glMatrixMode(GL_MODELVIEW);
      glLoadIdentity();
      gluLookAt(-200, 300, 200, 0, 0, 0, 0,1,0 );
	  // get the rotation matrix from the rotation user-interface
	  glMultMatrixf(gsrc_getmo() );  
	  //Clear the display and ready to show the robot arm
	  init_gl();	
	  
	  //put the light source
	  lightsrc();
	  //Draw coordinates
	  drawCoordinates();
	  //give material properties
	    GLfloat diffuseCoeff[] = {0.2, 0.4, 0.9, 1.0}; // kdR= 0.2, kdG= 0.4, kdB= 0.9
		GLfloat specularCoeff[] = {1.0, 1.0, 1.0, 1.0}; // 
		glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, diffuseCoeff);
		glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specularCoeff);
		glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 100.0 ); // ns= 25

	  //Draw the ground floor
	  glColor3f(0.4,0.4,0.4);
	  glPushMatrix();
		glRotatef(90,1,0,0);
		glRectf(-500,-500,500,500);
	  glPopMatrix();
	  
	    int i,j;
		GLfloat M[4][4];
		for (i=0; i<4; i++){
			for (j=0; j<4; j++){
				M[i][j] = 0;
			}
			M[0][0]=M[1][1]=M[2][2]=1;
			M[2][3]=-1.0/Zs;
		}

		//Start drawing shadow
		drawRobot(); // draw the objects
		glPushMatrix( ); // save state
		glMatrixMode(GL_MODELVIEW);
		glTranslatef(Xs, Ys, Zs);// Mwc&#8592;s
		glMultMatrixf(M[4]);// perspective project
		glTranslatef(-Xs, -Ys, -Zs);// Ms&#8592;wc
		glColor3fv (shadowcolor);
		//Draw the robot arm
		drawRobot();
		glPopMatrix(); // restore state
		//Shadow drawing ends
	
	  glFlush ();  
}

//To animate the robot arm
void animate(void)
{
	//get the end time
	endTime = timeGetTime();
	//float angle;
	//calculate deltaT 
	deltaT = (endTime - startTime); //in msecs
	//float test;
	float deltaTSecs = deltaT/1000.0f;  //in secs
	//apply moving equation	
	psi = (90.0) * 0.50 * (1-cos((deltaTSecs/(n+1)) * PI));
	glutPostRedisplay ();
}


//Deal with shadow matrix
void showshadow(){

}

void main (int argc, char** argv)
{ 
	glutInit(&argc, argv); 
	//DOUBLE mode better for animation
	// Set display mode.
	glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB);
	glutInitWindowPosition( 50, 100 ); // Set top-left display-window position.
	glutInitWindowSize( 400, 300 ); // Set display-window width and height.
	glutCreateWindow( "Robot arm : my first self-learning opengl program" ); // Create display window.
	// Register mouse-click and mouse-move glut callback functions
	// for the rotation user-interface.
	//Allow user to drag the mouse and view the object
	glutMouseFunc( gsrc_mousebutton );
	glutMotionFunc( gsrc_mousemove );	
    //record the starting time
	startTime = timeGetTime();
	// Display everything in showobj function
    glutDisplayFunc(showobj); 
	//Perform background processing tasks or continuous animation
	glutIdleFunc(animate);
	glutMainLoop(); 
}

I didn’t see a call to glEnable( GL_LIGHTING ). You should enable this state in order to enable lighting calculations.

Oh…Millions thanks McLeary, Got it after adding glEnable( GL_LIGHTING ), but the outcome still weird, the lines just move abnormally… I can’t explain, you can see it after compilation (even if I have added the command)

But the lighting works after that , really thanks!

Problems still existed, I have discovered that it may be the problem of the perspective matrix, as it cast shadows to the x-y plane. Unfortunately, my robot arm has perform the transformation and use x-z as the ground plane, therefore perspective matrix becomes improper to do the shadow casting, then is there any solutions on my case?

My shadow manipulating process is here, and I think it is ok to show the shadow, but the shadow still does not appear


//shadow drawing starts
	    int i,j;
		GLfloat M[4][4];
		for (i=0; i<4; i++){
			for (j=0; j<4; j++){
				M[i][j] = 0;
			}
		}

		M[0][0]=M[1][1]=M[2][2]=1;
		M[1][3]=-1.0/Ys;
		//Start drawing shadow
		drawRobot(); // draw the objects
		glPushMatrix( ); // save state
		glMatrixMode(GL_MODELVIEW);
		glTranslatef(Xs, Ys, Zs);// Mwc&#8592;s
		glMultMatrixf(M[4]);// perspective project
		glTranslatef(-Xs, -Ys, -Zs);// Ms&#8592;wc
		glColor3fv (shadowcolor);
		//Draw the shadow of robot arm
		drawRobot();
		glPopMatrix(); // restore state
		//Shadow drawing ends

And I’ve recorded the video
<object width=“425” height=“350”> <param name=“movie” value=“OpenGL Robot Hand Shadow Casting Problem - YouTube”></param> <param name=“wmode” value=“transparent”></param> <embed src=“OpenGL Robot Hand Shadow Casting Problem - YouTube” type=“application/x-shockwave-flash” wmode=“transparent” width=“425” height=“350”> </embed></object>