normals in opengl?

Oracle

New member
hey guys,

Im coding opengl and im trying to set up my lighting correctly but i cant sort out these normals and its getting annoying,

I thought i had the normals sorted but on further analysis and testing the normals dont work:(

Code:
GLuint adrian(float scale)
{
	vertex3 norm;

	vertex3 shape[] = { 
						{0.0f,3.0f,0.0f},// face 1
						{1.0f,0.0f,0.0f},
						{0.0f,0.0f,1.0f},

						{0.0f,3.0f,0.0f},// face 2
						{0.0f,0.0f,-2.0f},
						{-2.0f,0.0f,0.0f},

						{0.0f,0.0f,-2.0f},// face 3
						{1.0f,0.0f,0.0f},
						{0.0f,-1.0f,0.0f},

						{-2.0f,0.0f,0.0f},// face 4
						{0.0f,-1.0f,0.0f},
						{0.0f,0.0f,1.0f},

						{0.0f,0.0f,1.0f},// face 5
						{-2.0f,0.0f,0.0f},
						{0.0f,3.0f,0.0f},

						{1.0f,0.0f,0.0f},// face 6
						{0.0f,0.0f,-2.0f},
						{0.0f,3.0f,0.0f},

						{1.0f,0.0f,0.0f},// face 7
						{0.0f,0.0f,1.0f},
						{0.0f,-1.0f,.0f},

						{0.0f,0.0f,-2.0f},// face 8
						{-2.0f,0.0f,0.0f},
						{0.0f,-1.0f,0.0f},
	};

				struct material 
				{

				  float ambient[4];
				  float diffuse[4];
				  float specular[4];
				  float shininess[1];
	
				};


material sand =		{{0.2f, 0.2f, 0.2f, 1.0f},
					{0.92f, 0.72f, 0.21f, 1.0f},
					{0.05f, 0.05f, 0.05f, 1.0f},
					{1.0}}; 

	
	GLuint id = glGenLists(1);
	glNewList(id, GL_COMPILE);

	glMaterialfv(GL_FRONT, GL_AMBIENT, sand.ambient);
	glMaterialfv(GL_FRONT, GL_DIFFUSE, sand.diffuse);
	glMaterialfv(GL_FRONT, GL_SPECULAR, sand.specular);
	glMaterialfv(GL_FRONT, GL_SHININESS, sand.shininess);
		
//face 1
	
		glBegin(GL_TRIANGLES);
					norm = CalculateCrossProduct(shape[1], shape[1], shape[3]);
					glNormal3f(norm.x, norm.y, norm.z);
					glVertex3f(shape[0].x, shape[3].y, shape[0].z);
					glVertex3f(shape[1].x, shape[0].y, shape[0].z);
					glVertex3f(shape[0].x, shape[0].y, shape[1].z);
		glEnd();

//face 2
		glBegin(GL_TRIANGLES);
					norm = CalculateCrossProduct(shape[3], shape[-2], shape[-2]);
					glNormal3f(norm.x, norm.y, norm.z);
					glVertex3f(shape[0].x, shape[3].y, shape[0].z);
					glVertex3f(shape[0].x, shape[0].y, shape[-2].z);
					glVertex3f(shape[-2].x, shape[0].y, shape[0].z);
		glEnd();
		
//face 3
		glBegin(GL_TRIANGLES);
					norm = CalculateCrossProduct(shape[-2], shape[1], shape[-1]);
					glNormal3f(norm.x, norm.y, norm.z);
					glVertex3f(shape[0].x, shape[0].y, shape[-2].z);
					glVertex3f(shape[1].x, shape[0].y, shape[0].z);
					glVertex3f(shape[0].x, shape[-1].y, shape[0].z);
		glEnd();
		
//face 4
		glBegin(GL_TRIANGLES);			
					norm = CalculateCrossProduct(shape[-2], shape[-1], shape[1]);
					glNormal3f(norm.x, norm.y, norm.z);
					glVertex3f(shape[-2].x, shape[0].y, shape[0].z);
					glVertex3f(shape[0].x, shape[-1].y, shape[0].z);
					glVertex3f(shape[0].x, shape[0].y, shape[1].z);
glEnd();			

//face 5
		glBegin(GL_TRIANGLES);			
					norm = CalculateCrossProduct(shape[1], shape[-2], shape[3]);
					glNormal3f(norm.x, norm.y, norm.z);
					glVertex3f(shape[0].x, shape[0].y, shape[1].z);
					glVertex3f(shape[-2].x, shape[0].y, shape[0].z);
					glVertex3f(shape[0].x, shape[3].y, shape[0].z);
		glEnd();

//face 6
		glBegin(GL_TRIANGLES);
					norm = CalculateCrossProduct(shape[1], shape[3], shape[-2]);
					glNormal3f(norm.x, norm.y, norm.z);
					glVertex3f(shape[1].x, shape[0].y, shape[0].z);
					glVertex3f(shape[0].x, shape[0].y, shape[-2].z);
					glVertex3f(shape[0].x, shape[3].y, shape[0].z);
		glEnd();
	
//face 7
		glBegin(GL_TRIANGLES);
					norm = CalculateCrossProduct(shape[1], shape[-1], shape[1]);
					glNormal3f(norm.x, norm.y, norm.z);
					glVertex3f(shape[1].x, shape[0].y, shape[0].z);
					glVertex3f(shape[0].x, shape[0].y, shape[1].z);
					glVertex3f(shape[0].x, shape[-1].y, shape[0].z);
		glEnd();

//face 8
		glBegin(GL_TRIANGLES);
					norm = CalculateCrossProduct(shape[-2], shape[-2], shape[-1]);
					glNormal3f(norm.x, norm.y, norm.z);
					glVertex3f(shape[0].x, shape[0].y, shape[-2].z);
					glVertex3f(shape[-2].x, shape[0].y, shape[0].z);
					glVertex3f(shape[0].x, shape[-1].y, shape[0].z);
		glEnd();
		
			
			

	glEndList();

	return id;
}

thats my display list is there anything glaringly wrong with it?

:confused: oracle
 
Try normalizing the cross product before assigning it to normal. That's why it's called a normal :D

Also make sure the winding is the same for all triangles, otherwise some normals will be flipped backwards (baaaad).
 
winding?:confused:

and what do you mean normalising the cross product?

im relativly new to opengl so go slow:)
 
normalize is just math ;)

... a normal is by definition a vector of unit length, ie length=1. The length of a 3d vector is (in plain c)
Code:
length=sqrt(x*x+y*y+z*z);
Now, normalizing means rescaling the vector to unit length.
Code:
scale=1.0/length;
x*=scale;
y*=scale;
z*=scale;
I kind of assumed you knew this, because you already have that crossproduct thingy.

Anyways, that's what you should do to your crossproducts. Note that if you're dealing with degenerate triangles, the length of the crossproduct might be zero (or close enough) and you will get division expections.

So we need a better version:
Code:
//normalize the vector given by x, y, z
float length=sqrt(x*x+y*y+z*z);
if (length>0.01f)
{
   float scale=1.0f/length;
   x*=scale;
   y*=scale;
   z*=scale;
}

Part #2
"Winding"
*drumroll*

Your triangles are either 'wound' clockwise or counterclockwise. Or rather they are both, depending on your point of view. You generally want one side to be the 'outside' of model, so you choose a common winding and keep it throughout a model. Backface culling only works properly this way.

To actually specify a winding you use the order of vertices.

Let's imagine we have three vertices on screen, bottom left (A), bottom right (B) and center of screen (C).

GL's default front face is counterclockwise ( glFrontFace(GL_CCW); ). If we render with backface culling enabled and specify vertices A-C-B we get ... nothing. Because we specified the vertices clockwise, we 'look' onto the backface of the triangle and it gets culled. To actually see anything, we specify the triangle as A-B-C.

Or we rotate the triangle via modelview matrix until its screenspace winding is ccw. The purpose of this excercise is to save raster workload on parts of a model that face 'away' from the viewer. The downside is that your models can't have any holes in them. Imagine a bucket. The surface triangles can't serve double as inside and outside faces, so when you look into the bucket from the top, it'll become invisible.

(sorry, kind of hard to explain that)

Now I hear you asking "How does this apply to my normals?"
Answer: the same thing actually applies to crossproducts. In fact, crossproducts are the way backface culling is controlled internally. So to have a consistent model, make sure
1)every triangle face is 'wound' the same way
2)use the same order you use for your glVertex* calls in your crossproduct calculation. Hmmpf. I'll try:
Wrong
normal=normalize(crossproduct(a,b,c));
glNormalfv(normal);
glVertex3fv(&a);
glVertex3fv(&b);
glVertex3fv(&c);

normal=normalize(crossproduct(d,e,f));
glNormalfv(normal);
glVertex3fv(&d);
glVertex3fv(&f); //whoops! we use a different vertex order now ...
glVertex3fv(&e);

Right
normal=normalize(crossproduct(a,b,c));
glNormalfv(normal);
glVertex3fv(&a);
glVertex3fv(&b);
glVertex3fv(&c);

normal=normalize(crossproduct(d,e,f));
glNormalfv(normal);
glVertex3fv(&d);
glVertex3fv(&e); //aaah ... same order as above :-)
glVertex3fv(&f);
 
i think my programs buggered tbh, i think ill need to talk to my lecturer as i cant really understand what im doing wrong and the code you posted is a but confusing.

thanks anyway man:)
 
right....

normals i understand what there about, i get the make sure u specify them otherwise they wont show up etc but i wonder why the rest of my object isnt showing up?
 
right....

normals i understand what there about, i get the make sure u specify them otherwise they wont show up etc but i wonder why the rest of my object isnt showing up?

hmm its almost like the display list is only reading the first set of vertex data

ill post later on when ive tested some more
 
by the way im not posting all of my code just the stuff in the display list if you want all of it just ask
 
I think im getting opengl:)

latest update, got my normals completely wrong,but they now work, got 2 lights in my program, user controls, lighting on/off button and texture mapping:)
 
Back
Top