0

I am practicing lighting and smooth shading. THe problem is that this code only shines the light for front and the right side , but when the objected is rotated, it shines at constant position (the front and right) and not to the side that are on the positioned light.
If it is still unclearn i am saying that the directed light and position light does not shine at the position as its supposed to and only shines on the front and the right side. please help.

if you need the code ask.

2
Contributors
5
Replies
6
Views
8 Years
Discussion Span
Last Post by MattEvans
0

Am guessing that you have something like:

glTranslatef ( x, y, z );
glRotatef ( t, x, y, z );
....
glLightfv ( GL_POSITION, pos );
....
[draw object]

But see: http://www.opengl.org/sdk/docs/man/xhtml/glLight.xml, specifically:

The position is transformed by the modelview matrix when glLight is called (just as if it were a point), and it is stored in eye coordinates[...]

So, change your code to:

glLightfv ( GL_POSITION, pos );
...
glTranslatef ( x, y, z );
glRotatef ( t, x, y, z );
....
[draw object]

You can also glPushMatrix and transform some, then position the light (coords are obviously in object space), and then glPopMatrix and do the actual drawing.

0

Ovbiously this code is doing something else than what I wanted it to do. I wanted it to shine red on the left of the screen, whenever a part of the box comes near its axis,
and shine , green on the right of the screen, whenever a part of the box comes near its axis, and a spec of white on the right as well. And also when the color shines its backwards, meaning shining green on left and red on right?

please help.

I can see that all of the color works but, its not producing the result i wanted. any help?

here is the code :

#include<iostream>
#include<cstdlib>

#include<GL/glut.h>

using namespace std;


void keyHandler(unsigned char key, int x, int y)
{
	switch(key)
	{
	case 27 : exit(0);

	}

}

void InitRendering()
{
	glEnable(GL_DEPTH_TEST);
	glShadeModel(GL_SMOOTH);
	glEnable(GL_COLOR_MATERIAL);
	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);
	glEnable(GL_LIGHT1);
	//glEnable(GL_NORMALIZE);

}
 void handleResize(int w, int h)
 {
	 glViewport(0,0,w,h);

	 glMatrixMode(GL_PROJECTION);
	 glLoadIdentity();

	 gluPerspective(65.0,(double)w/(double)h,1.0,200.0);



 }

GLfloat Yrot = 0.0;

 void disp(void)
 {
	 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
	 glMatrixMode(GL_MODELVIEW);
	 glLoadIdentity();
	glPushMatrix();


	GLfloat amb[] = {0.2f,0.2f,0.2f,1.0f};
	glLightModelfv(GL_LIGHT_MODEL_AMBIENT,amb);

	GLfloat dif[] = {1.0f,0.0f,0.0f,1.0f};
	GLfloat difPos[] = {-1.0f,0.5f,3.0f,1.0f};
	glLightfv(GL_LIGHT0,GL_DIFFUSE,dif);
	glLightfv(GL_LIGHT0,GL_POSITION,difPos);

	GLfloat dirColor[] = {0.0f,1.0f,0.0f,1.0f};
	GLfloat dirPos[] = {-1.0f,0.5f,3.0f,0.0f};
	glLightfv(GL_LIGHT1,GL_DIFFUSE,dirColor);
	glLightfv(GL_LIGHT1,GL_POSITION,dirPos);

	GLfloat spec[] ={0.5f,0.5f,0.5f,1.0f};
	GLfloat position[] = {1.0f,0.5f,0.0f};
	glLightfv(GL_LIGHT1,GL_SPECULAR,spec);
	glLightfv(GL_LIGHT1,GL_POSITION,position);
	//glLightfv(GL_LIGHT0,GL_AMBIENT,amb);
	

	glColor3f(1.0f,1.0f,0.0f);
	//GLfloat mColor[] = {0.0f,1.0f,0.0f,1.0f};
	//glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,mColor);
		glTranslatef(0.0f,0.0f,-2.0f);
	glRotatef(Yrot,0.0f,1.0f,0.0f);
	glBegin(GL_QUADS);
		
			//FRONT
			glVertex3f(-0.5f,-0.2f,0.0f);
			glVertex3f(0.5f,-0.2f,0.0f);
			glVertex3f(0.5f,0.2f,0.0f);
			glVertex3f(-0.5f,0.2f,0.0f);
			
			//RIGHT SIDE
			glVertex3f(0.5f,-0.2f,0.0f);
			glVertex3f(0.5f,-0.2f,-0.5f);
			glVertex3f(0.5f,0.2f,-0.5f);
			glVertex3f(0.5f,0.2f,0.0f);
			
			//BACK SIDE
			glVertex3f(-0.5f,-0.2f,-0.5f);
			glVertex3f(0.5f,-0.2f,-0.5f);
			glVertex3f(0.5f,0.2f,-0.5f);
			glVertex3f(-0.5f,0.2f,-0.5f);

			//LEFT SIDE
			glVertex3f(-0.5f,-0.2f,-0.5f);
			glVertex3f(-0.5f,-0.2f,0.0f);
			glVertex3f(-0.5f,0.2f,0.0f);
			glVertex3f(-0.5f,0.2f,-0.5f);
	glEnd();
glPopMatrix();
	glutSwapBuffers();
 

 }

 void update(int value)
 {
	Yrot+=2.0;
		if(Yrot > 360)
			Yrot = 0;

		
		glutPostRedisplay();

		glutTimerFunc(100,update,0);

 }


 int main(int argc,char** argv)
 {
	 glutInit(&argc,argv); 
	 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
	 glutInitWindowSize(500,500);

	 glutCreateWindow("Lighting");
	 InitRendering();

	 glutDisplayFunc(disp);
	 glutKeyboardFunc(keyHandler);
	 glutReshapeFunc(handleResize);

	 glutTimerFunc(50,update,0);
	 glutMainLoop();
	 return 0;

 }
0

Some small changes ( in bold ):

[...]

 void disp(void)
 {
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glPushMatrix();
	glTranslatef(0.0f,0.0f,-2.0f);

	GLfloat amb[] = {0.2f,0.2f,0.2f,1.0f};
	glLightModelfv(GL_LIGHT_MODEL_AMBIENT,amb);

	GLfloat dif[] = {0.5f,0.5f,0.0f,1.0f};
	GLfloat difPos[] = {-5.0f,1.5f,8.0f,1.0f};
	glLightfv(GL_LIGHT0,GL_DIFFUSE,dif);
	glLightfv(GL_LIGHT0,GL_POSITION,difPos);

	GLfloat dirColor[] = {0.5f,0.2f,0.0f,1.0f};
	GLfloat dirPos[] = {1.0f,0.4f,8.0f,0.0f};
	glLightfv(GL_LIGHT1,GL_DIFFUSE,dirColor);
	glLightfv(GL_LIGHT1,GL_POSITION,dirPos);

	GLfloat spec[] ={0.5f,0.5f,0.5f,1.0f};
	GLfloat position[] = {1.0f,0.5f,0.0f,0.0f};
	[b]/* You were overwriting GL_LIGHT1 here, I guess you meant GL_LIGHT2?*/
	glLightfv(GL_LIGHT2,GL_SPECULAR,spec);
	glLightfv(GL_LIGHT2,GL_POSITION,position);[/b]
	//glLightfv(GL_LIGHT0,GL_AMBIENT,amb);
	

	glColor3f(1.0f,1.0f,0.0f);
	//GLfloat mColor[] = {0.0f,1.0f,0.0f,1.0f};
	//glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,mColor);
	
	glRotatef(Yrot,0.0f,1.0f,0.0f);
	glBegin(GL_QUADS);
			[b]/* Most importantly; you need to add normals for each face.
			Otherwise, the lighting calculation doesn't work correctly.*/[/b]
			//FRONT
			[b]glNormal3f(0,0,1);[/b]
			glVertex3f(-0.5f,-0.2f,0.0f);
			glVertex3f(0.5f,-0.2f,0.0f);
			glVertex3f(0.5f,0.2f,0.0f);
			glVertex3f(-0.5f,0.2f,0.0f);
			
			//RIGHT SIDE
			[b]glNormal3f(1,0,0);[/b]
			glVertex3f(0.5f,-0.2f,0.0f);
			glVertex3f(0.5f,-0.2f,-0.5f);
			glVertex3f(0.5f,0.2f,-0.5f);
			glVertex3f(0.5f,0.2f,0.0f);
			
			//BACK SIDE
			[b]glNormal3f(0,0,-1);[/b]
			glVertex3f(-0.5f,-0.2f,-0.5f);
			glVertex3f(0.5f,-0.2f,-0.5f);
			glVertex3f(0.5f,0.2f,-0.5f);
			glVertex3f(-0.5f,0.2f,-0.5f);

			//LEFT SIDE
			[b]glNormal3f(-1,0,0);[/b]
			glVertex3f(-0.5f,-0.2f,-0.5f);
			glVertex3f(-0.5f,-0.2f,0.0f);
			glVertex3f(-0.5f,0.2f,0.0f);
			glVertex3f(-0.5f,0.2f,-0.5f);
	glEnd();
	glPopMatrix();
	glutSwapBuffers();
 

 }

[...]

You may want to look at : http://www.falloutsoftware.com/tutorials/gl/gl8.htm.

Also, even if you make these changes, the lighting won't look 'great', because in the default fixed-function pipeline, lighting is calculated only at vertices and interpolated across the surfaces. (See: http://en.wikipedia.org/wiki/Gouraud_shading, for an idea of what I mean). You can solve this problem as demonstrated on that page, i.e. by densely tesselating polygons, or you can try out fragment shaders (although that's a whole new can of worms.)

0

thanks matt. Seems like you're the only one around here that knows about openGL. Thank you very much. The normal function helped , fixed the axies calculation. But in a tutorial i seen a normal for each vertex to better the effects. Can you explain how to set normal for each vertex. I mean the cordinates for each face of the box.
ex( glNormal3f(0.0f,0.0f,1.0f); //is for the front. but what about each glNormal for each vertex. what would be glNormal parameter, and how would I know what parameter to set?

0

Well, when you call glNormal(x,y,z), the current normal is set to xyz. Any subsequent call to glVertex uses the current normal. So:

glNormal3f(0,0,1);
glVertex3f(-0.5f,-0.2f,0.0f);
glVertex3f(0.5f,-0.2f,0.0f);
glVertex3f(0.5f,0.2f,0.0f);
glVertex3f(-0.5f,0.2f,0.0f);

is equivalent to:

glNormal3f(0,0,1);
glVertex3f(-0.5f,-0.2f,0.0f);
glNormal3f(0,0,1);
glVertex3f(0.5f,-0.2f,0.0f);
glNormal3f(0,0,1);
glVertex3f(0.5f,0.2f,0.0f);
glNormal3f(0,0,1);
glVertex3f(-0.5f,0.2f,0.0f);

With regards to what to set the normal to, it depends on the type of edge your trying to represent. For hard edges, you set the normals to the plane vectors of the polygons being drawn. For soft edges, you can set the normals to the (normalized) average of the plane vectors of any polygon that 'uses' the vertex. An alternative is to set the normal to the normalized position of the point in object space... this works for 'almost' spherical objects..

But basically, for correct lighting, the normals should point 'outwards' from the object. How you define 'outwards' mostly affects how the edges appear.

The normals I used before should be correct (they are 'hard' normals): if you change them to be 'soft', you'll lose the sharp appearance of the edges of the box. You can try another normal generation strategy, but the best way to get good shading of large, flat surfaces is always gonna be to tesselate them more densely (or use a fragment shader).

Here is code for the second method I suggested ( using normalized position as the normal ). This only works correctly in object space BTW, and only when the object is roughly centered about 0,0,0 in object space.

/* need this for sqrt, if using C rather than C++, #include <math.h> instead, obviously */
#include <cmath>

/* utility function to save a few lines of the same thing */
void glVertex3fSoftNormal ( float x, float y, float z )
{
  const float len = sqrt ( ( x * x ) + ( y * y ) + ( z * z ) );
  glNormal3f ( x / len, y / len, z / len );
  glVertex3f ( x, y, z );
}


 void disp(void)
 {
	 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
	 glMatrixMode(GL_MODELVIEW);
	 glLoadIdentity();
glShadeModel(GL_SMOOTH);
glPushMatrix();
	glTranslatef(0.0f,0.0f,-2.0f);

	GLfloat amb[] = {0.2f,0.2f,0.2f,1.0f};
	glLightModelfv(GL_LIGHT_MODEL_AMBIENT,amb);

	GLfloat dif[] = {0.5f,0.5f,0.0f,1.0f};
	GLfloat difPos[] = {-5.0f,1.5f,8.0f,1.0f};
	glLightfv(GL_LIGHT0,GL_DIFFUSE,dif);
	glLightfv(GL_LIGHT0,GL_POSITION,difPos);

	GLfloat dirColor[] = {0.5f,0.2f,0.0f,1.0f};
	GLfloat dirPos[] = {1.0f,0.4f,8.0f,0.0f};
	glLightfv(GL_LIGHT1,GL_DIFFUSE,dirColor);
	glLightfv(GL_LIGHT1,GL_POSITION,dirPos);

	GLfloat spec[] ={0.5f,0.5f,0.5f,1.0f};
	GLfloat position[] = {1.0f,0.5f,0.0f,0.0f};
	glLightfv(GL_LIGHT2,GL_SPECULAR,spec);
	glLightfv(GL_LIGHT2,GL_POSITION,position);
	//glLightfv(GL_LIGHT0,GL_AMBIENT,amb);
	

	glColor3f(1.0f,1.0f,0.0f);
	//GLfloat mColor[] = {0.0f,1.0f,0.0f,1.0f};
	//glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,mColor);
	
	glRotatef(Yrot,0.0f,1.0f,0.0f);
	glBegin(GL_QUADS);
		
			//FRONT
			glVertex3fSoftNormal(-0.5f,-0.2f,0.0f);
			glVertex3fSoftNormal(0.5f,-0.2f,0.0f);
			glVertex3fSoftNormal(0.5f,0.2f,0.0f);
			glVertex3fSoftNormal(-0.5f,0.2f,0.0f);
			
			//RIGHT SIDE
			glVertex3fSoftNormal(0.5f,-0.2f,0.0f);
			glVertex3fSoftNormal(0.5f,-0.2f,-0.5f);
			glVertex3fSoftNormal(0.5f,0.2f,-0.5f);
			glVertex3fSoftNormal(0.5f,0.2f,0.0f);
			
			//BACK SIDE
			glVertex3fSoftNormal(-0.5f,-0.2f,-0.5f);
			glVertex3fSoftNormal(0.5f,-0.2f,-0.5f);
			glVertex3fSoftNormal(0.5f,0.2f,-0.5f);
			glVertex3fSoftNormal(-0.5f,0.2f,-0.5f);

			//LEFT SIDE
			glVertex3fSoftNormal(-0.5f,-0.2f,-0.5f);
			glVertex3fSoftNormal(-0.5f,-0.2f,0.0f);
			glVertex3fSoftNormal(-0.5f,0.2f,0.0f);
			glVertex3fSoftNormal(-0.5f,0.2f,-0.5f);
	glEnd();
glPopMatrix();
	glutSwapBuffers();
 }
This topic has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.