Lighting problem

Hi people, I was just wondering how to draw a lit polygon correctly. I draw a plate in clockwise orientation and doing this I’m telling Opengl that the face I’m looking is back. This way is right because my “sun” is in the other side of the plate and all light goes well. But, if I rotate the plate, the back side should be lit, but because it is the backside, even in front of the “sun” it is not enlightened. In addition, the side that doesn’t face the sun, the front one, is enlightened.

My question is, what is the secret to do Opengl control this automatically, or, how can I draw a polygon in such a manner that the lighting can lit the faces correctly? In real life it doesn’t matter what side is the front or back one, what matter is that if a side faces light, it will be enlightened. How to do it?

Lighting is governed by normals, do you supply them for your polygon? (glNormal3f)

Can you put some screen shot of your plate with normals visible? For my part, it is clearly not understandable.

All normals should point out of the objet if you want that its surface is correctly lit.

I supply the normals. But I can’t see at where it points. All I did was:



GLfloat v1[] = {0,0,0};
GLfloat v2[] = {3,0,0};
GLfloat v3[] = {3,3,0};
GLfloat v4[] = {0,3,0};

glBegin(GL_POLYGON);

//counterclockwise

glNormal3f(v1);
glVertex3f(v1);

glNormal3f(v2);
glVertex3f(v2);

glNormal3f(v3);
glVertex3f(v3);

glNormal3f(v4);
glVertex3f(v4);

glEnd();


Obs: it is in a display list.

The light source is at (0,30,-100) and the cam is at (0,0,5). In that way it is correct. But, if I rotate the object 180 degrees, the other side, the one who was hidden from the light, now faces the light, right? But, instead of being lit, it stays unlit.

GLfloat v1[] = {0,0,0};
glNormal3f(v1);
glVertex3f(v1);
See this? Normal is vector with length of 1.0, not zero, not 3. Supply proper normals (0, 0, 1).

Your quad is in the XY plane so normals should be by definition orthogonal to this plane and point in the Z or -Z direction in your case.

hm… the normal should be defined in a point different from the vertex? I though the function glnormal calculates automatically this. So, in my example above, what is the correct normal coordinates I should pass?

and if a point doesn’t lie only in XY plane, but in the Z too?

thanks

I think you need to read about 3D rendering basics. Without wanting to be offensive, you are trying to draw some 3D stuff without knowing what you really do.

A normal is a vector orthogonal to a polygon and be should normalized for lighting computation. So if you had read the glNormal spec, you would have seen that you need to supply a normal vector which is independant of vertices position.

No, I know about 3d basics, I just don’t know how the function glnormal actually works. I know what is a normal vector, I know how to find it manually (cross product betwenn 2 vectors in a plane). Please, correct my example above, giving me the proper coordinates to normal in that case so I can figure out by myself how I have to proceed with glnormal.

By the way, I normalize automatically all vertices by enabling GL_NORMALIZE.

Yes you can normalize normals with glEnable(GL_NORMALIZE) but that does not work for normals with a length equal to zero.

glNormal is very easy to use, you have 3 parameters that are the normal coordinates. In you example, normals are all eaqual to (0,0,1).
So you set normals for each vertex like this:

glNormal3f(0,0,1);

this is what you would have found calculating the cross product… as you said.

http://www.opengl.org/sdk/docs/man/xhtml/glNormal.xml

By the way, your glNormal3f and glVertex3f calls are wrong, you should call glNormal3fv and glVertex3fv since you set parameters as arrays.

thanks for the patience dletozeun, now I got it. I’m doing all wrong.

btw,i typed wrong, yes it is *3fv.

one more question, after I set a normal vector for a plane, I have to set the opposite normal in order to have a normal vector for each side? Or does glnormal(*) do that by itself?

glNormal just set the normal, nothing more. I don’t know if OpenGL gives a way to enable double sided lighting, but this is a thing that you could do nicely in a vertex shader.

Well, I have checked it, and here it is, you can enable 2-sided lighting with this:

glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);

1 for 2-sided lighting, 0 for front lighting only.

More information here.

It worked! Thanks a lot guys!! you are fantastics!