Results 1 to 6 of 6

Thread: Position Lights :: Fixed relative to scene... How?

  1. #1
    Junior Member Newbie
    Join Date
    Mar 2005
    Location
    Birmingham UK
    Posts
    8

    Position Lights :: Fixed relative to scene... How?

    Edit 15/03/05 : Question answered, code updated.

    I've been going insane over this little problem, which is that I can't fix a GL_POSITION light at a point relative to my scene.

    The light seems to transform with objects. However I don't think it's moving with the camera. I want the light to stay in a fixed point in the scene, independent of everything else.

    Here's a screencap of the problem: Position Lights
    In this vid, as the cubes rotate the sides should change lightness as they get closer/further from the light.

    And here's the code:
    Code :
     
    #include <gl/gl.h>
    #include <gl/glu.h>
    #include <gl/glut.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <math.h>
     
    static GLfloat spin = 0.0;
    static GLfloat osc = 0.0;
    static GLfloat i = 0.0;
    static GLfloat j = 0.15;	//Increment: Adjusts horse bobbing speed
    static GLfloat k = 6.28;	
    static GLfloat l = 0.8;		//Increment: Adjusts rotation speed
     
    GLint height = 50, width = 50;
    GLint globalX, globalY;
     
     
     
    // COORDINATE COLUMNS ::		 X		 Y		 Z
    // base coordinates (left) 
    static GLint baseverts[] =	{	-50,	-40,	 50,		//point 1
    								 50,	-40,	 50,		//point 2
    								 50,	-30,	 50,		//etc
    								-50,	-30,	 50,
    								-50,	-40,	-50,
    								 50,	-40,	-50,
    								 50,	-30,	-50,
    								-50,	-30,	-50
    							};
     
    // base coordinates (left) 
    static GLint topverts[] =	{	-50,	30,		50,		//point 1
    								 50,	30,		50,		//point 2
    								 50,	40,		50,		//etc
    								-50,	40,		50,
    								-50,	30,		-50,
    								 50,	30,		-50,
    								 50,	40,		-50,
    								-50,	40,		-50
    							};
     
     
     
    // box 1 coordinates (left) 
    static GLint box1verts[] =	{	-50,	-10,	 10,		//point 1
    								-30,	-10,	 10,		//point 2
    								-30,	 10,	 10,		//etc
    								-50,	 10,	 10,
    								-50,	-10,	-10,
    								-30,	-10,	-10,
    								-30,	 10,	-10,
    								-50,	 10,	-10
    							};
     
     
    // box 2 coordinates (right)
    static GLint box2verts[] =	{	 30,	-10,	 10,		//point 1
    								 50,	-10,	 10,		//point 2
    								 50,	 10,	 10,		//etc
    								 30,	 10,	 10,
    								 30,	-10,	-10,
    								 50,	-10,	-10,
    								 50,	 10,	-10,
    								 30,	 10,	-10
    							};
     
    // box 3 coordinates (middle) 
    static GLint box3verts[] =	{	-10,	 -30,	10,		//point 1
    								 10,	 -30,	10,		//point 2
    								 10,	 30,	10,		//etc
    								-10,	 30,	10,
    								-10,	 -30,	-10,
    								 10,	 -30,	-10,
    								 10,	 30,	-10,
    								-10,	 30,	-10
    							};
     
    // NORMALS ::					X		Y		Z
    static GLfloat normals[]=	{	-1.0,	-1.0,	1.0,
    								1.0,	-1.0,	1.0,		
    								1.0,	1.0,	1.0,		
    								-1.0,	1.0,	1.0,
    								-1.0,	-1.0,	-1.0,
    								1.0,	-1.0,	-1.0,		
    								1.0,	1.0,	-1.0,
    								-1.0,	1.0,	-1.0};
     
     
     
    // COLOUR COLUMNS ::			R		G		B
    static GLfloat colors[]=	{	1.0,	0.0,	0.0,		//point 1 colors
    								0.0,	1.0,	0.0,		//etc
    								0.0,	0.0,	1.0,
    								0.5,	0.0,	0.0,
    								0.0,	0.5,	0.0,
    								0.0,	0.0,	0.5,
    								1.0,	1.0,	1.0,
    								1.0,	0.0,	1.0};
     
     
     
    //cube indices refs in one array
     
    //					3___________2
    //				   /		   /|
    //				  /			  /	|
    //			    7/___________/6	| RIGHT
    //				 |	|		|   |
    //				 |	0 _		|   |1
    //				 |  /		|  /
    //				 | 			| /
    //				 |__________|/
    //				4	FRONT	 5
     
     
     
    static GLubyte boxIndices[]= {4,5,6,7, 1,2,6,5, 0,1,5,4, 0,3,2,1, 0,4,7,3, 2,3,7,6};
    GLfloat posone [] = { 80.0,	20.0, -80.0, 0.0 };
    GLfloat colone [] = { 1.0, 0.0, 0.0 };
     
    GLfloat postwo [] = { -80.0, 200.0, 80.0, 0.0 };
    GLfloat coltwo [] = { 0.0, 1.0, 0.0 };
     
     
    void display(void)
    {
    	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    	glMatrixMode(GL_MODELVIEW);
    	glLoadIdentity();
     
    	GLdouble eyeX = globalX-(width/2);
    	GLdouble eyeZ = cos(eyeX/width)*2000-1820;
    	//printf("%4.2f\n",eyeZ);
     
    	gluLookAt(eyeX/2,globalY-30,eyeZ, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
    	glEnable(GL_LIGHTING);
    	glLightfv(GL_LIGHT0, GL_COLOR, colone);
    	glLightfv(GL_LIGHT1, GL_COLOR, coltwo);
    	glEnable(GL_LIGHT0);
    	glEnable(GL_LIGHT1);
     
    	glEnable(GL_DEPTH_TEST);
    	glShadeModel(GL_SMOOTH);
    	glEnableClientState(GL_COLOR_ARRAY);
    	glEnableClientState(GL_VERTEX_ARRAY);
    	glEnableClientState(GL_NORMAL_ARRAY);
     
    	glColorPointer(3,GL_FLOAT,0,colors);
     
     
     
     
     
     
     
     
    	glPushMatrix();
     
     
    	glVertexPointer(3,GL_INT,0,baseverts);
    	glNormalPointer(GL_FLOAT,0,normals);
    	glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, boxIndices);
    	glVertexPointer(3,GL_INT,0,topverts);
    	glNormalPointer(GL_FLOAT,0,normals);
    	glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, boxIndices);
     
    	glRotatef(spin,0.0,1.0,0.0);
     
     
     
    	// draw the lot at once
    	glVertexPointer(3,GL_INT,0,box3verts);
    	glNormalPointer(GL_FLOAT,0,normals);
    	glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, boxIndices);
     
     
     
    	glTranslatef(0.0,osc,0.0);
    	glVertexPointer(3,GL_INT,0,box1verts);
     
    	glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, boxIndices);
    	glVertexPointer(3,GL_INT,0,box2verts);
     
    	glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, boxIndices);
     
     
    	glPopMatrix();
     
     
    	glutSwapBuffers();
     
     
    }
     
    void oscDisplay(void)
    {
     
    	osc = sin(i)*20;
    	i = i + j;
    	if (i >k)
    		i = 0;
     
    	glutPostRedisplay();
     
    }
     
    void animDisplay(void)
    {
     
    	osc = sin(i)*20;
    	i = i + j;
    	if (i >k)
    		i = 0;
     
    	spin = spin + l;
    	if (spin > 360.0)
    		spin = spin - 360.0;
     
    	glutPostRedisplay();
    }
     
     
    void spinDisplay(void)
    {
    	spin = spin + l;
    	if (spin > 360.0)
    		spin = spin - 360.0;
     
    	glutPostRedisplay();
     
    }
     
     
     
     
     
     
     
     
     
    // Mouse Control :: Starts and stops animation
    void mouse(int button, int state, int x, int y)
    {
    	switch (button)
    	{
    	case GLUT_LEFT_BUTTON:
    		if (state == GLUT_DOWN)
    			printf("Left Mouse Button Pressed:\n	Horses Bobbing at increments of %f\n",j);
    			glutIdleFunc(oscDisplay);
    		break;
     
    		case GLUT_MIDDLE_BUTTON:
    		if (state == GLUT_DOWN)
    			printf("Middle Mouse Button Pressed:\n	Horses Rotating at increments of %f\n",l);
    			glutIdleFunc(spinDisplay);
    		break;
     
    	case GLUT_RIGHT_BUTTON:
    		if (state == GLUT_DOWN)
    			printf("Right Mouse Button Pressed:\n	Horses Bobbing at increments of %f\n	Horses Rotating at increments of %f\n",j,l);
    			glutIdleFunc(animDisplay);
    		break;
    	default:
    		break;
     
    	}
    }
     
     
    void eyePosition(int x, int y)
     
    {
     glMatrixMode(GL_PROJECTION);
     glLoadIdentity();
     gluPerspective(80,1.0,1,1000);
     glMatrixMode(GL_MODELVIEW);
     glLightfv(GL_LIGHT0, GL_POSITION, posone);
     glLightfv(GL_LIGHT1, GL_POSITION, postwo);
     glutPostRedisplay();
     globalX = x;
     globalY = y;
     
    }
    void reshape(int w, int h)
    {	
    	width	= w;
    	height	= h;	
     
    	glMatrixMode(GL_MODELVIEW);
     
    	glViewport(0,0,(GLsizei) w, (GLsizei) h);
    	printf("Window Resized: Width=%d Height=%d\n",w,h);
    	glutPassiveMotionFunc(eyePosition);
     
     
    }
     
     
     
    int main(int argc, char** argv)
    {
    	glutInit(&amp;argc,argv);
    	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB );
    	glutInitWindowSize(500,500);
    	glutInitWindowPosition(100,100);
    	glutCreateWindow("OpenGL Window");
    	glutReshapeFunc(reshape);
    	glutDisplayFunc(display);
    	glutMouseFunc(mouse);
    	glutMainLoop();
    	return 0;
    }
    Any ideas? Thanks in advance.

  2. #2
    Senior Member Frequent Contributor yooyo's Avatar
    Join Date
    Apr 2003
    Location
    Belgrade, Serbia
    Posts
    872

    Re: Position Lights :: Fixed relative to scene... How?

    glLightfv(GL_LIGHT0, GL_POSITION, position) is affected by current modelview matrix. Try to setup your light source position BEFORE any modelview matrix transformation... like

    Code :
    void display(void)
    {
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     glMatrixMode(GL_MODELVIEW);
     glLoadIdentity();
     glLightfv(GL_LIGHT0, GL_POSITION, position);
    // now you can setup view matrix (gluLookAt())
     
    ...
    }
    You also have a BIG error using opengl matrices. Please read this http://www.sjbaker.org/steve/omniv/p...ion_abuse.html

    yooyo

  3. #3
    Junior Member Newbie
    Join Date
    Mar 2005
    Location
    Birmingham UK
    Posts
    8

    Re: Position Lights :: Fixed relative to scene... How?

    yooyo thanks for your help... I made some changes to my code as you suggested (updated above) but I'm still getting the same problems. I admit I'm not 100% sure about the use of matrix modes (still learning)... just when I think I understand what they do it goes and does something completely unexpected!

    How do I create the light outside of the transform matrix? At the moment it seems to be getting transformed with everything else, even with the changes.

  4. #4
    Senior Member Frequent Contributor yooyo's Avatar
    Join Date
    Apr 2003
    Location
    Belgrade, Serbia
    Posts
    872

    Re: Position Lights :: Fixed relative to scene... How?

    Your eyePosition func is completly wrong. It should looks like:
    Code :
    int globalX, globalY;
    void eyePosition(int x, int y)
    {
     glMatrixMode(GL_PROJECTION);
     glLoadIdentity();
     gluPerspective(80,1.0,1,1000);
     glMatrixMode(GL_MODELVIEW);
     globalX = x;
     globalY = y;
    }
    and in display func you need to do:

    Code :
    void display(void)
    {
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     glMatrixMode(GL_MODELVIEW);
     glLoadIdentity();
     GLfloat position[] = { 80.0, 50.0, -50.0, 1.0 };	 // 1.0 for spot or 0.0 for directional light
     glLightfv(GL_LIGHT0, GL_POSITION, position);
     gluLookAt(globalX-(width/2),globalY,-100.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
    ...
    and you have to provide normal for each vertex if you want to see correct lighting. For your boxes, when face looks to -X vertex normal for all 4 vertices is (-1,0,0), +X -> (1,0,0), -Y -> (0,-1,0), +Y ->(0,1,0), -Z -> (0,0,-1), +Z ->(0,0,1). When you put all this data into vertex arrays, you'l see that vertex have 3 different normals depending on which face you render. So, box have 6 sides, each side has 4 vertices, each vertex has it's position and it's normal. 6sides*4 vertices = 24vertices for box.

    yooyo

  5. #5
    Junior Member Newbie
    Join Date
    Mar 2005
    Location
    Birmingham UK
    Posts
    8

    Re: Position Lights :: Fixed relative to scene... How?

    Thanks again for your help, I have made the corrections you suggested (updated in my original post) and have set up the face normals, and it's looking better! The light is independent of the camera and geometry, remaining in a fixed position.

    The only thing now is that the top faces of the boxes change shade, when I would have thought they would remain the same as these faces' normals are always the same angle in relation to the light.

  6. #6
    Senior Member Frequent Contributor yooyo's Avatar
    Join Date
    Apr 2003
    Location
    Belgrade, Serbia
    Posts
    872

    Re: Position Lights :: Fixed relative to scene... How?

    Do it on this way:
    Code :
    typedef struct tagVertex
    {
     float pos[3];
     float normal[3];
     float color[3];
    } tVertex;
     
    // note that you will repeat some verices, but it this vertices are different because of it's normal is different
    tVertex myBox[] =
    {
    {data for vertex 0},
    {data for vertex 1},
    ...
    {data for vertex 23}
    };
     
    unsigned int myBoxFaces[]=
    {
     ... // fill indices to each face
    };
     
    ...
    glEnableClientState(GL_COLOR_ARRAY);
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_NORMAL_ARRAY);
     
    glColorPointer(3,GL_FLOAT,sizeof(tVertex),myBox[0].color);
    glVertexPointer(3,GL_FLOAT,sizeof(tVertex),myBox[0].pos);
    glNormalPointer(GL_FLOAT,sizeof(tVertex),myBox[0].normal);
    glDrawElements(GL_QUADS, 24, GL_UNSIGNED_INT, myBoxFaces);
    yooyo

Similar Threads

  1. Fixed Pipeline Axis Relative Rotations
    By Carmine in forum OpenGL: Basic Coding
    Replies: 0
    Last Post: 02-06-2016, 09:38 PM
  2. Fog not relative to camera position
    By shouwel in forum OpenGL: Basic Coding
    Replies: 1
    Last Post: 06-03-2013, 02:17 AM
  3. Replies: 0
    Last Post: 01-22-2013, 08:06 AM
  4. getting position relative to normal
    By ocularb0b in forum OpenGL: Basic Coding
    Replies: 0
    Last Post: 03-16-2008, 06:39 AM
  5. Replies: 13
    Last Post: 11-29-2000, 02:19 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Proudly hosted by Digital Ocean