Advertisement

Calculating Normals, Dot product etc

Started by March 15, 2001 05:36 PM
14 comments, last by Clouds3000 23 years, 8 months ago
I believe GL_CULL_FACE culls polygons based one their winding. This means if you specified the triangle in clockwise order it is a back face, if you specify it in counter-clockwise order then it is a front face. Look into the glFrontFace function for more info.

Jason A.

---
I write code.
DelphiGL (http://delphigl.cfxweb.net)
---I write code.DelphiGL (http://delphigl.cfxweb.net)
Well if when you have GL_CULL_FACE enabled they dont show, and disabled they do show, then is has to be the winding of the polygons are not correct.

-SirKnight
Advertisement
I know, this is what I mean. If the winding is correct (counter-clockwise in my case) the 4 walls have lighting but the roof and floor do not. But if I screw up the winding on the floor/roof and disable CULL_FACE then the floor/roof are affected by lighting. So the lighting only works on these 2 horizontal surfaces if the winding on them is screwed up.
ps-It is the vertex coordinates I''m meant to be plugging into the cross product ain''t it?
Thanks
quote: Original post by Clouds3000

ps-It is the vertex coordinates I''m meant to be plugging into the cross product ain''t it?
Thanks


You should be crossing two edges of your polygon. The cross product gives you a perpendicular vector. So if you cross two vectors that are on the surface of your polygon, you get a perpendicular vector to the polygon.

Say you have a triangle with 3 vertices, v0,v1, and v2
Assuming you have a CCW winding, you want to cross
(v2-v1) X (v0-v1)


OK...some corrections here......i read in some posts here that you get your normals by doing the following Vector calculations:
V1 X V2

You don''t get normals out of that calculation, you get a cross product.....a normal isn''t a cross product, a Normal is a Normalized cross product....that means a that the normal vector has the same direction as the cross product but it is of unit length (length = 1)
Now, with OGL you can use crossproducts as normals but you should call:
glEnable(GL_NORMALIZE);

If you forget to do this, then your lighting gets screwed.

To speed things up you can precalculate your normals by dividing X,Y and Z values of the Crossproduct Through the length of your cross product.

Now you have made you crossproduct unit length and thus you can call it a Normal.

Now that you have your normals you can render your scene without:
glEnable(GL_NORMALIZE);
and thus speeding up your render proces


OK...that was the teacher inside of me

Some code from a .3DS model loader i am coding, i use it to calculate the face Normals after i loaded the Model into memory,
it''s still unoptimized and untested, but i am pretty sure that it will work: ( hope this code doesn''t get too screwed in the post)

void CModel::CalculateNormals()
{
// first we calculate the face normals of all the faces of all the objects
Object *pObjectPointer = m_plstObjects;
Vector CrossProduct, VectorA, VectorB;
float CrossProductLength;

while (pObjectPointer != NULL)
{
for (int i = 0; i < pObjectPointer->shNumFaces; i++)
{
// first calculate the face edge Vectors which will be used to determine the CrossProduct
VectorA.x = pObjectPointer->parFaces.Corner3->x - pObjectPointer->parFaces.Corner2->x;<br> VectorA.y = pObjectPointer->parFaces.Corner3->y - pObjectPointer->parFaces.Corner2->y;<br> VectorA.y = pObjectPointer->parFaces.Corner3->z - pObjectPointer->parFaces.Corner2->z;<br><br> VectorA.y = pObjectPointer->parFaces.Corner1->x - pObjectPointer->parFaces.Corner2->x;<br> VectorA.y = pObjectPointer->parFaces.Corner1->y - pObjectPointer->parFaces.Corner2->y;<br> VectorA.y = pObjectPointer->parFaces.Corner1->z - pObjectPointer->parFaces.Corner2->z;<br><br> // calculate the crossproduct<br> CrossProduct.x = VectorA.y * VectorB.z - VectorA.z * VectorB.y;<br> CrossProduct.y = VectorA.z * VectorB.x - VectorA.x * VectorB.z;<br> CrossProduct.z = VectorA.x * VectorB.y - VectorA.y * VectorB.x;<br><br> //normalize the Crossproduct and save it to the correct FaceNormal<br> CrossProductLength = (float)sqrt((CrossProduct.x * CrossProduct.x) + (CrossProduct.y * CrossProduct.y) + (CrossProduct.z * CrossProduct.z));<br><br> pObjectPointer->parFaces.FaceNormal.x = CrossProduct.x / CrossProductLength;<br> pObjectPointer->parFaces.FaceNormal.y = CrossProduct.y / CrossProductLength;<br> pObjectPointer->parFaces.FaceNormal.z = CrossProduct.z / CrossProductLength;<br> }<br> pObjectPointer = pObjectPointer->pNextObject;<br> }<br>}<br><br> </i>
Thanks for all your help guys, this is what I did.
I threw away my little level made of quads, cause no matter what I did, some of the faces wouldn't light up. I changed my program alittle bit to load in triangles instead of quads and used the level data from Lesson10 so I wouldn't have to takes ages typing out the data. And.........IT WORKED. As far as I can see its working, I presume there must have been some crap-up using the quads when calculating the Cross-product.
One more thing though, I move around my level using Lesson10 code, so I rotate the polygons around me instead of moving the camera. But I want a main light in the room (which works) and a light that follows me around but I wasn't sure how to do this cause if I specified the coordinates of 'my' light to be (0,0,0) ie-where I am, it will get rotated like all the others points. The light that follows me is yellow, though even when I turn it on the room is white (mixture of the original blue light and the yellow light ??????), but if I stick a glLoadIdentity in front of the light position that follows me like so.....
glLoadIdentity();
(glLightfv(GL_LIGHT2, GL_POSITION,LightPosition2);
then if I duck down the ceiling goes a darker yellow color and the floor dark blue. I understand the floor goin' blue cause if I am too close to it I am 'on top' of its normal but the ceiling going yellow? I don't understand.
Sorry for being such a slow learner with this dam lighting thing
Cheers again.

Edited by - Clouds3000 on March 22, 2001 5:25:32 PM

This topic is closed to new replies.

Advertisement