PDA

View Full Version : Averaging normals



efesar
04-11-2000, 02:38 PM
I simply cannot get normal averaging to work. I was under the impression that normal averaging in triangle strips occurs automatically. glShadeModel = GL_SMOOTH, and that's how it was explained to me.

I was thinking perhaps this is not something GL does automatically? If so, how do I average normals mathematically at an intersection of 2 or 4 vertices?

Here is my display-list for my object. If anyone has suggestions, please email efesar@nmia.com. Eternally grateful.

---

//////////////////////////////////////////////////////////////////
// MyGLbackplane()
// Our cyan backplane display list
//////////////////////////////////////////////////////////////////
void CMyGL::MyGLbackplane()
{
float specref[] = {1.0f,1.0f,1.0f,1.0f};
float amref[] = {0.5f,0.5f,0.5f,1.0f};

float ellX = 1.1f;
float ellY = 0.75f;

glNewList(backplane,GL_COMPILE);

glPushAttrib(GL_ENABLE_BIT );
glDisable(GL_CULL_FACE);
glShadeModel(GL_SMOOTH);

// set the material for our backplane
glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,specref );
glMateriali(GL_FRONT_AND_BACK,GL_SHININESS,64);
glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFF USE,amref);

float jinc = 5.0f;

// a grid of 66x66 little quads (for specularity)
for (float ii=0.0f;ii < 32.0f; ii++)
{
glBegin(GL_TRIANGLE_STRIP);
for (float jj=0.0f;jj<=360.0f; jj=jj+jinc)
{
float v1[3][3],v2[3][3];
float out[3];

v1[0][0] = ellX*(float)cos( DegToRad(jj) ) * ii;
v1[0][1] = ellY*(float)sin( DegToRad(jj) ) * ii;
v1[0][2] = 100.0f -(float)cos( DegToRad(ii) ) * 100.0f;

v1[2][0] = ellX*(float)cos( DegToRad(jj+jinc) ) * (ii);
v1[2][1] = ellY*(float)sin( DegToRad(jj+jinc) ) * (ii);
v1[2][2] = 100.0f - (float)cos( DegToRad(ii) ) * 100.0f;

v1[1][0] = ellX*(float)cos( DegToRad(jj) ) * (ii+1.0f);
v1[1][1] = ellY*(float)sin( DegToRad(jj) ) * (ii+1.0f);
v1[1][2] = 100.0f - (float)cos( DegToRad(ii+1.0f) ) * 100.0f;

v2[0][0] = v1[0][0];
v2[0][1] = v1[0][1];
v2[0][2] = v1[0][2];

v2[1][0] = v1[1][0];
v2[1][1] = v1[1][1];
v2[1][2] = v1[1][2];

v2[2][0] = ellX*(float)cos( DegToRad(jj+jinc) ) * (ii+1.0f);
v2[2][1] = ellY*(float)sin( DegToRad(jj+jinc) ) * (ii+1.0f);
v2[2][2] = 100.0f - (float)cos( DegToRad(ii+1) ) * 100.0f;

CalcNormal(v1,out);

glColor3f(0.7647f,0.4353f,0.1059f);

glNormal3fv(out);
glVertex3fv(v1[0]);

glNormal3fv(out);
glVertex3fv(v1[1]);

glNormal3fv(out);
glVertex3fv(v1[2]);

CalcNormal(v2,out);

glNormal3fv(out);
glVertex3fv(v2[2]);

}
glEnd();
}

glPopAttrib();

glEndList();
}

Humus
04-11-2000, 04:16 PM
GL_SMOOTH tells OpenGL to interpolate between colors, it has nothing to do with normals. If you would use GL_FLAT instead you would get an constant color.

To get an average of the normalvectors you just need to add them together and normalize.

Pseudo:
AvarageNormal = (Normal1 + Normal2 + Normal3) / length(Normal1 + Normal2 + Normal3);