problem with light on selfcreated objects

Started by
6 comments, last by Kalidor 17 years, 6 months ago
Hi, for accessing each plane-coordinates while texturing I've written my own routines that create objects like disk, cylinders and spheres. after that, I've to realize that all lights (standard, spot, a.s.o) doesn't positioned like in normal cases. here the light seems to come from bottom of space. I tried to modify the position, but it's always the same. If I exchange the object with an auxSolidSphere for instance the same light lights correctly. and now I ask me why. all the planes of my objects are calculated from the same point and use the normal-vector glNormal3f(0.0, 0.0, 0.0) at start-up. But the problem have to be here, right? The code for drawing planes: GLvoid drawPlanes(struct object *obj) { int n; glNormal3f(0.0, 0.0, 0.0); glBegin(GL_QUAD_STRIP); for(n=0; n<obj->nPlanes; n++) { glVertex3f(obj->plane[n].x1, obj->plane[n].y1, obj->plane[n].z1); glVertex3f(obj->plane[n].x2, obj->plane[n].y2, obj->plane[n].z2); glVertex3f(obj->plane[n].x3, obj->plane[n].y3, obj->plane[n].z3); glVertex3f(obj->plane[n].x4, obj->plane[n].y4, obj->plane[n].z4); } glEnd(); } Can someone helps? Sergio
Advertisement
you're not specifying any normals for your planes. Each vertex should have a corresponding normal if you want correct lighting.
Okay, that makes sense! Unfortunatly I only know the calculation of normals for triangles:

Nx=(y2-y1)*(z3-z1)-(y3-y1)*(z2-z1);
Ny=(z2-z1)*(x3-x1)-(z3-z1)*(x2-x1);
Nz=(x2-x1)*(x3-x1)-(x3-x1)*(y2-y1);

Perhaps do you know the calcutation of normals for quads?
Sergio
I am no expert, but wouldn't a triangle and a quad facing the same way have the same normal?

In other words:
a-----b  p---q|     |  |  /|     |  | /|     |  |/c-----d  r

If a = p, b = q and c = r, wouldn't they have the same normal? Then all there's left is to take the right three values and calculate the normal for half of the quad.

I'm not too certain... maybe somebody can say if it's right or wrong?
In case you were wondering what to put in your next christian game; don't ask me, because I'm an atheist, an infidel, and all in all an antitheist. If that doesn't bother you, visit my site that has all kinds of small utilities and widgets.
you don't really need to calculate the normals, you can just specify them using glNormal3f(). Now if you were doing more complex geometry then a simple plane you would want to either calculate them or ideally have them loaded in with the mesh. But for this you should just be able to do the following

[source lang = "cpp"]glBegin(GL_QUAD_STRIP);for(n=0; n<obj->nPlanes; n++){glNormal3f(0.0f, 1.0f, 0.0f);glVertex3f(obj->plane[n].x1, obj->plane[n].y1, obj->plane[n].z1);glNormal3f(0.0f, 1.0f, 0.0f);glVertex3f(obj->plane[n].x2, obj->plane[n].y2, obj->plane[n].z2);glNormal3f(0.0f, 1.0f, 0.0f);glVertex3f(obj->plane[n].x3, obj->plane[n].y3, obj->plane[n].z3);glNormal3f(0.0f, 1.0f, 0.0f);glVertex3f(obj->plane[n].x4, obj->plane[n].y4, obj->plane[n].z4);}glEnd();}


or something similar. That won't work exactly because it's saying every plane has a normal pointing in the same direction as the positive y-axis. You'll obviously want to base this on the orientation of the specific quad.
to Joakim_ar's answer:
that's the way I thought too. I'll try this next...
(but it would be nice if someone could spent this code!)

to Morpheus001's answer:
that's what I tried first of course, but it can't work because
normals always point to the same direction (as you said by yourself) ;)
(add: remember. opengl is a state machine. In that case putting glNormal3f()
before glBegin() has the same effect like putting glNormal3f()
before each vertex...)

[Edited by - Sergio Oigres on September 29, 2006 8:43:49 AM]
hi guys,
I've found the solution! calculating of normals is described
in opengl-bible "the redbook" and is easier as I thought:

1st you need to know the length of each point's vector:

len=sqrt((x*x)+(y*y)+(z*z));

than you can calc the normal-vector for each point:

nx=x/len;
ny=y/len;
nz=z/len;

that's all!
Sergio
That doesn't calculate a normal vector as in a "vector perpendicular to a surface." It calculates the unit vector (also called a normalized vector) with the same direction as the original non-zero vector. This calculation is commonly called normalization because it divides the vector by it's (L2) norm.

As Joakim_ar said, the normal of a triangle is the same as the normal of a quad (or any polygon) that is in the same plane. You can calculate this by taking the cross product of any two vectors in that plane. So again using Joakim_ar's example, the cross product of vectors (c-a) and (b-a) is the same as the cross product of (r-p) and (q-p). And keep in mind the right-hand rule... UxV = -(VxU).

After you find the normals of all the faces of your object, you can then calculate smooth normals for each vertex by adding up the normals for each face a vertex is part of and then normalizing it. In pseudocode the proper way to do this is something like this...
initialize all vertex normals to (0,0,0)foreach face f   foreach vertex v in f      add normal of f to normal of vforeach vertex v    normalize normal of v

This topic is closed to new replies.

Advertisement