#include <windows.h>
#include <gl\glut.h>
#pragma comment(lib, "opengl32")
#pragma comment(lib, "glut32")
GLfloat rx=0;
GLfloat ry=0;
GLfloat tx=0;
GLfloat ty=0;
GLfloat tz=-9;
GLint tt=0;
int mx,my;
bool ldown=false;
bool rdown=false;
int WinWidth=640;
int WinHeight=480;
GLfloat light_Ka[]={.1, .1, .1, 1};
GLfloat light_Kd[]={.3, .3, .3, 1};
GLfloat light_Ks[]={.1, .1, .1, 1};
GLfloat light_model_Ka[]={.2, .2, .2, 1};
GLfloat pos_light[4]={10,4,10,1},
dir_light[4]={0,-1,0,1};
GLfloat material_Ka[]={.5, .5, .5, 1};
GLfloat material_Kd[]={.4, .6, .8, 1};
GLfloat material_Ks[]={.5, .5, .5, 1};
GLfloat material_Ke[]={0, 0, 0, 1};
GLfloat material_Se=10;
GLuint list_cubes;
void Init()
{
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glEnable(GL_TEXTURE_2D);
glEnable(GL_LIGHTING);
glEnable(GL_NORMALIZE);
int i=3;
glEnable(GL_LIGHT0+i);
glLightfv(GL_LIGHT0+i,GL_AMBIENT,light_Ka);
glLightfv(GL_LIGHT0+i,GL_DIFFUSE,light_Kd);
glLightfv(GL_LIGHT0+i,GL_SPECULAR,light_Ks);
glLightf(GL_LIGHT0+i,GL_SPOT_CUTOFF,60);
glLightf(GL_LIGHT0+i,GL_SPOT_EXPONENT,100);
glLightfv(GL_LIGHT0+i,GL_POSITION,pos_light);
glLightfv(GL_LIGHT0+i,GL_SPOT_DIRECTION,dir_light);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT,light_model_Ka);
glLightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER,1);
glLightModelf(GL_LIGHT_MODEL_TWO_SIDE,1);
glMaterialfv(GL_FRONT,GL_AMBIENT,material_Ka);
glMaterialfv(GL_FRONT,GL_DIFFUSE,material_Kd);
glMaterialfv(GL_FRONT,GL_SPECULAR,material_Ks);
glMaterialfv(GL_FRONT,GL_EMISSION,material_Ke);
glMaterialf(GL_FRONT,GL_SHININESS,material_Se);
list_cubes=glGenLists(1);
glNewList(list_cubes, GL_COMPILE);
for(int y=0;y<200;y++){
for(int x=0;x<200;x++){
glutSolidCube(.1);
glTranslatef(1,0,0);
}
glTranslatef(-200,0,0);
glTranslatef(0,0,1);
}
glEndList();
}
void Display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glLoadIdentity();
glTranslatef(tx,ty,tz);
glTranslatef(0,0,-20);
glRotatef(rx,1,0,0);
glRotatef(ry,0,1,0);
glRotatef(180,0,1,0);
glPushMatrix();
glTranslatef(-100,0,0);
glTranslatef(0,0,-100);
glTranslatef(0,1,0);
glCallList(list_cubes);
glPopMatrix();
glutSwapBuffers();
}
void Reshape(int Width,int Height)
{
glViewport(0,0,Width,Height);
WinWidth=Width;
WinHeight=Height;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45,GLdouble(WinWidth)/WinHeight,1,1000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glutPostRedisplay();
}
void Mouse(int button, int state, int x, int y)
{
if (button==GLUT_LEFT_BUTTON)
{
switch (state)
{
case GLUT_DOWN:
ldown=true;
mx=x;
my=y;
break;
case GLUT_UP:
ldown=false;
break;
}
}
if (button==GLUT_RIGHT_BUTTON)
{
switch (state)
{
case GLUT_DOWN:
rdown=true;
mx=x;
my=y;
break;
case GLUT_UP:
rdown=false;
break;
}
}
}
void MouseMotion(int x, int y)
{
if (ldown)
{
rx+=0.5*(y-my);
ry+=0.5*(x-mx);
mx=x;
my=y;
glutPostRedisplay();
}
if (rdown)
{
tx+=0.01*(x-mx);
if (tt)
tz+=0.01*(y-my);
else
ty+=0.01*(my-y);
mx=x;
my=y;
glutPostRedisplay();
}
}
int main(int argc, char* argv[])
{
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(WinWidth,WinHeight);
glutInitWindowPosition((glutGet(GLUT_SCREEN_WIDTH)-WinWidth)/2,
(glutGet(GLUT_SCREEN_HEIGHT)-WinHeight)/2);
glutCreateWindow("gl_lights");
Init();
glutDisplayFunc(Display);
glutReshapeFunc(Reshape);
glutMouseFunc(Mouse);
glutMotionFunc(MouseMotion);
glutMainLoop();
return 0;
}
[OpenGL] spot light
Hi!
I'm trying to create a spot light. Please help me to find error.
Thanks.
Generally you should copy 'glLightfv(GL_LIGHT0+i,GL_POSITION,pos_light);' code
line from Init() to Display() and make 'i' a global variable, but I have added
some attractions :) -for other users to watch quite cool efect your program
generates.
(and i hope you will forgive me entering the hole code once more)
#include <windows.h>
#include <gl\glut.h>
#pragma comment(lib, "opengl32")
#pragma comment(lib, "glut32")
GLfloat rx=0;
GLfloat ry=0;
GLfloat tx=0;
GLfloat ty=0;
GLfloat tz=-9;
GLint tt=0;
int mx,my;
int i=3; // NEW - now 'i' must be a global variable
// but why are you using it instead of
// simple GL_LIGHT0? me don't know...
bool ldown=false;
bool rdown=false;
int WinWidth=640;
int WinHeight=480;
GLfloat light_Ka[]={.6, .6, .6, 1}; // NEW VALUES
GLfloat light_Kd[]={.3, .3, .3, 1};
GLfloat light_Ks[]={.5, .5, .5, 1};
GLfloat light_model_Ka[]={.2, .2, .2, 1};
GLfloat pos_light[4]={10,10,10,1}, /// NEW POS.Y VALUE - for better effect:) ///
dir_light[4]={0,-1,0,1};
GLfloat material_Ka[]={.5, .5, .5, 1};
GLfloat material_Kd[]={.4, .6, .8, 1};
GLfloat material_Ks[]={.5, .5, .5, 1};
GLfloat material_Ke[]={0, 0, 0, 1};
GLfloat material_Se=10;
GLuint list_cubes;
void Init()
{
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glEnable(GL_TEXTURE_2D);
glEnable(GL_LIGHTING);
glEnable(GL_NORMALIZE);
/// note that 'int i=3;' is moved to global definitions ///
glEnable(GL_LIGHT0+i);
glLightfv(GL_LIGHT0+i,GL_AMBIENT,light_Ka);
glLightfv(GL_LIGHT0+i,GL_DIFFUSE,light_Kd);
glLightfv(GL_LIGHT0+i,GL_SPECULAR,light_Ks);
glLightf(GL_LIGHT0+i,GL_SPOT_CUTOFF,60);
glLightf(GL_LIGHT0+i,GL_SPOT_EXPONENT,100);
glLightfv(GL_LIGHT0+i,GL_POSITION,pos_light);
glLightfv(GL_LIGHT0+i,GL_SPOT_DIRECTION,dir_light);
//glEnable(GL_COLOR_MATERIAL); // NEW, but not necessary /////////////////////
// delete the slashes if want to see the effect,
// otherwise, when color tracking is disabled,
// you will see only these cubes which
// are lightened by the spot light
glLightModelfv(GL_LIGHT_MODEL_AMBIENT,light_model_Ka);
glLightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER,1);
glLightModelf(GL_LIGHT_MODEL_TWO_SIDE,1);
glMaterialfv(GL_FRONT,GL_AMBIENT,material_Ka);
glMaterialfv(GL_FRONT,GL_DIFFUSE,material_Kd);
glMaterialfv(GL_FRONT,GL_SPECULAR,material_Ks);
glMaterialfv(GL_FRONT,GL_EMISSION,material_Ke);
glMaterialf(GL_FRONT,GL_SHININESS,material_Se);
list_cubes=glGenLists(1);
glNewList(list_cubes, GL_COMPILE);
for(int y=0;y<200;y++){
for(int x=0;x<200;x++){
glutSolidCube(.5); /// NEW RADIUS VALUE - for better effect:) ///
glTranslatef(1,0,0);
}
glTranslatef(-200,0,0);
glTranslatef(0,0,1);
}
glEndList();
}
void Display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glLoadIdentity();
glTranslatef(tx,ty,tz);
glTranslatef(0,0,-20);
glRotatef(rx,1,0,0);
glRotatef(ry,0,1,0);
glRotatef(180,0,1,0);
glLightfv(GL_LIGHT0+i,GL_POSITION,pos_light); /// NEW - copied from Init() function ///
glPushMatrix();
glTranslatef(-100,0,0);
glTranslatef(0,0,-100);
glTranslatef(0,1,0);
glCallList(list_cubes);
glPopMatrix();
glutSwapBuffers();
}
void Reshape(int Width,int Height)
{
glViewport(0,0,Width,Height);
WinWidth=Width;
WinHeight=Height;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45,GLdouble(WinWidth)/WinHeight,1,1000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glutPostRedisplay();
}
void Mouse(int button, int state, int x, int y)
{
if (button==GLUT_LEFT_BUTTON)
{
switch (state)
{
case GLUT_DOWN:
ldown=true;
mx=x;
my=y;
break;
case GLUT_UP:
ldown=false;
break;
}
}
if (button==GLUT_RIGHT_BUTTON)
{
switch (state)
{
case GLUT_DOWN:
rdown=true;
mx=x;
my=y;
break;
case GLUT_UP:
rdown=false;
break;
}
}
}
void MouseMotion(int x, int y)
{
if (ldown)
{
rx+=0.5*(y-my);
ry+=0.5*(x-mx);
mx=x;
my=y;
glutPostRedisplay();
}
if (rdown)
{
tx+=0.01*(x-mx);
if (tt)
tz+=0.01*(y-my);
else
ty+=0.01*(my-y);
mx=x;
my=y;
glutPostRedisplay();
}
}
int main(int argc, char* argv[])
{
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(WinWidth,WinHeight);
glutInitWindowPosition((glutGet(GLUT_SCREEN_WIDTH)-WinWidth)/2,
(glutGet(GLUT_SCREEN_HEIGHT)-WinHeight)/2);
glutCreateWindow("gl_lights");
Init();
rx=55; ry=-50; // NEW but not necessary - adjusting camera view; now you don't have
// to look after the spot light - it's in the centre of GLwindow
glutDisplayFunc(Display);
glutReshapeFunc(Reshape);
glutMouseFunc(Mouse);
glutMotionFunc(MouseMotion);
glutMainLoop();
return 0;
}
line from Init() to Display() and make 'i' a global variable, but I have added
some attractions :) -for other users to watch quite cool efect your program
generates.
(and i hope you will forgive me entering the hole code once more)
#include <windows.h>
#include <gl\glut.h>
#pragma comment(lib, "opengl32")
#pragma comment(lib, "glut32")
GLfloat rx=0;
GLfloat ry=0;
GLfloat tx=0;
GLfloat ty=0;
GLfloat tz=-9;
GLint tt=0;
int mx,my;
int i=3; // NEW - now 'i' must be a global variable
// but why are you using it instead of
// simple GL_LIGHT0? me don't know...
bool ldown=false;
bool rdown=false;
int WinWidth=640;
int WinHeight=480;
GLfloat light_Ka[]={.6, .6, .6, 1}; // NEW VALUES
GLfloat light_Kd[]={.3, .3, .3, 1};
GLfloat light_Ks[]={.5, .5, .5, 1};
GLfloat light_model_Ka[]={.2, .2, .2, 1};
GLfloat pos_light[4]={10,10,10,1}, /// NEW POS.Y VALUE - for better effect:) ///
dir_light[4]={0,-1,0,1};
GLfloat material_Ka[]={.5, .5, .5, 1};
GLfloat material_Kd[]={.4, .6, .8, 1};
GLfloat material_Ks[]={.5, .5, .5, 1};
GLfloat material_Ke[]={0, 0, 0, 1};
GLfloat material_Se=10;
GLuint list_cubes;
void Init()
{
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glEnable(GL_TEXTURE_2D);
glEnable(GL_LIGHTING);
glEnable(GL_NORMALIZE);
/// note that 'int i=3;' is moved to global definitions ///
glEnable(GL_LIGHT0+i);
glLightfv(GL_LIGHT0+i,GL_AMBIENT,light_Ka);
glLightfv(GL_LIGHT0+i,GL_DIFFUSE,light_Kd);
glLightfv(GL_LIGHT0+i,GL_SPECULAR,light_Ks);
glLightf(GL_LIGHT0+i,GL_SPOT_CUTOFF,60);
glLightf(GL_LIGHT0+i,GL_SPOT_EXPONENT,100);
glLightfv(GL_LIGHT0+i,GL_POSITION,pos_light);
glLightfv(GL_LIGHT0+i,GL_SPOT_DIRECTION,dir_light);
//glEnable(GL_COLOR_MATERIAL); // NEW, but not necessary /////////////////////
// delete the slashes if want to see the effect,
// otherwise, when color tracking is disabled,
// you will see only these cubes which
// are lightened by the spot light
glLightModelfv(GL_LIGHT_MODEL_AMBIENT,light_model_Ka);
glLightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER,1);
glLightModelf(GL_LIGHT_MODEL_TWO_SIDE,1);
glMaterialfv(GL_FRONT,GL_AMBIENT,material_Ka);
glMaterialfv(GL_FRONT,GL_DIFFUSE,material_Kd);
glMaterialfv(GL_FRONT,GL_SPECULAR,material_Ks);
glMaterialfv(GL_FRONT,GL_EMISSION,material_Ke);
glMaterialf(GL_FRONT,GL_SHININESS,material_Se);
list_cubes=glGenLists(1);
glNewList(list_cubes, GL_COMPILE);
for(int y=0;y<200;y++){
for(int x=0;x<200;x++){
glutSolidCube(.5); /// NEW RADIUS VALUE - for better effect:) ///
glTranslatef(1,0,0);
}
glTranslatef(-200,0,0);
glTranslatef(0,0,1);
}
glEndList();
}
void Display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glLoadIdentity();
glTranslatef(tx,ty,tz);
glTranslatef(0,0,-20);
glRotatef(rx,1,0,0);
glRotatef(ry,0,1,0);
glRotatef(180,0,1,0);
glLightfv(GL_LIGHT0+i,GL_POSITION,pos_light); /// NEW - copied from Init() function ///
glPushMatrix();
glTranslatef(-100,0,0);
glTranslatef(0,0,-100);
glTranslatef(0,1,0);
glCallList(list_cubes);
glPopMatrix();
glutSwapBuffers();
}
void Reshape(int Width,int Height)
{
glViewport(0,0,Width,Height);
WinWidth=Width;
WinHeight=Height;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45,GLdouble(WinWidth)/WinHeight,1,1000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glutPostRedisplay();
}
void Mouse(int button, int state, int x, int y)
{
if (button==GLUT_LEFT_BUTTON)
{
switch (state)
{
case GLUT_DOWN:
ldown=true;
mx=x;
my=y;
break;
case GLUT_UP:
ldown=false;
break;
}
}
if (button==GLUT_RIGHT_BUTTON)
{
switch (state)
{
case GLUT_DOWN:
rdown=true;
mx=x;
my=y;
break;
case GLUT_UP:
rdown=false;
break;
}
}
}
void MouseMotion(int x, int y)
{
if (ldown)
{
rx+=0.5*(y-my);
ry+=0.5*(x-mx);
mx=x;
my=y;
glutPostRedisplay();
}
if (rdown)
{
tx+=0.01*(x-mx);
if (tt)
tz+=0.01*(y-my);
else
ty+=0.01*(my-y);
mx=x;
my=y;
glutPostRedisplay();
}
}
int main(int argc, char* argv[])
{
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(WinWidth,WinHeight);
glutInitWindowPosition((glutGet(GLUT_SCREEN_WIDTH)-WinWidth)/2,
(glutGet(GLUT_SCREEN_HEIGHT)-WinHeight)/2);
glutCreateWindow("gl_lights");
Init();
rx=55; ry=-50; // NEW but not necessary - adjusting camera view; now you don't have
// to look after the spot light - it's in the centre of GLwindow
glutDisplayFunc(Display);
glutReshapeFunc(Reshape);
glutMouseFunc(Mouse);
glutMotionFunc(MouseMotion);
glutMainLoop();
return 0;
}
Hi!
Thanks a lot for your answer!!
One little thing left: I whant a spotlight to be static. Placing line
glLightfv(GL_LIGHT0 + i,GL_POSITION,pos_light); /// NEW - copied from Init() function ///
into Display() after world (camera) transformations makes spotlight dependant from camera position. How this can be avoided?
I use GL_LIGHT0 + i beacause I have 8 lights in my scene and one of them was taken for this example.
Thaks again for your help.
Thanks a lot for your answer!!
One little thing left: I whant a spotlight to be static. Placing line
glLightfv(GL_LIGHT0 + i,GL_POSITION,pos_light); /// NEW - copied from Init() function ///
into Display() after world (camera) transformations makes spotlight dependant from camera position. How this can be avoided?
I use GL_LIGHT0 + i beacause I have 8 lights in my scene and one of them was taken for this example.
Thaks again for your help.
You have almost resolved this problem.
Let's forget about all i have written ealier - it was my first post on the forum and i was a bit excited, but now i am quite fine ;). Let's get back to your version.
Now you know that in Display() the light must be positioned once again (because of transformations). You expect the spot light to be static, so copy 'glLightfv(GL_LIGHT0+i,GL_POSITION,pos_light);' between Push and Pop Matrix, for example after glCallList().
But that's not enough to do the trick - spot light direction is always (0,-1,0,1) as you definied at the code begining, no matter that you pushed the matrix after transformations. So you should copy in here a code which is related to the direction, that is 'glLightfv(GL_LIGHT0+i,GL_SPOT_DIRECTION,dir_light);'.
Changed code lines from Display() are below:
And remember to make an 'i' a global variable, if you haven't done it yet.
Good luck!
[Edited by - TNDenton on June 3, 2006 3:53:24 AM]
Let's forget about all i have written ealier - it was my first post on the forum and i was a bit excited, but now i am quite fine ;). Let's get back to your version.
Now you know that in Display() the light must be positioned once again (because of transformations). You expect the spot light to be static, so copy 'glLightfv(GL_LIGHT0+i,GL_POSITION,pos_light);' between Push and Pop Matrix, for example after glCallList().
But that's not enough to do the trick - spot light direction is always (0,-1,0,1) as you definied at the code begining, no matter that you pushed the matrix after transformations. So you should copy in here a code which is related to the direction, that is 'glLightfv(GL_LIGHT0+i,GL_SPOT_DIRECTION,dir_light);'.
Changed code lines from Display() are below:
glPushMatrix(); glTranslatef(-100,-4,-100); // a little optimisation // This way is cheaper, and I changed Pos.Y for // better view glCallList(list_cubes); glTranslatef(90,20,-120); // not a must, just positions the light nearer glLightfv(GL_LIGHT0+i,GL_SPOT_DIRECTION,dir_light); // it is a must glLightfv(GL_LIGHT0+i,GL_POSITION,pos_light); // it is a must glPopMatrix();
And remember to make an 'i' a global variable, if you haven't done it yet.
Good luck!
[Edited by - TNDenton on June 3, 2006 3:53:24 AM]
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement