How to Set the Current Normal Vector in an OpenGL Application

Last reviewed: September 29, 1995
Article ID: Q131130
The information in this article applies to:
  • Microsoft Win32 Application Programming Interface (API) included with:

        - Microsoft Windows NT version 3.5
    

SUMMARY

In a Microsoft Win32 OpenGL application, it is common practice to construct objects with the glBegin function followed by several calls to glVertex. For example, to create a flat polygon in three-dimensional space, you could write this code:

   glBegin(GL_POLYGON);
   glVertex3f(.....);
   glVertex3f(.....);
   glVertex3f(.....);
   .  .  .
   .  .  .
   glEnd();

Now, if you want to implement a light source or multiple light sources in your OpenGL application, it is important that you include a call to the glNormal function between the calls to glBegin and glEnd so that the normal vector can be used by OpenGL when calculating the color to use when filling the polygon.

You can perform a vector cross product on two vectors to obtain a third vector that is perpendicular to the plane containing the two vectors. Using a vector cross product, you can calculate the vector normal to the polygon and use that value in your call to glNormal.

MORE INFORMATION

Using cross product math on two vectors of a polygon, you can obtain a vector that is perpendicular to the polygon. Two sides of a polygon describe two vectors in the plane of the polygon. With those two vectors, you can calculate a vector that is perpendicular to the polygon. The length of the normal vector calculated will not be unit length, and the normal vector needs to be unit length. Therefore, you need to call glEnable(GL_NORMALIZE) when you initialize your OpenGL application, so that normal vectors specified with glNormal are scaled to unit length after transformation.

Code Sample

You can use the following function to calculate a normal vector for a polygon. You need to give it three points of the polygon and the points should be given in clock-wise order when you are facing the front of the polygon:

//***********************************************************************
// Function: CalculateVectorNormal
//
// Purpose: Given three points of a 3D plane, this function calculates
//          the normal vector of that plane.
//
// Parameters:
//     fVert1[]   == array for 1st point (3 elements are x, y, and z).
//     fVert2[]   == array for 2nd point (3 elements are x, y, and z).
//     fVert3[]   == array for 3rd point (3 elements are x, y, and z).
//
// Returns:
//     fNormalX   == X vector for the normal vector
//     fNormalY   == Y vector for the normal vector
//     fNormalZ   == Z vector for the normal vector
//
// Comments:
//
// History:  Date       Author        Reason
//           3/22/95     GGB           Created
//*************************************************************************

GLvoid CalculateVectorNormal(GLfloat fVert1[], GLfloat fVert2[],
                             GLfloat fVert3[], GLfloat *fNormalX,
                             GLfloat *fNormalY, GLfloat *fNormalZ)
    {
    GLfloat Qx, Qy, Qz, Px, Py, Pz;

    Qx = fVert2[0]-fVert1[0];
    Qy = fVert2[1]-fVert1[1];
    Qz = fVert2[2]-fVert1[2];
    Px = fVert3[0]-fVert1[0];
    Py = fVert3[1]-fVert1[1];
    Pz = fVert3[2]-fVert1[2];

    *fNormalX = Py*Qz - Pz*Qy;
    *fNormalY = Pz*Qx - Px*Qz;
    *fNormalZ = Px*Qy - Py*Qx;
}

Code to Call and Use the CalculateVectorNormal Function

Here is an example of how you might call and use the function:

   glBegin(GL_POLYGON);
   glVertex3fv(fVert1);
   glVertex3fv(fVert2);
   glVertex3fv(fVert3);
   glVertex3fv(fVert4);

   // Calculate the vector normal coming out of the 3D polygon.
   CalculateVectorNormal(fVert1, fVert2, fVert3, &fNormalX,
                         &fNormalY, &fNormalZ);
   // Set the normal vector for the polygon
   glNormal3f(fNormalX, fNormalY, fNormalZ);
   glEnd();


Additional reference words: 3.50 graphics
KBCategory: kbgraphic kbcode
KBSubcategory: GdiOpenGL


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: September 29, 1995
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.