Sign in to follow this  
Sergio Oigres

problem with light on selfcreated objects

Recommended Posts

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

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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 v

foreach vertex v
normalize normal of v

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this