Basic GLSL: Light Position relative to object

Hi,
Im having a question regarding GLSL. So I set a standard light using GL_LIGHT0, and set the position to 0, 3, 0 (xyz). And I put lots of stuff on the scene, under the light (at y = 0). however, all the objects have the same shading behavior: all the light is on their top, which is wrong for an object positioned at different x and z eg: 3, 0, 3.

This is how i set the light


	glLightfv(GL_LIGHT0, GL_POSITION, light0_position);
	glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, light0_direction);

and for the glsl code, i just copy from lighthouse tutorials

http://www.lighthouse3d.com/opengl/glsl/index.php?lights

how can i do multiple object lighted in the scene according to their position in xyz?

thanks in advance

I seem to recall that light positions are transformed by the matrix on top of the modelview stack, which keeps everything in eye space for fixed function lighting. In your case as I understand it you’d probably want to load up an identity prior to issuing your Light calls to pass positions through unmodified.

im a little bit lost here :smiley: kinda new to opengl/glsl programing
here is the onDisplay() method, being called each time the openGL draws the screen:


glLoadIdentity();
camera1.setCamera(cameraDefault, dt);
cManager.checkAllObject();
static GLuint objectList = 0;
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
	
glUseProgram( programObj );
glColor3f(1.0f, 1.0f, 1.0f);
for (int i = 0; i < cManager.objects.size(); i++) {
	glPushMatrix();
	glTranslatef(objects.at(i).x, objects.y, objects.at(i).z());
	glRotatef(objects.at(i)->getAngleX(), 1, 0, 0);
	glRotatef(objects.at(i)->getAngleY(), 0, 1, 0);
	objects.at(i)->drawObject();
	glPopMatrix();
}
	
glDisable(GL_LIGHTING);
glDisable(GL_LIGHT0);
glUseProgram(0);


did i miss anything?

What he’s saying is that you need to position those two glLightfv calls (that set the light POSITION and DIRECTION) carefully. If you want the position and vector you provide to glLightfv to be interpreted as a “world-space” position and vector, then you need to call them right after you initialize your MODELVIEW matrix with the VIEWING transform. That way, the current MODELVIEW will transform your points from WORLD space to EYE space, and OpenGL will store them in EYE space (as it always does):


glLoadIdentity();
camera1.setCamera(cameraDefault, dt);
<<<<  PROBABLY RIGHT HERE >>>>

Probably right here.

hi,

so i started to build a program from scratch and try to do basic lighting. all i want to do is to have a spotlight inside my plane(top of the cube), so basically there will be part that is lighted and part that is not lighted, and i can see the border. this is the entire code hope so you can see my problem straight away:


/*
 *  untitled.cpp
 *  LightTest
 *
 *  Created by Jos Timanta Tarigan on 11/28/09.
 *  Copyright 2009 Linkoping University. All rights reserved.
 *
 */


#include <GLUT/glut.h>

float light0Direction[] = {0, -90, 0};
float light0SpotCutOff = 40.0;
GLuint objectList = 0;

void init(void)
{
	GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0};
	GLfloat mat_shininess[]  = {50.0};
	GLfloat light_position[] = {3.0, 3.0, 3.0, 1.0};
	GLfloat light_ambient[] = {1.0, .0, .0, 1.0};
	GLfloat light_specular[] = {.0, .5, .5, 1.0};
	GLfloat light_diffuse[] = {.0, .1, 1, 1.0};
	glClearColor(.0, .0, .0, .0);
	glShadeModel(GL_SMOOTH);
	
	glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
	glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
	glLightfv(GL_LIGHT0, GL_POSITION, light_position);
	glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
	glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
	glLightfv(GL_LIGHT0, GL_SPECULAR, light_diffuse);
	
	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);
	glEnable(GL_DEPTH_TEST);
}


void display(void)
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glPushMatrix();
	glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, light0Direction);
	glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, light0SpotCutOff);
	
	objectList = glGenLists(1);
	glNewList(objectList, GL_COMPILE);
	glScalef(20.0, 0.1, 10.0f);
	glutSolidCube(1.0);
	glEndList();
	glCallList(objectList);
	//glutSolidCube(1.0);
	
	
	glutSwapBuffers();
}

void reshape(int w, int h)
{
	glViewport(.0, .0, (GLsizei) w, (GLsizei) h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(65.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glTranslatef(.0, .0, -5);
	gluLookAt(.0, 5.0, 7.0,
			  .0, .0, .0,
			  .0, 3.0, .0);
}

int main(int argc, char ** argv)
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
	glutInitWindowSize(1000, 500);
	glutInitWindowPosition(100, 100);
	glutCreateWindow("ARGV");
	init();
	glutDisplayFunc(display);
	glutReshapeFunc(reshape);
	glutMainLoop();
	return 0;
}

its osx based, so you might wanna change the header.
i’ve been playing with the direction and and spotcutoff but the result is either half of them is lighted (splitted in the diagonal) or not lighted at all. any idea?

thanks in advance

I’ll let you answer that question. What is the MODELVIEW matrix set to when you set light 0’s GL_POSITION? Where does that put it in eye space (or world space)? Now what is the MODELVIEW matrix set to when you set light 0’s GL_DIRECTION? Where does that put it in eye space (or world space)?

What world-space cube and light positions/directions are you “trying” to get?

And let me just suggest that that glTranslatef(.0, .0, -5) before your gluLookAt looks like a mistake. Your VIEWING transform should be first on the MODELVIEW stack, before any MODELING transforms are stacked on. And this translate is going on even before your VIEWING transform, which is probably a mistake.

Also, you PushMatrix, but don’t PopMatrix. A bug.

Further, you’re not gonna get nice spotlight falloff with as few verts as you have. Try commenting out GL_LIGHTING and tell GL to render in wireframe, like this:

 //glEnable(GL_LIGHTING);
 glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );

As you can see, there are only 8 vertices in this cube. Lighting is only evaluated at these 8 points and interpolated across. Use more verts to see the cool spotlight effect with falloff.

Once you get going with shaders, you’ll be able to write a shader that’ll evaluate the spotlight for every pixel, regardless of the number of vertices. See the Orange Book for details.