question about normals and shading

Hi. I have a project where I am given a .m file thats used to draw a person’s hand using several triangles. The file has the vertices of each triangle and the correct normals for each vertex as floats. How do I implement the normals correctly with the normal3f function? I saw an example where the vertices were added with thier normal and I’ve seen conflicting methods…

I have the lighting set up correctly and GL_SMOOTH and GL_NORMALIZE enabled.

It seems like the lighting is still jagged when I try to implement those normals. Does that happen when the normals are incorrectly entered or is that a problem with my lighting or smooth enabling?

Thanks for any help!

Will

Hmm. I think I might have found something. When I changed the corners of every triangle to RGB like this

http://openglut.sourceforge.net/redbook_smooth.png

but in the model the triangles do not blend well (they almost all look like the triangle in the link). Does that mean I need to do the averaging of every touching vertex thing? Would that make the model look less jagged?

The professor said all the normals are already correct. So I’m not sure what the problem is…

And apparently few people do, you have to be precise in the description of your problem and your code for other to be able to help.

Well here’s my drawing function in main. I think I have everything in place in main, but maybe something should be in the draw_model file. I’m pretty sure the normals are correct.

and a pic of the model right now with the rest of the arm. You can see the light reflection but theres no real shadow and the surface is still jagged.

http://s803.photobucket.com/albums/yy315…pg&newest=1

void appDrawScene ()
{

// Clear the rendering buffer:
glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

glEnable(GL_NORMALIZE);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);

glShadeModel(GL_SMOOTH);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

glColorMaterial ( GL_FRONT_AND_BACK, GL_EMISSION ) ;
glEnable ( GL_COLOR_MATERIAL ) ;

GLfloat diffuse0[]={1.0, 1.0, 1.0, 1.0};
GLfloat ambient0[]={0.0, 0.0, 0.0, 1.0};
GLfloat specular0[]={1.0, 1.0, 1.0, 1.0};
GLfloat light0_pos[]={-2, 2.0, 2.0, 1.0};
GLfloat mat_shine = 10.0f;

glLightfv(GL_LIGHT0, GL_POSITION, light0_pos);
glLightfv(GL_LIGHT0, GL_AMBIENT, ambient0);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse0);
glLightfv(GL_LIGHT0, GL_SPECULAR, specular0);

GLfloat mat_ambient[] = {0.11, 0.6, 0.11, 1.0};
GLfloat mat_diffuse[] = {0.43, 0.47, 0.54, 1.0};
GLfloat mat_specular[] = {0.33, .33, .52, 1.0};
GLfloat mat_emission[] = {0.0, 0.0, 0.0, 0.0};

// Set the viewing frustum for a coordinate range in [-10,10]^3
int w = glutGet ( GLUT_WINDOW_WIDTH );
int h = glutGet ( GLUT_WINDOW_HEIGHT );
double aspect = double(w)/double(h);
glMatrixMode ( GL_PROJECTION );
glLoadIdentity ();
gluPerspective ( App->fovy, aspect, 2/znear/, 100/zfar/ );
gluLookAt ( 0, 0, -20, // eye
0, 0, 0, // center
0, 1, 0 ); // up vector

// Clear the model transformation stack:
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();

// Rotate the scene for some simple visualization:
glRotated ( App->rotx, 1, 0, 0 );
glRotated ( App->roty, 0, 1, 0 );

// Draw:
if ( App->viewaxis ) draw_axis ( 40.0 );

glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialf(GL_FRONT, GL_SHININESS, mat_shine);
glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);

//draw model

Model *M = new Model();

M->load(“rhand.m”);
glPushMatrix();
glTranslated(-26, -9, 0);
if (App->viewtube){draw_model (*M, smooth, rotate );}
glPopMatrix();

glDisable(GL_LIGHTING);

// Show back buffer:
glFlush(); // flush the pipeline (usually not necessary)
glutSwapBuffers(); // we were drawing to the back buffer, now bring it to the front
}

Here’s my draw_model file. I’ve tested all of the normals and I’m getting the correct ones from my .m file. but maybe I’m implementing them incorrectly?

void draw_model ( const Model& m, bool smooth, double angle ){

glColor3ub(m.F[0].r, m.F[0].g, m.F[0].b);

int A = 0, B = 0, C = 0, An = 0, Bn = 0, Cn = 0; //Indices of the face vertices and arrays to hold the vertex normals

glRotated(-90, 0, 1, 0);
glRotated(angle, 0, 0, 1);
for(int i = 0; i < m.fsize; i++){
A = m.F[i].va;
B = m.F[i].vb;
C = m.F[i].vc;

An = m.F[i].na;
Bn = m.F[i].nb;
Cn = m.F[i].nc;

float Anorm[] = {m.N[An].x, m.N[An].y, m.N[An].z};
float Bnorm[] = {m.N[Bn].x, m.N[Bn].y, m.N[Bn].z};
float Cnorm[] = {m.N[Cn].x, m.N[Cn].y, m.N[Cn].z};

glBegin(GL_TRIANGLES);

glNormal3fv(Anorm);
glVertex3f(m.V[A].x, m.V[A].y, m.V[A].z);

glNormal3fv(Bnorm);
glVertex3f(m.V[b].x, m.V[b].y, m.V[b].z);

glNormal3fv(Cnorm);
glVertex3f(m.V[C].x, m.V[C].y, m.V[C].z);
glEnd();
}	

};

In fact there is nothing wrong with your lighting here :slight_smile:
Classic vertex lighting looks like this, and cast shadows have to be done explicitly because it is much more complex.

If you want per pixel lighing, you have to go with GLSL shaders :
http://www.lighthouse3d.com/opengl/glsl/index.php?dirlightpix