making the light stationary

so i read everywhere and it says if you put the light position right after you load identity for modelview matrix it would not be moved when u move ur camera…well mine does…im changing the view by incrementing and decrementing the 1st 6 arguments of glLookAt(); which should not in any way affect my light positions but it moves :frowning:

heres’s the code … help plz ive been at this for 2 days and im almost about to trash my pc :@



void myInit()
{
glClearColor(1.0,1.0,1.0,0.0);
glPointSize(4.0);


   
   glClearColor (0.0, 0.0, 0.0, 0.0);
   glShadeModel (GL_SMOOTH);


   
   glLightModelfv(GL_LIGHT_MODEL_AMBIENT, global_ambient); 
   glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
   
   glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,mdiffuse_ambient);
   glMaterialfv(GL_FRONT, GL_SHININESS, mshininess);
   glMaterialfv(GL_FRONT, GL_SPECULAR, mspecular);
   
   /*glLightfv(GL_LIGHT0,GL_AMBIENT,ambient0);
   glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuse0);
   glLightfv(GL_LIGHT0,GL_SPECULAR,specular0);
   glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION,spot_dir0);
   glLightfv(GL_LIGHT0,GL_SPOT_CUTOFF,spot_cutoff0);
   glLightfv(GL_LIGHT0,GL_SPOT_EXPONENT,spot_exp0);*/
  
   glLightfv(GL_LIGHT1,GL_DIFFUSE,diffuse1);
   glLightfv(GL_LIGHT1,GL_SPECULAR,specular1);

   glLightfv(GL_LIGHT2,GL_DIFFUSE,diffuse2);
   glLightfv(GL_LIGHT2,GL_SPECULAR,specular2);
   glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION,spot_dir0);

   glLightfv(GL_LIGHT3,GL_DIFFUSE,diffuse3);
   glLightfv(GL_LIGHT3,GL_SPECULAR,specular3);

   glEnable(GL_NORMALIZE);
   glEnable(GL_DEPTH_TEST);
   glEnable(GL_LIGHTING);
   glEnable(GL_LIGHT1); 
   //glEnable(GL_LIGHT2);
   //glEnable(GL_LIGHT3);


   
   
   //glEnable(GL_COLOR_MATERIAL);
   //glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);

   

   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   gluPerspective(120, 1, 1.0, 2000.0);


   glMatrixMode(GL_MODELVIEW);
   glPushMatrix();
   glLoadIdentity();
 
  // GLfloat light_position0[] = { 800,500,-800, 1.0 };
  // glLightfv(GL_LIGHT0, GL_POSITION, light_position0);
   GLfloat light_position1[] = { -800.0,300,-1000.0, 1.0};
   glLightfv(GL_LIGHT1, GL_POSITION, light_position1);
   GLfloat light_position2[] = { 1000.0,500,-800.0, 1.0};
   glLightfv(GL_LIGHT2, GL_POSITION, light_position2);
   GLfloat light_position3[] = { 1200.0,300,-1600.0, 1.0};
   glLightfv(GL_LIGHT3, GL_POSITION, light_position3);
   glEnable(GL_LIGHTING);
   glEnable(GL_LIGHT1); 

  glPopMatrix();

   gluLookAt(x,y,z,0.0,0.0,-400.0,0.0,1.0,0.0);

}

I don’t know where you read that, but it’s wrong. To make the light stationary w.r.t. WORLD space, you need to position the light in WORLD space – that is, with only the viewing transform on the MODELVIEW stack (i.e. gluLookAt).

However, you’re positioning it even before you put the viewing transform on the stack (in which case your viewing transform is the identity, meaning WORLD space == EYE space – remember viewing transform takes you from WORLD space to EYE space), so you’re positioning your light at a constant location in EYE space. That means as your eye moves, so does the light source with it.

so you’re saying that my code is set up for stationary light right? but it still moves as i move the camera…can you be more specific where i put my position code plz

also i dont have any transformation (rotate or translate etc) in my program

thanks
Raza

i give up… i didnt wanna put my code online coz this is for uni assignment but here it is …

plz dont mind the messy object modelling…still need to clean it up…

i think the problem might be in the way im moving the camera…plz take a look at the change(), reshap() and init() functions

if you run it press F1 for help on keys…it’ll pop in the output window

im using visual studio 2008


#include <iostream>
#include <stdlib.h>	
#include <GL/glut.h>
#include <GL/gl.h>
#include <ctime>
#include <math.h>
#define PI 3.1415926

   GLfloat diffuse0[] = {1.0,1.0,0.0,1.0};
   GLfloat ambient0[] = {0.0,0.0,0.0,1.0};
   GLfloat specular0[] = {1.0,1.0,0.0,1.0};

   GLfloat diffuse1[] = {0.4,0.4,0.4,1.0};
   GLfloat specular1[] = {0.5,0.5,0.5,1.0};

   GLfloat diffuse2[] = {0.4,0.4,0.4,1.0};
   GLfloat specular2[] = {0.5,0.5,0.5,1.0};

   GLfloat diffuse3[] = {0.4,0.4,0.4,1.0};
   GLfloat specular3[] = {0.5,0.5,0.5,1.0};
  
   GLfloat mspecular[] = {1.0,1.0,1.0,1.0};
   GLfloat mbspecular[] = {0.0,0.0,1.0,1.0};
   GLfloat mdiffuse_ambient[] = {1.0,1.0,1.0,1.0};
   GLfloat mbdiffuse_ambient[] = {0.0,0.0,1.0,1.0};
   GLfloat mshininess[] = {128.0};

   GLfloat global_ambient[] = {0.0,0.0,0.0,1.0};
   
   GLfloat spot_dir0[] = {-0.9,-1.0,-1.5};
   GLfloat spot_cutoff0[] = {70.0};
   GLfloat spot_exp0[] = {128.0};

class point
{
public:
 int x,y,z;
};

point mesh2[10000][4];
point mesh[10000][4];
int minx=-400,maxx=400,minz=-1600,maxz=1000,xinc=20,zinc=20;
int stack=0,mesh2count=0; // count for squares
int x=-800,y=500,z=400,cx=0,cy=0,cz=0;


using namespace std;

void initialize()
{
   int x=minx,z=minz;
		for(z=minz;z<=maxz;z+=zinc) {  // row
			for(int x=minx;x<=maxx;x+=xinc) {  // coloums
               
               mesh[stack][0].x=x;
					mesh[stack][0].y=0;
               mesh[stack][0].z=z;
					mesh[stack][1].x=x;
               mesh[stack][1].y=0;
               mesh[stack][1].z=z+zinc;
               mesh[stack][2].x=x+xinc;
               mesh[stack][2].y=0;
					mesh[stack][2].z=z+zinc;
               mesh[stack][3].x=x+xinc;
               mesh[stack][3].y=0;
               mesh[stack][3].z=z;
					stack++;
			}
      }
}


void elevate()
{
	int yoff=0,d1y=140,d2y=200,d3y,d4y; 
	
   int rinc=0;
   
   for(int j=41*1;j<=41*126;j+=41) {
		
      d3y=d1y;
      d4y=d2y;
      rinc+=1;
      for(int i=1;i<=38;i++) {
			yoff=d3y+ rand()/(RAND_MAX/(d4y-d3y+1)+1);
         mesh[i+j][3].y+=yoff;

         
            if(d3y<=d2y*2  && j<=41*40) {
               d3y+=int(rinc/3);
               d4y+=int(rinc/3);
            }

            if(d3y<=d2y*2  && j>=41*60 && j<=41*90) {
               d3y+=int(rinc);
               d4y+=int(rinc);
            }

            if(d3y<=d2y*2  && j>=41*90 && i<20) {
               d3y+=int(rinc/5);
               d4y+=int(rinc/5);
            }

            if(d3y<=d2y*2  && j>=41*90 && i>20) {
               d3y-=int(rinc/5);
               d4y-=int(rinc/5);
            }
      }  
      if(j>=41*70)
      {
      d1y+=5;
      d2y+=5;
      }
      if(j <= 41*15) {
			d1y+=20;
         d2y+=20;
      }
      else if(d1y>=30 && j<=41*70) {
         d1y-=30;
         d2y-=30;
      }

	}
    
    for(int j=82*0;j<=82*63;j+=82) {       // copy elevated mesh
		for(int i=0;i<=39;i++) {  	
			
				

		
         mesh2[mesh2count][0].x=mesh[i+j][3].x;
         mesh2[mesh2count][0].y=mesh[i+j][3].y;
         mesh2[mesh2count][0].z=mesh[i+j][3].z;
         mesh2[mesh2count][1].x=mesh[i+j+1][3].x;
         mesh2[mesh2count][1].y=mesh[i+j+1][3].y;
         mesh2[mesh2count][1].z=mesh[i+j+1][3].z;
         mesh2[mesh2count][2].x=mesh[i+j+82+1][3].x;
         mesh2[mesh2count][2].y=mesh[i+j+82+1][3].y;
         mesh2[mesh2count][2].z=mesh[i+j+82+1][3].z;
         mesh2[mesh2count][3].x=mesh[i+j+82][3].x;
         mesh2[mesh2count][3].y=mesh[i+j+82][3].y;
         mesh2[mesh2count][3].z=mesh[i+j+82][3].z;
         mesh2count++;
      }
   }
}    
void myInit()
{

glPointSize(4.0);


   
   glClearColor (0.2, 0.2, 0.2, 0.0);
   glShadeModel (GL_SMOOTH);


   
   glLightModelfv(GL_LIGHT_MODEL_AMBIENT, global_ambient); 
   glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
   
   glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,mdiffuse_ambient);
   glMaterialfv(GL_FRONT, GL_SHININESS, mshininess);
   glMaterialfv(GL_FRONT, GL_SPECULAR, mspecular);
   
   glLightfv(GL_LIGHT0,GL_AMBIENT,ambient0);
   glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuse0);
   glLightfv(GL_LIGHT0,GL_SPECULAR,specular0);
   glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION,spot_dir0);
   glLightfv(GL_LIGHT0,GL_SPOT_CUTOFF,spot_cutoff0);
   glLightfv(GL_LIGHT0,GL_SPOT_EXPONENT,spot_exp0);
  
   glLightfv(GL_LIGHT1,GL_DIFFUSE,diffuse1);
   glLightfv(GL_LIGHT1,GL_SPECULAR,specular1);

   glLightfv(GL_LIGHT2,GL_DIFFUSE,diffuse2);
   glLightfv(GL_LIGHT2,GL_SPECULAR,specular2);

   glLightfv(GL_LIGHT3,GL_DIFFUSE,diffuse3);
   glLightfv(GL_LIGHT3,GL_SPECULAR,specular3);

   glEnable(GL_NORMALIZE);
   glEnable(GL_DEPTH_TEST);
   glEnable(GL_LIGHTING);
   glEnable(GL_LIGHT1); 
   //glEnable(GL_LIGHT2);
  // glEnable(GL_LIGHT3);


   
   
   //glEnable(GL_COLOR_MATERIAL);
   //glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);

   

   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   gluPerspective(120, 1, 1.0, 2000.0);


   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
   gluLookAt(x,y,z,0.0,0.0,-400.0,0.0,1.0,0.0);
   GLfloat light_position0[] = { 300,500,100, 1.0 };
   glLightfv(GL_LIGHT0, GL_POSITION, light_position0);
   GLfloat light_position1[] = { 800.0,900,-1400.0, 1.0  };
   glLightfv(GL_LIGHT1, GL_POSITION, light_position1);
   GLfloat light_position2[] = { 1000.0,500,-800.0, 1.0 };
   glLightfv(GL_LIGHT2, GL_POSITION, light_position2);
   GLfloat light_position3[] = { -900.0,400,-800.0, 1.0 };
   glLightfv(GL_LIGHT3, GL_POSITION, light_position3);
   GLfloat light_position4[] = { -400.0,500,-800.0, 1.0 };
   glLightfv(GL_LIGHT4, GL_POSITION, light_position4);
   glPushMatrix();
   glPopMatrix();
   glLoadIdentity();

   
   

}

void axis()
{
glBegin(GL_LINES);
		glColor3f(0,1,0); // y-axis green
		glVertex3i(0,-400,00);
		glVertex3i(0,800,00);
	glEnd();
}

void normal (point p1,point p2,point p3,point &normal)
{
    point a, b;
 
    // calculate the vectors A and B
    // a
    a.x = p3.x - p2.x;
    a.y = p3.y - p2.y;
    a.z = p3.z - p2.z;
    // b
    b.x = p1.x - p2.x;
    b.y = p1.y - p2.y;
    b.z = p1.z - p2.z;
 
    // calculate the cross product and place the resulting vector
    // into the address specified by vertex_t *normal
    normal.x = ((a.y * b.z) - (a.z * b.y));
    normal.y = ((a.z * b.x) - (a.x * b.z));
    normal.z = ((a.x * b.y) - (a.y * b.x));
 
    // normalize
    float len = (float)(sqrt((double)((normal.x * normal.x) + (normal.y * normal.y) + (normal.z * normal.z))));
 
    // avoid division by 0
    if (len == 0.0f)
        len = 1.0f;
 
    // reduce to unit size
    normal.x /= len;
    normal.y /= len;
    normal.z /= len;
}


void draw()
{
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);	

point norm;
   //sphere2(20,20);
   //glPolygonMode(GL_FRONT_AND_BACK ,GL_LINE);
   
	for(int i=0;i<stack;i++){ // base mesh
		if(mesh[i][3].y==0){		
			if(mesh[i][3].y >=0 && mesh[i][3].y <=30)
				glColor4f(0,0,1,0.6);
		glBegin(GL_QUADS);
      normal(mesh[i][0],mesh[i][1],mesh[i][2],norm);
      glNormal3f(norm.x,norm.y,norm.z);
      glVertex3i(mesh[i][0].x,mesh[i][0].y,mesh[i][0].z);
		glVertex3i(mesh[i][1].x,mesh[i][1].y,mesh[i][1].z);
		glVertex3i(mesh[i][2].x,mesh[i][2].y,mesh[i][2].z);
		glVertex3i(mesh[i][3].x,mesh[i][3].y,mesh[i][3].z);
	glEnd();
		}
	}
   

   glBegin(GL_POINTS);
      glVertex3i(800.0,800,-1400.0);
      glEnd();
   for(int i=0;i<=mesh2count;i++) {  	      // print elevated mesh
			            
      glColor3f(0.0,0.6,0.0); 
      int j=0;
      if(i>=41*21 && i<=41*28) {    // water
         glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,mbdiffuse_ambient);         
         glMaterialfv(GL_FRONT, GL_SPECULAR, mbspecular);
      }
		glBegin(GL_QUADS);
      normal(mesh[i][0],mesh[i][1],mesh[i][2],norm);
      glNormal3f(norm.x,norm.y,norm.z);

            //glNormal3f(mesh2[i][0].x,mesh2[i][0].y,mesh2[i][0].z);
				glVertex3i(mesh2[i][0].x,mesh2[i][0].y,mesh2[i][0].z);

            //glNormal3f(mesh2[i][1].x,mesh2[i][1].y,mesh2[i][1].z);
				glVertex3i(mesh2[i][1].x,mesh2[i][1].y,mesh2[i][1].z);

            //glNormal3f(mesh2[i][2].x,mesh2[i][2].y,mesh2[i][2].z);
				glVertex3i(mesh2[i][2].x,mesh2[i][2].y,mesh2[i][2].z);

            //glNormal3f(mesh2[i][3].x,mesh2[i][3].y,mesh2[i][3].z);
				glVertex3i(mesh2[i][3].x,mesh2[i][3].y,mesh2[i][3].z);
			glEnd();
         glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,mdiffuse_ambient);
         glMaterialfv(GL_FRONT, GL_SPECULAR, mspecular);
		}        
	axis();

}
void myDisplay()
{
	glClear(GL_COLOR_BUFFER_BIT);
   draw();
	glFlush();
	
}

void resetMe()
{
x=-800, y=500, z=400;
myInit();
}

void reshape(int w, int h)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(120, (float)w/(float)h, 1.0, 2000.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(x,y,z,cx,cy,cz,0.0,1.0,0.0);

}

void change(float tx, float ty,float tz, float tcx, float tcy, float tcz)
{
 glMatrixMode(GL_MODELVIEW);
 glLoadIdentity();
 gluLookAt(x+=tx,y+=ty,z+=tz,cx+=tcx,cy+=tcy,cz+=tcz,0.0,1.0,0.0);
}



void cameraHelp()
{
cout << "
HOW TO CONTROL THE VIEW ";
cout << "
left key - " << "Move feet left";
cout << "
Right key - " << "Move feet right";
cout << "
Up key - " << "Move feet up";
cout << "
Down key - " << "Move feet down";
cout << "
Home key - " << "Move camera up";
cout << "
Page Up key - " << "Move camera left";
cout << "
Page Down key - " << "Move camera right";
cout << "
End key - " << "Move camera down";
cout << "
F3 - " << "Reset to original view";
cout << "
F4 - Move along -x axis";
cout << "
F - Move along +x axis";
}

void keyboard (int key, int a, int b)
{
   float x=0.0, y=0.0, z=0.0, cx=0, cy=0, cz=0; ;	
   switch (key) {
		case GLUT_KEY_LEFT:
         z-=20;
         cz-=20;
         change(x, y, z, cx, cy, cz);break;
		case GLUT_KEY_RIGHT: 
        z+=20;
        cz+=20;
        change(x, y, z, cx, cy, cz);break;
		case GLUT_KEY_UP : 
         y+=20;
         cy+=20;
			change(x, y, z, cx, cy, cz);break;
		case GLUT_KEY_DOWN : 
         y-=20;
         cy-=20;
			change(x, y, z, cx, cy, cz);break;
      case GLUT_KEY_F1 :
         cameraHelp();
      case GLUT_KEY_F2 :
        change(x, y, z, cx, cy, cz); break;
         case GLUT_KEY_F3 :
         resetMe(); break;
      case GLUT_KEY_F4 :
         x+=20;
         change(x, y, z, cx, cy, cz);        
         break;
      case GLUT_KEY_F5 :
         x-=20;
         change(x, y, z, cx, cy, cz);
         break;
      case GLUT_KEY_PAGE_UP :
         cz+=20;
         change(x, y, z, cx, cy, cz);break;
      case GLUT_KEY_PAGE_DOWN :
         cz-=20;
         change(x, y, z, cx, cy, cz);break;
      case GLUT_KEY_HOME :
         cy+=20;
         change(x, y, z, cx, cy, cz);break;
case GLUT_KEY_END :
      cy-=20;
         change(x, y, z, cx, cy, cz);break;
   }
}

void main(int argc, char** argv)
{
glutInit(&argc, argv);

glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH );
glutInitWindowSize(600,600);
glutInitWindowPosition(50,50);
glutCreateWindow("3D Viewing System");
myInit();
initialize();
elevate();
glutSpecialFunc (keyboard);
glutDisplayFunc(myDisplay);
glutIdleFunc (myDisplay);
glutReshapeFunc (reshape);
cout << "
 Stack = " << stack;
glutDisplayFunc(myDisplay);
glutMainLoop();
}

                                             

thanks
Raza

I pretty well told you. Read about “Viewing” transformations and “Lighting” in the OpenGL Programming Guide: http://glprogramming.com/red/

ok i figured it out but now im having a problem which im not sure is a problem…

when i move my view point the light doesnt move…

but when i increase the y in lookat(x,y,z,cx,cy,cz…) the specular seems to be moving

is that avoidable? or is my lighting and viewing screwed?

That’s to be expected. Look in the OpenGL Programming Guide, Lighting chapter (here, at the very end of this page, in the sections titled Diffuse Term and Specular Term).

As you can see, the diffuse term directionality is based on “L * n” (i.e. dot(L,n)). This only depends on the light direction and the surface normal. It has nothing to do with the eye. So as the eye moves, you wouldn’t expect this to quantity to change for any point on the surface of the object.

BUT, the specular term is primarily determined by “s * n” (i.e. dot(s,n)) – s is sometimes referred to as “h” or the "half-vector between the light and the eye. As you can see, as the eye moves around, this changes. So you’d expect the specular to change as the eye moves. If you crank the specular exponent up, you can see that this has the effect of the specular highlight trying to follow the eye around in sort-of a light reflection.

That’s to be expected. Look in the OpenGL Programming Guide, Lighting chapter (here, at the very end of this page, in the sections titled Diffuse Term and Specular Term).

As you can see, the diffuse term directionality is based on “L * n” (i.e. dot(L,n)). This only depends on the light direction and the surface normal. It has nothing to do with the eye. So as the eye moves, you wouldn’t expect this to quantity to change for any point on the surface of the object.

BUT, the specular term is primarily determined by “s * n” (i.e. dot(s,n)) – s is sometimes referred to as “h” or the "half-vector between the light and the eye. As you can see, as the eye moves around, this changes. So you’d expect the specular to change as the eye moves. If you crank the specular exponent up, you can see that this has the effect of the specular highlight trying to follow the eye around in sort-of a light reflection.