PDA

View Full Version : making the light stationary



badass
05-27-2010, 09:18 AM
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 :(

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,mdiff use_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_D IFFUSE);



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);

}

Dark Photon
05-27-2010, 05:12 PM
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 :(
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.

badass
05-28-2010, 12:48 AM
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

badass
05-28-2010, 02:03 AM
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 &amp;&amp; j<=41*40) {
d3y+=int(rinc/3);
d4y+=int(rinc/3);
}

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

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

if(d3y<=d2y*2 &amp;&amp; j>=41*90 &amp;&amp; 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 &amp;&amp; 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,mdiff use_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_D IFFUSE);



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 &amp;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 &amp;&amp; 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 &amp;&amp; i<=41*28) { // water
glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,mbdif fuse_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,mdiff use_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+=tc z,0.0,1.0,0.0);
}



void cameraHelp()
{
cout << "\nHOW TO CONTROL THE VIEW ";
cout << "\nleft key - " << "Move feet left";
cout << "\nRight key - " << "Move feet right";
cout << "\nUp key - " << "Move feet up";
cout << "\nDown key - " << "Move feet down";
cout << "\nHome key - " << "Move camera up";
cout << "\nPage Up key - " << "Move camera left";
cout << "\nPage Down key - " << "Move camera right";
cout << "\nEnd key - " << "Move camera down";
cout << "\nF3 - " << "Reset to original view";
cout << "\nF4 - Move along -x axis";
cout << "\nF - 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(&amp;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 << "\n Stack = " << stack;
glutDisplayFunc(myDisplay);
glutMainLoop();
}




thanks
Raza

Dark Photon
05-30-2010, 07:12 PM
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
I pretty well told you. Read about "Viewing" transformations and "Lighting" in the OpenGL Programming Guide: http://glprogramming.com/red/

badass
05-31-2010, 02:59 AM
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?

Dark Photon
05-31-2010, 06:48 AM
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 (http://glprogramming.com/red/chapter05.html), 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.

Dark Photon
05-31-2010, 06:50 AM
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 (http://glprogramming.com/red/chapter05.html), 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.