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 ******************************************/