### 5.4.5 Example G2, The Sine Curve

This short example demonstrates the use of double buffers. We create a 3DCanvas and draw a sine curve into it continuously. At each draw we shift the phase a little bit, creating the illusion of a moving wave.

We use a check button to turn the double buffer on/off. In double buffer mode, the animation looks smooth, while in single buffer mode, the curve flickers too much.

We also provide a slider to adjust the speed of the animation.

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

    static void eventHandler(EZ_Widget *, void *, int, XEvent *);
    static void draw(EZ_Widget *);
    static void sliderCallBack(EZ_Widget *, void *);
    static void cbtnCallBack(EZ_Widget *, void *);
    static float speed = 0.1;
    static int  bufferMode = 1;

    main(int argc, char **argv)
    {
      EZ_Widget *frame, *canvas, *slider, *cbtn;
      /*
       * Initialize EZWGL, don't forget to
       * initialize the graphics library also.
       */
      EZ_Initialize(argc, argv, 1);      /* notice the 1        */
      /*
       * canvases do not resize propertly as toplevel
       * widgets (bug!) It is recommended to put it
       * under a frame at least for now.
       */
      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, eventHandler, NULL,
                               0);
      slider = EZ_CreateWidget(EZ_WIDGET_VERTICAL_SLIDER, frame,
                               EZ_LABEL_STRING,      "speed",
                               EZ_SLIDER_RANGE,      0.0, 10.0,
                               EZ_SLIDER_INIT_VALUE, 1.0,
                               EZ_CALLBACK,          sliderCallBack, &speed,
                               0);

      /* create a button to toggle double buffer on/off */
      cbtn = EZ_CreateWidget(EZ_WIDGET_CHECK_BUTTON, canvas,
                             EZ_LABEL_STRING,        "Turn DoubleBuffer On/Off",
                             EZ_CHECK_BUTTON_ON_VALUE,  0,
                             EZ_CHECK_BUTTON_OFF_VALUE, 1,
                             EZ_CHECK_BUTTON_ON_OFF,    EZ_ON,
                             EZ_BORDER_WIDTH,           2,
                             EZ_BORDER_TYPE,            EZ_BORDER_RAISED,
                             EZ_CALLBACK,               cbtnCallBack, NULL,
                             0);
      /*
       * now display the canvas. One must first display
       * a 3DCanvas before calling any GL functions !!!
       */
      EZ_DisplayWidget(canvas);

      /* now setup global GL attributes */
      EZ_RGBMode();                 /* we are using RGB mode  */
      EZ_AutoSelectBackBuffer();    /* select a back buffer   */
      EZ_DrawBuffer(EZ_BACK);/* always draw into the back buf */

      /*
       * We'll draw a 2D polygon, so we don't have to setup
       * a complex projection matrix. The default matrix mode
       * is EZ_MODELVIEW. We just set the projection matrix
       * on this default matrix stack.
       */
      EZ_LoadIdentity();            /* clear the top mtx 2 id */
      EZ_Ortho2(0.0,10.0,-1.3,1.3); /* project the unit cube  */

      /*
       * We don't draw anything here, let the
       * event handler handle the drawing
       */
      while(1)
        {
          EZ_ServiceEvents();
          EZ_DrawBuffer(bufferMode == 0? EZ_FRONT: EZ_BACK);
          draw(canvas);
          if(bufferMode != 0) EZ_SwapBuffers();
        }
    }

    static void draw(EZ_Widget *canvas)
    {
      static float shift = 0.0;
      float  t, x, y;
      int    i;

      EZ_Clear(EZ_COLOR_BUFFER_BIT); /* clear the frame buffer */
      EZ_Color3f(1.0,1.0,0.0);

      EZ_Begin(EZ_LINE_STRIP);       /* start a polyline       */

      t = shift;
      shift += speed;
      x = 0.0;

      for(i = 0; i < 1000; i++)
        {
          y = sin(t+x);
          x += 0.01;

          EZ_Vertex2f(x, y);
        }
      EZ_End();
    }
    /*
     * the event handler. It should handle at least the
     * EZ_REDRAW event and the EZ_RESIZE.
     */
    static void eventHandler(EZ_Widget *canvas, void *data,
                             int eventType, XEvent *xevent)
    {
      switch(eventType)
        {
        case EZ_REDRAW:
        case EZ_RESIZE:
          draw(canvas);
          if(bufferMode != 0) EZ_SwapBuffers();
          break;
        case EZ_KEY_PRESS:
          if(EZ_PressedKey == EZ_ESCAPE_KEY) exit(0);
          break;
        default:
          break;
        }
    }

    static void sliderCallBack(EZ_Widget *slider, void *data)
    {
      float *f = (float *)data;
      *f = 0.05 * EZ_GetSliderValue(slider);
    }

    static void cbtnCallBack(EZ_Widget *cbtn, void *data)
    {
      EZ_GetCheckButtonState(cbtn, &bufferMode);
    }
    /*************** Example G2 ******************************************/

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