Calcuation of normals

I need to calculate the normals.
In my application i have an array of x,y,z i.e x[42],y[42],z[42,42]
I am displaying 3D block using glBegin(GL_TRIANGLE).
So since i have to draw 3D i have to draw 12 triangles in all(in a loop).
Is there any better way to do it secondly how should i calculate normal ,i know one formula [v1-v2]x[v2-v3] were v1 etc are vertices of triangle
Is there ,any other better way

Thanks
aus

AFAIK there is only one way to caculate the normal of a polygon…

A better primitive type to use is GL_TRIANGLE_FAN or GL_TRIANGLE_STRIP, or even GL_QUAD_STRIP, check those three types out. What you have for the formula to find the normal of a poly on the plane is correct. I usually use <v2-v1>x<v3-v1> but yours works also. The way i do it there just creates two vectors that start at the same place, its no big deal really. But remember this normal is the normal to the plane. If you want a vertex normal for smooth shading then for each vertex take an average of the normals of polys who share that vertex and let this averaged normal be the vertex normal. Its just an approximation but works good.

-SirKnight

Thanks for the reply,

Now I have set the normals to the surface using glNormalf();
and i have set lighting position to {0,0,1,1)

But still the object doesn’t look 3D
What could be the problem

Any susggestions

Attaching part of my code…

void
reshape(int width, int height)
{
GLfloat light_pos[] = { 0, 0, 1, 1 };

glViewport(-300, -300, width, height);
glMatrixMode(GL_PROJECTION);

glLoadIdentity();

glOrtho(-2,2,-5,5,-2,2);

 glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

GLfloat light_ambient[] = {0.0, 0.0, 0.0, 1.0};
GLfloat light_diffuse[] = {0.7, 0.7, 0.7, 1.0};
GLfloat light_specular[] = {1.0, 1.0, 1.0, 1.0};

glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_POSITION, light_pos);

glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 1.0);
glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.0);
glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.0);

 glEnable(GL_LIGHT0);
glLoadIdentity();
glShadeModel(GL_SMOOTH);
gluPerspective(30,(GLfloat)width/height,150,250);

gluLookAt(30,-30,250,21,-50,21,0,1,0);

}

void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0f,0.0f,1.0f);

glBegin (GL_QUADS);
glVertex3f(0,100,0);
glVertex3f(100,100,0);
glVertex3f(100,200,0);
glVertex3f(0,200,0);

glBegin (GL_TRIANGLES);

for(int si=1;si<=41;si++)
{
for(int sj=1;sj<=41;sj++)
{

glColor3f (0.0f, 1.0f, 1.0f);

glNormal3f(0,0,1);
glVertex3f(xw[si],0,- yw[sj]);
glVertex3f(xw[si+1],0, -yw[sj]);
glVertex3f(xw[si+1],zw[si+1][sj],- yw[sj]);

glNormal3f(0,0,1);
glVertex3f(xw[si+1],zw[si+1][sj], -yw[sj]);
glVertex3f(xw[si],zw[si][sj], -yw[sj]);
glVertex3f(xw[si],0, -yw[sj]);

glColor3f (0.0f, 1.0f, 1.0f);
glNormal3f(-1,0,0);
glVertex3f(xw[si],0, -yw[sj]);
glVertex3f(xw[si],zw[si][sj], -yw[sj]);
glVertex3f(xw[si],zw[si][sj+1], -yw[sj+1]);

glNormal3f(-1,0,0);
glVertex3f(xw[si],0, -yw[sj]);
glVertex3f(xw[si],zw[si][sj+1], -yw[sj+1]);
glVertex3f(xw[si],0, -yw[sj+1]);

/calnormal(xw[si+1],zw[si+1][sj],yw[sj],xw[si],zw[si][sj],yw[sj],xw[si+1],zw[si+1][sj+1],yw[sj+1]);/

glColor3f (0.0f, 1.0f, 0.0f);
glNormal3f(0,1,0);
glVertex3f(xw[si+1],zw[si+1][sj], -yw[sj]);
glVertex3f(xw[si],zw[si][sj], -yw[sj]);
glVertex3f(xw[si+1],zw[si+1][sj+1], -yw[sj+1]);

glNormal3f(0,1,0);
/calnormal(xw[si+1],zw[si+1][sj+1], yw[sj+1],xw[si],zw[si][sj+1], yw[sj+1],xw[si],zw[si][sj], yw[sj]);/
glVertex3f(xw[si+1],zw[si+1][sj+1],- yw[sj+1]);
glVertex3f(xw[si],zw[si][sj+1], -yw[sj+1]);
glVertex3f(xw[si],zw[si][sj], -yw[sj]);

glColor3f (0.0f, 1.0f, 1.0f);
glNormal3f(-1,0,0);
glVertex3f(xw[si+1],0, -yw[sj]);
glVertex3f(xw[si+1],zw[si+1][sj], -yw[sj]);
glVertex3f(xw[si+1],zw[si+1][sj+1], -yw[sj+1]);

glNormal3f(-1,0,0);
glVertex3f(xw[si+1],zw[si+1][sj+1], -yw[sj+1]);
glVertex3f(xw[si+1],0, -yw[sj+1]);
glVertex3f(xw[si+1],0, -yw[sj]);

glColor3f (0.0f, 1.0f, 1.0f);
glNormal3f(0,0,1);
glVertex3f(xw[si+1],zw[si+1][sj+1], -yw[sj+1]);
glVertex3f(xw[si+1],0,- yw[sj+1]);
glVertex3f(xw[si],zw[si][sj+1], -yw[sj+1]);

glNormal3f(0,0,1);
glVertex3f(xw[si],zw[si][sj+1], -yw[sj+1]);
glVertex3f(xw[si+1],0, -yw[sj+1]);
glVertex3f(xw[si],0, -yw[sj+1]);

glColor3f (0.0f, 1.0f, 1.0f);
glNormal3f(0,0,1);
glVertex3f(xw[si],0, -yw[sj+1]);
glVertex3f(xw[si+1],0,- yw[sj+1]);
glVertex3f(xw[si],0, -yw[sj]);

glNormal3f(0,0,1);
glVertex3f(xw[si],0, -yw[sj]);
glVertex3f(xw[si+1],0, -yw[sj+1]);
glVertex3f(xw[si+1],0, -yw[sj]);

}

}

glEnd();

glFlush();

}

Thanks
aus

doesn’t look like you enable lighting
glEnable(GL_LIGHTING);

Thanks for you help.
Now it looks 3D but the color is grey
but actually it should be blue…why?

void
reshape(int width, int height)
{
GLfloat light_pos[] = { 0, 0, 1, 1 };

glViewport(-300, -300, width, height);
glMatrixMode(GL_PROJECTION);

glLoadIdentity();

glOrtho(-2,2,-5,5,-2,2);

 glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

GLfloat light_ambient[] = {1.0, 1.0, 1.0, 1.0};
GLfloat light_diffuse[] = {0.7, 0.7, 0.7, 1.0};
GLfloat light_specular[] = {1.0, 1.0, 1.0, 1.0};

glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_POSITION, light_pos);

glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 1.0);
glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.0);
glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.0);

 glEnable(GL_LIGHTING);
 glEnable(GL_LIGHT0);
glLoadIdentity();
glShadeModel(GL_SMOOTH);
gluPerspective(30,(GLfloat)width/height,150,250);

gluLookAt(30,-30,250,21,-50,21,0,1,0);

}

Thanks
aus

either use glEnable(GL_COLOR_MATERIAL);
or use glMaterial(…) instead of glColor3f()
you will have to look up the glMaterial details, but its much more powerful. If you just have a simple project GL_COLOR_MATERIAL will do just fine

I thought you had to be in projection mode to use gluPerspective().

Originally posted by aus79er:
[b] glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
GLfloat light_ambient = {1.0, 1.0, 1.0, 1.0};
GLfloat light_diffuse = {0.7, 0.7, 0.7, 1.0};
GLfloat light_specular = {1.0, 1.0, 1.0, 1.0};

glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_POSITION, light_pos);

glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 1.0);
glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.0);
glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.0);

glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLoadIdentity();
glShadeModel(GL_SMOOTH);
gluPerspective(30,(GLfloat)width/height,150,250);
[/b]

Also isn’t it unnecessary to call glOrtho() then gluPerspective()?

Thanks for the help.
I agree glOrtho is not required but I cannot still understand why the color of my object is black while i am setting it to green.
Am i making mistake somewhere…
Please help me

Thanks
aus

I noticed that your light position is {0, 0, 1, 1} which indicates a light positioned at (0, 0, 1). If this is too far from your objects they will be poorly lit. If you want a directional light use {0, 0, 1, 0}.

I tried the light position to {0, 0, 1, 0}
But still no change.The object still look black.
What can be the problem.

Thanks,
aus

did you try
glEnable(GL_COLOR_MATERIAL); ??

Thanks,
Yes I even tried
glEnable(GL_COLOR_MATERIAL);

any other suggestion
aus

I could be wrong, and this won’t solve your problem, but you have light ambient at
{1,1,1,1}
and diffuse at
{.7, .7, .7, .7}
but I belive that GL clamps light to 1.0, this means that the diffuse light will be over run by ambient
try
ambient {.5,.5,.5,1}
diffuse {1,1,1,1}

I tried your setting but it didn’t work.

Now i have identified the problem ,it has to do with light position if I comment out that part i.e enable lighting…then i can see the color i.e green etc.
But as soon as i enable lighting it appears black what could be the problem

Thanks in advance
Abhijit

I am not the expert here, but I noticed you are not using depth buffering. Without depth buffering it is possible that you may be drawing polygons facing away from the camera over polygons facing the camera. These polygons would show up black. Try enableing the depth buffer or specify GL_FRONT_AND_BACK in your glColorMaterial() call.

Just in case you didn’t do so, you’re supposed to use glColorMaterial() with glEnable(GL_COLOR_MATERIAL).

When you enable ambient and specular and so forth, you need to set an ambient light that will lit your scene though… You use glLighModel.

You will also see in my code a variabe light… That is simply an integer value, I use it to enable different lights. Say you want to work with light 4, you pass GL_LIGHT0+(4)

Below is a piece of a code from my engine…
It should have all you need to have lighting…

newLight.ambient_Light[0] = 0.4f;		// Red
newLight.ambient_Light[1] = 0.4f;		// Green
newLight.ambient_Light[2] = 0.4f;		// Blue
newLight.ambient_Light[3] = 0.0f;		// Alpha (translucency, transparency)

newLight.diffuse_Light[0] = 0.6f;		// Red
newLight.diffuse_Light[1] = 0.6f;		// Green
newLight.diffuse_Light[2] = 0.6f;		// Blue
newLight.diffuse_Light[3] = 1.0f;		// Alpha

newLight.specular_Light[0] = 0.9f;		// Red
newLight.specular_Light[1] = 0.9f;		// Green
newLight.specular_Light[2] = 0.9f;		// Blue
newLight.specular_Light[3] = 1.0f;		// Alpha

newLight.specular_Reflection[0] = 1.0f;		// Red
newLight.specular_Reflection[1] = 1.0f;		// Green
newLight.specular_Reflection[2] = 1.0f;		// Blue
newLight.specular_Reflection[3] = 1.0f;		// Alpha

newLight.light_Position[0] = -3.0f;		// X axis
newLight.light_Position[1] = 1.0f;		// Y axis
newLight.light_Position[2] = 2.0f;		// Z axis
newLight.light_Position[3] = 0.0f;		// This value indicates that the
										// light present at this location

newLight.light_Direction[0] = 0.0f;		// X axis
newLight.light_Direction[1] = 0.0f;		// Y axis
newLight.light_Direction[2] = 10.0f;	// Z axis

newLight.lightID = light;

glLightModelfv(GL_LIGHT_MODEL_AMBIENT, newLight.ambient_Light);

// Set-up and anble light
//
glLightfv(GL_LIGHT0 + light, GL_DIFFUSE, newLight.diffuse_Light);
glLightfv(GL_LIGHT0 + light, GL_SPECULAR, newLight.specular_Light);
glLightfv(GL_LIGHT0 + light, GL_POSITION, newLight.light_Position);

glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);

// All materials are set here to have full specular reflectivity //
glMaterialfv(GL_FRONT, GL_SPECULAR, newLight.specular_Reflection); 
glMateriali(GL_FRONT, GL_SHININESS, 100);		// This specifies how small or focused
												// the specular highlight is

I don’t think you need a global light, I have never used one, but try doing this:
if
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
makes it gray
and
glDisable(GL_LIGHT0);
glDisable(GL_LIGHTING);
leaves it green
set
glDisable(GL_LIGHT0);
glEnable(GL_LIGHTING);
and see if it stays gray or is green

glEnable(GL_LIGHTING);
leaves the object grey
while
glDisable(GL_LIGHTING);
leaves the object green

Thanks.
aus

ok it sounds like for some odd reason the material colors are not being set properly. I know I mentioned it before but try
GLfloat Color[4] = {0,1,0,1};
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, Color);