PDA

View Full Version : Problems when dealing with lighting and shadowing



openglam
04-03-2011, 09:16 AM
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
http://i102.photobucket.com/albums/m112/ihmcjacky/weird3d.png

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 :(

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!!\n");
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", &amp;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&amp;#8592;s
glMultMatrixf(M[4]);// perspective project
glTranslatef(-Xs, -Ys, -Zs);// Ms&amp;#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(&amp;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();
}

McLeary
04-03-2011, 09:35 AM
I didn't see a call to glEnable( GL_LIGHTING ). You should enable this state in order to enable lighting calculations.

openglam
04-03-2011, 09:40 AM
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!

openglam
04-04-2011, 09:06 PM
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?

openglam
04-04-2011, 11:01 PM
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&amp;#8592;s
glMultMatrixf(M[4]);// perspective project
glTranslatef(-Xs, -Ys, -Zs);// Ms&amp;#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="http://www.youtube.com/v/TBYteXuTdnI"></param> <param name="wmode" value="transparent"></param> <embed src="http://www.youtube.com/v/TBYteXuTdnI" type="application/x-shockwave-flash" wmode="transparent" width="425" height="350"> </embed></object>