Lighting

Hi,
How comes when i enable lighting in openGL, everything in the window goes black.

You must setup the lights.

Ok, set up a light with all the properties, two questions.

1, Can i set the actual co-ordinates of the light source so for example, it is in a room.

2, All the colours of my objects have changed, how i get my original colours to stick.

  1. You can put the light anywhere you want.

  2. Make sure that the light is white. Otherwise different colors might be getting relected back.

How do you place the light as the values in the position variable say were the light points?

Thanks

Use 1.0 for the fourth coordinate (W). Then you specif a position instead of a direction.

Ok,
Read the chapter on lighting in the red book and i am completly confused about the whole lighting thing, help would be most appreciated.

Here’s how to setup a few different types of light that might explain things a bit better.

  1. Positional light. This type of light is given a position and emits light in all directions. To do this you use glLightfv with the GL_POSITION. The 4th value in the vector you give MUST have a non-zero value (usually 1.0 is used.) For instance…

float lightpos[] = {0.0, 2.0, 0.0, 1.0};

glLightfv(GL_LIGHT0, GL_POSITION, lightpos);

  1. A directional light. This type of light only has a direction and is treated as though the light is at an infinite position so that the basically all light beams are parallel to each other in the scene. (Kind of like the light from the sun. You move a few feet and the angle between you and the sun is essentially the same.) To do this, you use GL_POSITION and specify 0 for the 4th value in the vector. For instance…

float lightdir[] = {0.0, 0.71, 0.71, 0.0};

glLightfv(GL_LIGHT0, GL_POSITION, lightdir);

  1. A spot light, which has both a direction and a position. You basically combine GL_POSITION with a non-0 value for the 4th element of the coordinate with GL_SPOT_DIRECTION. There is also a cutoff angle on a spot light that you can use to control the “tightness” of the spotlight beam. Like so…

float lightpos[] = {0.0, 2.0, 0.0, 1.0};
float lightdir[] = {0.0, 0.71, 0.71};
float cutoff = 30.0;

glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, lightdir);
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, cutoff);

There are a bunch of other values that can be changed for lights, but these are probably some of the most common you will run into. You can read more about the other things you can set in MSDN or the Red Book.

Ok,
Let’s start with Positional light.

I have a flat rectangle which is used as the floor, around all the edges are walls. Just inside the world walls, is a big building with many rooms inside.

I set a Positional light at 0, 2, 0, 0.
I start at 0, 0, -1.

The wall behind me is always black, dark while the wall at the far side of the map is light, very very light, am i doing something wrong.

Hi,
I am trying to get a light at the front of the building only pointing in throught the door.
This is were the user first starts. If anyone can do this for me or show me, i would be very very grateful. This lighting is starting to get on my nerves. Thanks.

Main.c

///////////////////////////////////////////////////////////////////////////////////
//LOST IN SPACE AND TIME V0.1b (DEVELOPMENT) //
// //
//DESCRIPTION : //
// //
// //
// //
//TODO : //
// //
//Play with shapes //
// //
//COMPLETED : //
// //
//Read .map file and store data in appropate places //
//Setup OpenGL world (Width, Depth Visiability Range) //
//Free Resources and shut down //
//Use glutSpecialFunc to use arrow keys //
//Draw cubes //
//Draw pyramids //
//Add Colour functionality //
//Add Surface normal functionality //
// //
///////////////////////////////////////////////////////////////////////////////////

#include <GL/glut.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <ctype.h>
#include <iostream.h>
#include <fstream.h>

#include <gl\gl.h>
#include <gl\glu.h>
#include <gl\glut.h>

#include “objects.h”
#include “world.h”

#define MAX_SIZE 250000

static float angle=0.0,ratio;
static float x=0.0f,y=1.0f,z=-1.0f;
static float lx=0.0f,ly=0.0f,lz=-1.0f;

float xEyeSpin;

char windowTitle [20];

float visabilityRange;
int worldWidth;
int worldDepth;

int numberRectangles;
int numberTriangles;

GLfloat rectangles[MAX_SIZE];
GLfloat triangles[MAX_SIZE];
GLfloat quadColours[MAX_SIZE];
GLfloat triColours[MAX_SIZE];
GLfloat surfaceNormals[MAX_SIZE];

//AMBIENT = INTENSITY
//DIFFUSE = COLOUR

GLfloat light_position[] = {0.0, 1.0, 60.0, 1.0};

float colour [3] = {1.0,0.0,0.0};//Will Not Be Needed Anymore

///////////////////////////////////////////////////////////////////////////////////

void display(void)
{
int i = 0;
//CLEAR SCREEN TO BLACK
glClearColor (0.0, 0.0, 1.0, 0.0);
glClearDepth (1.0);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

//SETUP SUN
glLightfv(GL_LIGHT0, GL_POSITION, light_position);

//SETUP THE CAMERA
glLoadIdentity ( );							
gluLookAt(x, y, z, 
	      x + lx,y + ly,z + lz,
   		  0.0f,1.0f,0.0f);

//SETUP SURFACE NORMALS
glNormalPointer (GL_FLOAT, 0, surfaceNormals);

//DRAW WORLD BOUNDARIES
DrawInitialWorld (worldWidth, worldDepth - (2 * worldDepth));

glColor3f (1.0, 0.0, 0.0);



//Draw Quads
glColorPointer (3, GL_FLOAT, 0, quadColours);
glVertexPointer (3, GL_FLOAT, 0, rectangles);
glDrawArrays (GL_QUADS, 0, (numberRectangles * 4));

glColor3f (1.0, 1.0, 1.0);

//Draw Triangles
glColorPointer (3, GL_FLOAT, 0, triColours);
glVertexPointer (3, GL_FLOAT, 0, triangles);
glDrawArrays (GL_TRIANGLES, 0, (numberTriangles * 3));

glColor3f (0.0, 0.0, 0.0);

glutSwapBuffers ();

}

///////////////////////////////////////////////////////////////////////////////////

void init (void)
{
//glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
//glEnable(GL_COLOR_MATERIAL);

glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);

}

///////////////////////////////////////////////////////////////////////////////////

void reshape ( int w, int h )
{
glViewport ( 0, 0, w, h ); //SET THE SCREEN CO-ORDINATES
glMatrixMode ( GL_PROJECTION ); //SELECT THE PROJECTION MATRIX
glLoadIdentity ( ); //RESET THE PROJECTION MATRIX
glFrustum (-1, 1, -1, 1, 1, visabilityRange); //SET THE PROJECTION MATRIX
glMatrixMode ( GL_MODELVIEW ); //SELECT THE MODEL MATRIX
}

///////////////////////////////////////////////////////////////////////////////////

void orientMe(float ang) {
lx = sin(ang);
lz = -cos(ang);
}

void moveMeFlat(int i) {
x = x + i*(lx)0.1;
z = z + i
(lz)*0.1;
}

///////////////////////////////////////////////////////////////////////////////////

void keyboard(unsigned char key, int x, int y)
{
glutPostRedisplay ();
}

void keyboardSpecial(int key, int x, int y)
{

switch (key) {
	case GLUT_KEY_LEFT  : angle -= 0.05f;orientMe(angle); break;
	case GLUT_KEY_RIGHT : angle +=0.05f;orientMe(angle);  break;
	case GLUT_KEY_UP    : moveMeFlat(1);				  break;
	case GLUT_KEY_DOWN  : moveMeFlat(-1);				  break;
}

glutPostRedisplay ();

}

///////////////////////////////////////////////////////////////////////////////////

void OpenMapAndParse ()
{
ifstream fin; //FILE POINTER TO MAP FILE
int i;

fin.open("map1.map");	//OPEN THE FILE

//GET WORLD DATA
fin &gt;&gt; worldWidth;
fin &gt;&gt; worldDepth;
fin &gt;&gt; numberRectangles;
fin &gt;&gt; numberTriangles;

//READ RECTANGLE VERTEX DATA
for(i = 0; i &lt; (12 * numberRectangles); i++)
	fin &gt;&gt; rectangles[i];

//READ TRIANGLE VERTEX DATA
for(i = 0; i &lt; (9 * numberTriangles); i++)
	fin &gt;&gt; triangles[i];

//READ QUAD COLOURS DATA
for(i = 0; i &lt; (12 * numberRectangles); i++)
	fin &gt;&gt; quadColours[i];

for(i = 0; i &lt; (9 * numberTriangles); i++)
	fin &gt;&gt; triColours[i];

for(i= 0; i &lt; (3 * (numberRectangles + numberTriangles)); i++)
	fin &gt;&gt; surfaceNormals[i];


fin.close();			//CLOSE THE FILE

}

///////////////////////////////////////////////////////////////////////////////////

int main(int argc, char** argv)
{
//C++ STUFF 1ST
OpenMapAndParse ();

if (worldWidth &gt; worldDepth)
	visabilityRange = worldWidth + 10;

if (worldDepth &gt; worldWidth)
	visabilityRange = worldDepth + 10;

//OPENGL STUFF 2ND
glutInit				( &argc, argv            );
glutInitDisplayMode		( GLUT_DOUBLE | GLUT_RGB );
glutInitWindowSize		( 700, 700               ); 
glutInitWindowPosition	( 100, 100               );
glutCreateWindow		( "hello"                );
init					();
glutDisplayFunc			( display                ); 
glutReshapeFunc			( reshape                );
glutKeyboardFunc		( keyboard               );
glutSpecialFunc			( keyboardSpecial        );
glutMainLoop			();
return 0;   

}

world.h

void DrawInitialWorld (int worldWidth, int worldDepth)
{
int startPoint = (worldWidth / 2) - worldWidth;

glColor3f (1.0, 1.0, 1.0);

//DRAW THE GROUND
glBegin (GL_QUADS);
	glVertex3f (worldWidth / 2,  0, worldDepth);
	glVertex3f (startPoint,		 0, worldDepth);
	glVertex3f (startPoint,		 0, 0);
	glVertex3f (worldWidth / 2,  0, 0);
glEnd ();

glColor3f (0.0, 1.0, 0.0);

//DRAW THE SIDES
glBegin (GL_QUADS);
	glVertex3f( worldWidth / 2, 2,  0);				// FRONT
	glVertex3f( startPoint,     2,  0);				// 
	glVertex3f( startPoint,     -1, 0);				// 
	glVertex3f( worldWidth / 2, -1, 0);				// 

	glVertex3f( worldWidth / 2, 2,  worldDepth);	// BACK
	glVertex3f(	startPoint,     2,  worldDepth);	// 
	glVertex3f( startPoint,     -1, worldDepth);	// 
	glVertex3f( worldWidth / 2, -1, worldDepth);	// 

	glVertex3f( startPoint, 2,  worldDepth);		// LEFT
	glVertex3f( startPoint, 2,  0);					// 
	glVertex3f( startPoint, -1, 0);					// 
	glVertex3f( startPoint, -1, worldDepth);		// 

	glVertex3f( worldWidth / 2, 2,  worldDepth);	// RIGHT
	glVertex3f( worldWidth / 2, 2,  0);				// 
	glVertex3f( worldWidth / 2, -1, 0);				// 
	glVertex3f( worldWidth / 2, -1, worldDepth);	// 
glEnd();						

}

map1.map

60
40
25
4

-25.0 6.0 -5.0 -25.0 6.0 -30.0 -25.0 -1.0 -30.0 -25.0 -1.0 -5.0
25.0 6.0 -30.0 -25.0 6.0 -30.0 -25.0 -1.0 -30.0 25.0 -1.0 -30.0
25.0 6.0 -5.0 25.0 6.0 -30.0 25.0 -1.0 -30.0 25.0 -1.0 -5.0
25.0 6.0 -5.0 2.0 6.0 -5.0 2.0 -1.0 -5.0 25.0 -1.0 -5.0
2.0 6.0 -5.0 -2.0 6.0 -5.0 -2.0 3.0 -5.0 2.0 3.0 -5.0
-2.0 6.0 -5.0 -25.0 6.0 -5.0 -25.0 -1.0 -5.0 -2.0 -1.0 -5.0

5.0 5.0 -5.0 5.0 5.0 -13.0 5.0 -1.0 -13.0 5.0 -1.0 -5.0
25.0 5.0 -15.0 5.0 5.0 -15.0 5.0 -1.0 -15.0 25.0 -1.0 -15.0
9.0 5.0 -15.0 9.0 5.0 -20.0 9.0 -1.0 -20.0 9.0 -1.0 -15.0
5.0 5.0 -19.0 5.0 5.0 -26.0 5.0 -1.0 -26.0 5.0 -1.0 -19.0
9.0 5.0 -24.0 9.0 5.0 -30.0 9.0 -1.0 -30.0 9.0 -1.0 -24.0
23.0 5.0 -15.0 13.0 5.0 -15.0 13.0 -1.0 -16.0 23.0 -1.0 -16.0
25.0 5.0 -16.0 25.0 5.0 -22.0 24.0 -1.0 -22.0 24.0 -1.0 -16.0
25.0 5.0 -23.0 25.0 5.0 -29.0 24.0 -1.0 -29.0 24.0 -1.0 -23.0
23.0 5.0 -30.0 13.0 5.0 -30.0 13.0 -1.0 -29.0 23.0 -1.0 -29.0

-7.0 5.0 -5.0 -7.0 5.0 -7.5 -7.0 -1.0 -7.5 -7.0 -1.0 -5.0
-7.0 5.0 -7.5 -10.0 5.0 -7.5 -10.0 -1.0 -7.5 -7.0 -1.0 -7.5
-10.0 5.0 -5.0 -10.0 5.0 -7.5 -10.0 -1.0 -7.5 -10.0 -1.0 -5.0
-7.0 5.0 -9.5 -8.0 5.0 -9.5 -8.0 -1.0 -9.5 -7.0 -1.0 -9.5
-7.0 5.0 -9.5 -7.0 5.0 -16.5 -7.0 -1.0 -16.5 -7.0 -1.0 -9.5
-7.0 5.0 -16.5 -11.5 5.0 -16.5 -11.5 -1.0 -16.5 -7.0 -1.0 -16.5
-10.0 5.0 -9.5 -10.0 5.0 -16.5 -10.0 -1.0 -16.5 -10.0 -1.0 -9.5
-11.5 5.0 -16.5 -11.5 5.0 -21.5 -11.5 -1.0 -21.5 -11.5 -1.0 -16.5
-11.5 5.0 -21.5 -14.0 5.0 -21.5 -14.0 -1.0 -21.5 -11.5 -1.0 -21.5
-14.0 5.0 -21.5 -14.0 5.0 -30.0 -14.0 -1.0 -30.0 -14.0 -1.0 -21.5

-25.0 6.0 -30.0 -25.0 6.0 -5.0 0.0 18.0 -20.0
-25.0 6.0 -30.0 25.0 6.0 -30.0 0.0 18.0 -20.0
25.0 6.0 -30.0 25.0 6.0 -5.0 0.0 18.0 -20.0
-25.0 6.0 -5.0 25.0 6.0 -5.0 0.0 18.0 -20.0

1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0
1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0
1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0
1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0
1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0
1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0

0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0

1.0 0.0 1.0 1.0 0.0 1.0 1.0 0.0 1.0 1.0 0.0 1.0
1.0 0.0 1.0 1.0 0.0 1.0 1.0 0.0 1.0 1.0 0.0 1.0
1.0 0.0 1.0 1.0 0.0 1.0 1.0 0.0 1.0 1.0 0.0 1.0
1.0 0.0 1.0 1.0 0.0 1.0 1.0 0.0 1.0 1.0 0.0 1.0

0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0
0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0
0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0
0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0
0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0
0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0
0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0
0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0
0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0
0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 1.0

1.0 1.0 0.0 1.0 1.0 0.0 1.0 1.0 1.0
1.0 1.0 0.0 1.0 1.0 0.0 1.0 1.0 1.0
1.0 1.0 0.0 1.0 1.0 0.0 1.0 1.0 1.0
1.0 1.0 0.0 1.0 1.0 0.0 1.0 1.0 1.0

-1 0 0
0 0 1
-1 0 0
0 0 1
0 0 1
0 0 1
-1 0 0
0 0 1
-1 0 0
-1 0 0
-1 0 0
0 -0.164399 0.986394
-0.986394 0.164399 0
-0.986394 0.164399 0
0 0.164399 0.986394
-1 0 0
0 0 1
-1 0 0
0 0 1
-1 0 0
0 0 1
-1 0 0
-1 0 0
0 0 1
-1 0 0
-0.432731 0.901523 0
0 -0.640184 0.768221
-0.432731 -0.901523 0
0 0.780869 0.624695

Thanks to anyone who can help.

I didn’t check your code there but in reply to the previous post, you need to set the w coordinate to 1, not 0 to position the light. Also, it is always a good idea to have a very low level ambient light set up just to be sure that everything is drawing. If you really want to get the full effect, then the ambient light can be taken out when you finish fiddling.

This is just a wild guess since I didn’t really study your code, but bit seems that you have to set the front and back of each rectangle and decide which will be lit. There is a command to choose which side will be lit depending on whether you are describing the vertices in a clockwise or counterclockwise manner.
You need code similar to: glFrontFace( GL_CCW )
and then pay attention to the order of the vertices in each rectangle.
Barry

I took a quick look at your code and ran it. Didn’t notice anything obviously wrong with the code, but running the program makes me think that maybe the normals are messed up.

Also, when you say you just want the light going through the door it sounds like you might be thinking the light will just shine through the door and that the walls will block out light making things dark. This is not the case. OpenGL does not have any knowledge of “objects” so it performs lighting calculations for each vertex without taking any previously drawn primitives into account. (i.e. it won’t automatically do shadows for you.)

I believe I see where you are getting messed up on your normal data as well.

//READ RECTANGLE VERTEX DATA
for(i = 0; i < (12 * numberRectangles); i++)
fin >> rectangles[i];

//READ TRIANGLE VERTEX DATA
for(i = 0; i < (9 * numberTriangles); i++)
fin >> triangles[i];

for(i= 0; i < (3 * (numberRectangles + numberTriangles)); i++)
fin >> surfaceNormals[i];

You are using vertex arrays and do not have the same number of normals as you have vertices. You also seem to have triangles and quads in different arrays, yet you have all the normals in a single array. When you use vertex arrays in OpenGL it works something like this…

Say your array has 1 triangle and you want to draw the indices 0,1,2. Internally the vertex arrays will get drawn something like so

glNormalfv(normals[0]);
glVertex3fv(vertices[0]);
glNormalfv(normals[1]);
glVertex3fv(vertices[1]);
glNormalfv(normals[2]);
glVertex3fv(vertices[2]);

As you see, the indices for the normal array have to match up with the indices in the vertex array. This could very easily explain the weird lighting you are seing because normals play a big part in lighting calculations.

Hi,
I have a surface normal for each face, should i have one for each set of vertices, each corner of a face?

When using vertex arrays and normal arrays, you need one normal per vertex.

I’ve used a function to generate a surface normal for each quad, triangle by using 3 sets of vertices.

B**A

C***

How do i calculate a surface normal for each vertex set?

Ok, for smooth shading, each vertex normal is the normalized sum of all triangle normals of the triangles that share that vertex. However, for objects in which the angle between adjacent faces is large, e.g. a cube or box, you should not add the normals. In that instance, you would need to duplicate the vertex, once with one normal, and one or more other times with other normals.