PDA

View Full Version : Calcuation of normals

aus79er
04-02-2002, 10:16 AM
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

Norling
04-02-2002, 10:21 AM
AFAIK there is only one way to caculate the normal of a polygon...

SirKnight
04-02-2002, 10:30 AM
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

aus79er
04-02-2002, 04:55 PM

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);

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

glMatrixMode(GL_MODELVIEW);
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);

glEnable(GL_LIGHT0);
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);

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

chowe6685
04-02-2002, 05:02 PM
doesn't look like you enable lighting
glEnable(GL_LIGHTING);

aus79er
04-02-2002, 05:15 PM
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);

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

glMatrixMode(GL_MODELVIEW);
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);

glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
gluPerspective(30,(GLfloat)width/height,150,250);
gluLookAt(30,-30,250,21,-50,21,0,1,0);

}

Thanks
aus

chowe6685
04-02-2002, 05:28 PM
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

Furrage
04-03-2002, 12:50 PM
I thought you had to be in projection mode to use gluPerspective().

Originally posted by aus79er:
glMatrixMode(GL_MODELVIEW);
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);

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

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

aus79er
04-03-2002, 01:20 PM
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...

Thanks
aus

Furrage
04-03-2002, 01:36 PM
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}.

aus79er
04-03-2002, 02:23 PM
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

chowe6685
04-03-2002, 05:00 PM
did you try
glEnable(GL_COLOR_MATERIAL); ??

aus79er
04-03-2002, 05:36 PM
Thanks,
Yes I even tried
glEnable(GL_COLOR_MATERIAL);

any other suggestion
aus

chowe6685
04-03-2002, 05:58 PM
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}

aus79er
04-03-2002, 07:42 PM
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

Abhijit

Furrage
04-04-2002, 05:12 AM
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).

Miguel_dup1
04-04-2002, 06:26 AM
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

chowe6685
04-04-2002, 05:21 PM
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

aus79er
04-05-2002, 09:03 AM
glEnable(GL_LIGHTING);
leaves the object grey
while
glDisable(GL_LIGHTING);
leaves the object green

Thanks.
aus

chowe6685
04-05-2002, 10:05 AM
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);

aus79er
04-05-2002, 01:34 PM
Thanks chowe6685
Can you explain me what it exactly meant.
And why it worked

Thanks
aus

chowe6685
04-06-2002, 01:46 PM
glad you finally solved the problem.
when using lighting gl combines the light color and the material color. glMaterial sets the material properties, GL_FRONT_AND_BACK specifies which faces to apply the settings to

GL_AMBIENT_AND_DIFFUSE specifies which propery of the material we are changing

the last value is what color you are changing to
someone might have a better explanation than me, or you could check the red book, but in general whenever you use lighting you need either glMaterial or GL_COLOR_MATERIAL, the latter is easier, but didn't work in your situation and glMaterial is a more flexible command

hope that helps