Advertisement
Guest User

Cairo animation example with timing

a guest
Oct 27th, 2016
32
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.66 KB | None | 0 0
  1. /**
  2.  * A simple animation using cairo and GTK+
  3.  *
  4.  * This program shows high /usr/libexec/Xorg load while running full screen on Linux
  5.  *
  6.  * Compile with:
  7.  *   gcc `pkg-config --cflags --libs gtk+-3.0` -lm main.c
  8.  */
  9.  
  10. #include <gtk/gtk.h>
  11. #include <math.h>
  12. #include <time.h>
  13.  
  14. #define NUM_WINDOWS (1u)
  15. #define NUM_POINTS (1000u)
  16. #define PERIOD (100u)
  17.  
  18. /* Local function prototypes */
  19. static gboolean invalidate_cb(void *);
  20. static gboolean drawing_area_draw_cb(GtkWidget *, cairo_t *, void *);
  21.  
  22. int main(int argc, char **argv)
  23. {
  24.     int i;
  25.     gtk_init(&argc, &argv);
  26.    
  27.     for (i = 0; i < NUM_WINDOWS; i++)
  28.     {
  29.         GtkWidget *main_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  30.         gtk_window_set_title(GTK_WINDOW(main_window), "Drawing example");
  31.         gtk_window_set_default_size(GTK_WINDOW(main_window), 400, 400);
  32.         GtkWidget *drawing_area = gtk_drawing_area_new();
  33.        
  34.         gtk_container_add(GTK_CONTAINER(main_window), drawing_area);
  35.         gtk_widget_show_all(main_window);
  36.  
  37.         /* Create a  timer to invalidate our window at 60Hz */
  38.         g_timeout_add(1000 / 60, invalidate_cb, drawing_area);
  39.  
  40.         /* Connect our redraw callback */
  41.         g_signal_connect(drawing_area, "draw", G_CALLBACK(drawing_area_draw_cb), NULL);
  42.  
  43.         /* Connect the destroy signal */
  44.         g_signal_connect(main_window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
  45.     }
  46.     gtk_main();
  47. }
  48.  
  49. static gboolean invalidate_cb(void *ptr)
  50. {
  51.     if (GTK_IS_WIDGET(ptr))
  52.     {
  53.         gtk_widget_queue_draw(GTK_WIDGET(ptr));
  54.         return TRUE;
  55.     }  
  56.     return FALSE;
  57. }
  58.  
  59. static inline float sine_to_point(int x, int width, int height)
  60. {
  61.  
  62.     return (height / 2.0) * sin(x * 2 * M_PI / (PERIOD)) + height / 2.0;
  63. }
  64.  
  65. static gboolean drawing_area_draw_cb(GtkWidget *widget, cairo_t *context, void *ptr)
  66. {
  67.     static int redraw_number = 0;
  68.     static double average_time = 0;
  69.     clock_t start = clock();
  70.     int width, height, i;
  71.    
  72.     width = gtk_widget_get_allocated_width(widget);
  73.     height = gtk_widget_get_allocated_height(widget);
  74.  
  75.     /* Draw the background */  
  76.     cairo_set_source_rgb(context, 1, 1, 1);
  77.     cairo_rectangle(context, 0, 0, width, height);
  78.     cairo_fill(context);
  79.  
  80.     /* Draw a moving sine wave */
  81.     cairo_set_source_rgb(context, 0.5, 0.5, 0);
  82.     cairo_move_to(context, 0, sine_to_point(0 + redraw_number, width, height));
  83.     for (i = 1; i < NUM_POINTS; i++)
  84.     {
  85.         cairo_line_to(context,  i, sine_to_point(i + redraw_number, width, height));   
  86.     }  
  87.     cairo_stroke(context);
  88.  
  89.  
  90.     redraw_number++;
  91.    
  92.     clock_t end = clock();
  93.     average_time += (double) (end - start) / CLOCKS_PER_SEC;
  94.     if (redraw_number % 60 == 0)
  95.     {
  96.         printf("Average time: %fms, Max FPS: %d\n", 1000.0 * average_time / 60, (int) (1.0 / (average_time / 60)));
  97.         average_time = 0;
  98.     }
  99. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement