### 5.9.1 Example G4, Lighting

Here is a short example that uses lighting calculations. In this example, we turn one light source, set its positon but use its default color. We set the local viewer property of the light model. Then we render a yellow dodecahedron and a red sphere.

    /********************* Example G4 **********************************************/
    #include "EZ.h"

    static void event_handle(EZ_Widget *, void *,int,XEvent *); /* event handle   */
    static void draw(EZ_Widget *canvas);                        /* repaint func   */
    static float light_position[] = {0.5, 0.5, 0.0, 1.0};       /* light position */
    static float white[] = {1.0,1.0,1.0,1.0};
    static float shininess[] = {8.0};

    main(int argc, char **argv)
    {
      EZ_Widget *frame, *canvas;

      /* create a canvas */
      EZ_Initialize(argc, argv, 1);

      frame = EZ_CreateWidget(EZ_WIDGET_FRAME, NULL,
                             EZ_FILL_MODE, EZ_FILL_BOTH,
                             0);
      canvas = EZ_CreateWidget(EZ_WIDGET_3D_CANVAS, frame,
                               EZ_ORIENTATION,   EZ_VERTICAL_BOTTOM,
                               EZ_WIDTH_HINT,    320,
                               EZ_HEIGHT_HINT,   320,
                               EZ_EVENT_HANDLER, event_handle, NULL,
                               0);

      EZ_DisplayWidget(canvas);

      /* setup GL modes */
      EZ_AutoSelectBackBuffer();                          /* select a back  buffer */
      EZ_RGBMode();                                       /* select color  mode    */
      EZ_ShadeModel(EZ_SMOOTH);                           /* select  shading model */
      EZ_DrawBuffer(EZ_BACK);                             /* draw into the  backbuf*/
      EZ_Enable(EZ_CULL_FACE);                            /* enable  backface cull */
      EZ_Enable(EZ_DEPTH_TEST);                           /* enable  zbuffer       */

      /* lighting related attributes. One should be aware
       * that where to invoke EZ_Lightfv or EZ_Materialfv
       * matters a lot. The corresponding properties are
       * computed based on the current model view matrix.
       */
      EZ_Enable(EZ_LIGHTING);                             /* enable lighting      */
      EZ_Enable(EZ_LIGHT0);                               /* enable one light src */
      /* set light src pos, this light src has a fixed position, i.e.
       * the position will not be affected by the model view matrux */
      EZ_Lightfv(EZ_LIGHT0, EZ_POSITION, light_position);
      EZ_Materialfv(EZ_FRONT,EZ_SPECULAR,white);   /* set material for front face */
      EZ_Materialfv(EZ_FRONT,EZ_SHININESS,shininess);
      EZ_LightModelfv(EZ_LIGHT_MODEL_LOCAL_VIEWER, white);

      EZ_MatrixMode(EZ_PROJECTION);           /* setup a fixed projection matrix */
      EZ_Perspective(60.0, 1.0, 2.0, 30.0);   /* a perspective view, ...         */
      EZ_MatrixMode(EZ_MODELVIEW);            /* set matrix mode to model view   */
      EZ_LookAt(0.0,0.0,15.0, 0.0,0.0,0.0,    /* and set up a look at view       */
                0.0,1.0, 0.0);                /* view up vector        */

      EZ_EventMainLoop();                     /* turn control to EZWGL           */
    }

    static float rotX = 0.0, rotY = 0.0, rotZ = 0.0;      /* rotation angles      */
    static float scale = 1.0;                             /* zooming factor       */
    static float yellow[] = {0.8, 0.8, 0.0, 0.0};         /* material color       */
    static float red[] = {0.8, 0.1, 0.0, 0.0};            /* material color       */

    static void draw(EZ_Widget *canvas)
    {
      /*
       * since we only have one 3DCanvas, which is always
       * active, we actually don't need the argument.
       */
      EZ_Clear(EZ_COLOR_BUFFER_BIT |                    /* clear the frame buffer */
               EZ_DEPTH_BUFFER_BIT);                    /* and the zbuffer        */
      EZ_PushMatrix();
      EZ_Scale(scale,scale,scale);                      /* a uniform scale        */
      EZ_Rotate(rotX, 1.0, 0.0, 0.0 );                  /* rotate about X, Y & Z  */
      EZ_Rotate(rotY, 0.0, 1.0, 0.0 );
      EZ_Rotate(rotZ, 0.0, 0.0, 1.0 );
      EZ_PushMatrix();
      EZ_Translate( -3.0, 0.0, 0.0 );
      EZ_Materialfv(EZ_FRONT,EZ_DIFFUSE, yellow);      /* a yellow material */
      EZ_Dodecahedron(0.0,0.0,0.0,2.4);
      EZ_PopMatrix();
      EZ_PushMatrix();
      EZ_Translate(3.0,0.0,0.0);
      EZ_Materialfv(EZ_FRONT,EZ_DIFFUSE, red);         /* a red material  */
      EZ_Sphere(EZ_SPHERE_TRIANGLE, 4,0.0,0.0,0.0,2.0);
      EZ_PopMatrix();
      EZ_PopMatrix();
      EZ_SwapBuffers();
    }

    static void event_handle(EZ_Widget *canvas, void *data, int eventType, XEvent *xev)
    {
      switch(eventType) {
      case EZ_REDRAW:
      case EZ_RESIZE:
        draw(canvas);
        break;
      case EZ_KEY_PRESS:
        switch(EZ_PressedKey) {
        case EZ_DOWN_KEY:   rotX += 5.0; draw(canvas); break;
        case EZ_UP_KEY:     rotX -= 5.0; draw(canvas); break;
        case EZ_RIGHT_KEY:  rotY += 5.0; draw(canvas); break;
        case EZ_LEFT_KEY:   rotY -= 5.0; draw(canvas); break;
        case 'e':           scale *= 1.1;draw(canvas); break;
        case 'r':           scale *= 0.9;draw(canvas); break;
        case EZ_ESCAPE_KEY:
          EZ_DestroyWidget(canvas);
          EZ_Shutdown();
          exit(0);
          break;
        default:
          break;
        }
        EZ_GLResetEvents(NULL); /* clear the event queue, too many keypresses */
        break;
      default:
        break;
      }
    }
    /********************* Example G4 **********************************************/

HTML Documentation Maintainance:`Arturo Espinosa <arturo@nuclecu.unam.mx>`