PDA

View Full Version : Spot lights...



savage
31-07-2005, 07:41 PM
Hi All,
I have spent most of the day and yesterday, tearing my hair hout about OpenGL and Spot lights.

Basically I am using glOrtho to rendering a textured background and some text. That is fine, but now I want to add a spot light that moves over the screen only highlighting only the bits of the back ground where the spotlight is. I know I could do this using a Mask, but I'd like to use proper lighting for this effect. Does anyone know a resource or have some sample code that shows this effect in operation. At the moment I only see light when, the spot cutoff is set to 180...
glLightf( GL_LIGHT0, GL_SPOT_CUTOFF, 180.0 );
My spot exponent does not seem to make any difference regardless of what I set it to. It is currently set to...
glLightf( GL_LIGHT0, GL_SPOT_EXPONENT, 15.0 );
and spot direction is set as follows...
spotDirection[0] := 0.0;
spotDirection[1] := 0.0;
spotDirection[2] := -1.0;
glLightfv( GL_LIGHT0, GL_SPOT_DIRECTION, @spotDirection );


What am I missing??

Clootie
31-07-2005, 08:03 PM
And spotDirection declared as..?

technomage
31-07-2005, 08:15 PM
I've not played with spot lights myself much *yet*. But if I get a chance I'll have a look. (I have enough trouble getting *normal* lights to work :wink:

Paulius
31-07-2005, 08:33 PM
Did you set light position? If not there could be a problem with it being directional be default (w = 0). Anyway vertex lighting spotlights will look like crap unless you have zillion poly models, why not use an additively blended projected spotlight texture?

savage
31-07-2005, 09:25 PM
And spotDirection declared as..?

spotDirection : array[0..2] of GLFloat;

savage
31-07-2005, 09:26 PM
Did you set light position? If not there could be a problem with it being directional be default (w = 0). Anyway vertex lighting spotlights will look like crap unless you have zillion poly models, why not use an additively blended projected spotlight texture?

Sorry could you explain what you mean by "additively blended projected spotlight texture". An example maybe?

Clootie
31-07-2005, 09:39 PM
Sorry could you explain what you mean by "additively blended projected spotlight texture". An example maybe?
Quake 2 (3?) "dynamic" lighting of walls by fireballs

Paulius
31-07-2005, 09:51 PM
I'm sure there was a projective texturing example somewhere at delphi3d

Traveler
01-08-2005, 08:08 AM
Alternatively, the tutorials at delphigl.de (http://www.delphigl.de/eng_index.html) may be of some help

JSoftware
01-08-2005, 03:20 PM
you could implement perpixel spotlights as another alternative :D

savage
03-08-2005, 09:50 PM
Ok it seems the reason why my light was not working properly was because my quad was not tessallated enough ( from http://www.opengl.org/resources/features/KilgardTechniques/oglpitfall/ ).

Ok I have that appearing with...

// Start Drawing Our Quads
glBegin(GL_QUADS);
for i := 0 to 43 do
begin
for j := 0 to 43 do
begin
w := 1 / 44 * Application.Width;
h := 1 / 44 * Application.Height;
glTexCoord2f((i+1)/GridWidth, (j+1)/GridHeight); glVertex3f( (i+1)*w, (j+1)*h,0);
glTexCoord2f((i+1)/GridWidth, j /GridHeight); glVertex3f( (i+1)*w, j *h,0);
glTexCoord2f( i /GridWidth, j /GridHeight); glVertex3f( i *w, j *h,0);
glTexCoord2f( i /GridWidth, (j+1)/GridHeight); glVertex3f( i *w, (j+1)*h,0);
end;
end;
glEnd();


Ok but my light still does not appear properly.

I currently have a SpotLight record set as follows...

TLight = record
amb : array[0..3] of GLFloat;
diff : array[0..3] of GLFloat;
spec : array[0..3] of GLFloat;
pos : array[0..3] of GLFloat;
spotDir : array[ 0..2 ] of GLfloat;
spotExp : GLfloat;
spotCutoff : GLfloat;
atten : array[ 0..2 ] of GLfloat;

trans : array[ 0..2 ] of GLfloat;
rot : array[ 0..2 ] of GLfloat;
end;

and populating it as follows...

// ambient
SpotLight.amb[0] := 0.2;
SpotLight.amb[1] := 0.0;
SpotLight.amb[2] := 0.0;
SpotLight.amb[3] := 1.0;

// diffuse
SpotLight.diff[0] := 0.8;
SpotLight.diff[1] := 0.0;
SpotLight.diff[2] := 0.0;
SpotLight.diff[3] := 1.0;

// specular
SpotLight.spec[0] := 0.4;
SpotLight.spec[1] := 0.0;
SpotLight.spec[2] := 0.0;
SpotLight.spec[3] := 1.0;

// position
SpotLight.pos[0] := 0.0;
SpotLight.pos[1] := 0.0;
SpotLight.pos[2] := 0.0;
SpotLight.pos[3] := 1.0;

// direction
SpotLight.spotDir[0] := 0.0;
SpotLight.spotDir[1] := 0.0;
SpotLight.spotDir[2] := -1.0;

// exponent
SpotLight.spotExp := 20.0;

// cutoff
SpotLight.spotCutoff := 60.0;

// attenuation
SpotLight.atten[0] := 1.0;
SpotLight.atten[1] := 0.0;
SpotLight.atten[2] := 0.0;

// translation
SpotLight.trans[0] := 0.0;
SpotLight.trans[1] := 1.25;
SpotLight.trans[2] := 0.0;

// rotation
SpotLight.rot[0] := 0.0;
SpotLight.rot[1] := 0.0;
SpotLight.rot[2] := 0.0;


and I'm setting the light as follows

glLightfv(GL_LIGHT0, GL_POSITION, @SpotLight.pos);
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, @SpotLight.spotDir);


Why is my light not appearing when I use glOrtho for projection?
I know there are other ways to get this effect, but I really want to learn how to do it with OpenGL lighting. I just want the spot light to shine on a small portion of the background texture, or another example would be for the light to only highlight the bits of the background texture that the mouse is over. I'm sure you are all familiar with the effect.

I think my problem is my understanding of the co-ordinate system as it applies to glOrtho. With gluPerspective I sort of understand you need to use small decimal values, but with glOrtho I not sure if that is still the case or not. I think I need to go back to OpenGL school. Can anyone shed some light ( not pun intended ) on the situation?

Paulius
03-08-2005, 10:39 PM
Did a quick test, it works for me

pos[0]:= 0.0;
pos[1]:= 0.0;
pos[2]:= 0.0;
pos[3]:= 1.0;

Dir[0]:= 0.0;
Dir[1]:= 0.0;
Dir[2]:= -1.0;

glLightfv(GL_LIGHT0, GL_POSITION, @pos);
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, @Dir);
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 60);
glLightf( GL_LIGHT0, GL_SPOT_EXPONENT, 20.0);

glenable(Gl_LIGHTING);
glenable(GL_LIGHT0);
glMatrixMode(GL_PROJECTION);
glloadidentity();
glOrtho(0, 1, 0, 1, 10, -10);

glBegin(GL_QUADS);
for i:= 0 to 43 do
begin
for j:= 0 to 43 do
begin
w := 1 / 44;
h := 1 / 44;
glVertex3f((i+1) * w, (j+1) * h, -1);
glVertex3f( i * w, (j+1) * h, -1);
glVertex3f( i * w, j * h, -1);
glVertex3f((i+1) * w, j * h, -1);
end;
end;
glEnd;

savage
03-08-2005, 10:46 PM
My glOrtho is set to glOrtho( 0.0, width, height, 0.0, -1.0, 1.0 );

What is the advantage is there in using your implemenation over mine?

Paulius
03-08-2005, 11:16 PM
Height and width are constants just out of my preference to keep things resolution invariant. Top is more than bottom naturally, if done the other way around winding order changes.
Edit: I used zNear and zFar incorrectly, it should be like yours near < far