/* Test performance of al_draw_bitmap_region, al_create_sub_bitmap and * al_set_clipping_rectangle when clipping a bitmap. */ #include #include #include #include #include #include #include "common.c" struct Example { ALLEGRO_BITMAP *pattern; ALLEGRO_FONT *font; ALLEGRO_EVENT_QUEUE *queue; ALLEGRO_COLOR background, text, white; double timer[4], counter[4]; int FPS; float text_x, text_y; } ex; static ALLEGRO_BITMAP *example_bitmap(int w, int h) { int i, j; float mx = w * 0.5; float my = h * 0.5; ALLEGRO_STATE state; ALLEGRO_BITMAP *pattern = al_create_bitmap(w, h); al_store_state(&state, ALLEGRO_STATE_TARGET_BITMAP); al_set_target_bitmap(pattern); al_lock_bitmap(pattern, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_WRITEONLY); for (i = 0; i < w; i++) { for (j = 0; j < h; j++) { float a = atan2(i - mx, j - my); float d = sqrt(pow(i - mx, 2) + pow(j - my, 2)); float l = 1 - pow(1.0 - 1 / (1 + d * 0.1), 5); float hue = a * 180 / ALLEGRO_PI; float sat = 1; if (i == 0 || j == 0 || i == w - 1 || j == h - 1) { hue += 180; } else if (i == 1 || j == 1 || i == w - 2 || j == h - 2) { hue += 180; sat = 0.5; } al_put_pixel(i, j, al_color_hsl(hue, sat, l)); } } al_unlock_bitmap(pattern); al_restore_state(&state); return pattern; } static void set_xy(float x, float y) { ex.text_x = x; ex.text_y = y; } static void get_xy(float *x, float *y) { *x = ex.text_x; *y = ex.text_y; } static void print(char const *format, ...) { va_list list; char message[1024]; int th = al_get_font_line_height(ex.font); va_start(list, format); vsnprintf(message, sizeof message, format, list); va_end(list); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); al_draw_textf(ex.font, ex.text, ex.text_x, ex.text_y, 0, "%s", message); ex.text_y += th; } static void start_timer(int i) { ex.timer[i] -= al_get_time(); ex.counter[i]++; } static void stop_timer(int i) { ex.timer[i] += al_get_time(); } static double get_fps(int i) { if (ex.timer[i] == 0) return 0; return ex.counter[i] / ex.timer[i]; } static void draw(void) { float x, y; int iw = al_get_bitmap_width(ex.pattern); int ih = al_get_bitmap_height(ex.pattern); ALLEGRO_BITMAP *temp; int cx, cy, cw, ch, gap = 8; al_get_clipping_rectangle(&cx, &cy, &cw, &ch); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); al_clear_to_color(ex.background); /* Test 1. */ set_xy(8, 8); print("al_draw_bitmap_region (%.1f fps)", get_fps(0)); get_xy(&x, &y); al_draw_bitmap(ex.pattern, x, y, 0); start_timer(0); al_draw_bitmap_region(ex.pattern, 1, 1, iw - 2, ih - 2, x + 8 + iw + 1, y + 1, 0); stop_timer(0); set_xy(x, y + ih + gap); /* Test 2. */ print("al_create_sub_bitmap (%.1f fps)", get_fps(1)); get_xy(&x, &y); al_draw_bitmap(ex.pattern, x, y, 0); start_timer(1); temp = al_create_sub_bitmap(ex.pattern, 1, 1, iw - 2, ih - 2); al_draw_bitmap(temp, x + 8 + iw + 1, y + 1, 0); al_destroy_bitmap(temp); stop_timer(1); set_xy(x, y + ih + gap); /* Test 3. */ print("al_set_clipping_rectangle (%.1f fps)", get_fps(2)); get_xy(&x, &y); al_draw_bitmap(ex.pattern, x, y, 0); start_timer(2); al_set_clipping_rectangle(x + 8 + iw + 1, y + 1, iw - 2, ih - 2); al_draw_bitmap(ex.pattern, x + 8 + iw, y, 0); al_set_clipping_rectangle(cx, cy, cw, ch); stop_timer(2); set_xy(x, y + ih + gap); } static void tick(void) { draw(); al_flip_display(); } static void run(void) { ALLEGRO_EVENT event; bool need_draw = true; while (1) { if (need_draw && al_is_event_queue_empty(ex.queue)) { tick(); need_draw = false; } al_wait_for_event(ex.queue, &event); switch (event.type) { case ALLEGRO_EVENT_DISPLAY_CLOSE: return; case ALLEGRO_EVENT_KEY_DOWN: if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) return; break; case ALLEGRO_EVENT_TIMER: need_draw = true; break; } } } static void init(void) { ex.FPS = 60; ex.font = al_create_builtin_font(); if (!ex.font) { abort_example("Error creating builtin font.\n"); } ex.background = al_color_name("beige"); ex.text = al_color_name("blue"); ex.white = al_color_name("white"); ex.pattern = example_bitmap(100, 100); } int main(int argc, char **argv) { ALLEGRO_DISPLAY *display; ALLEGRO_TIMER *timer; (void)argc; (void)argv; if (!al_init()) { abort_example("Could not init Allegro.\n"); } al_install_keyboard(); al_install_mouse(); al_init_font_addon(); init_platform_specific(); display = al_create_display(640, 480); if (!display) { abort_example("Error creating display.\n"); } init(); timer = al_create_timer(1.0 / ex.FPS); ex.queue = al_create_event_queue(); al_register_event_source(ex.queue, al_get_keyboard_event_source()); al_register_event_source(ex.queue, al_get_mouse_event_source()); al_register_event_source(ex.queue, al_get_display_event_source(display)); al_register_event_source(ex.queue, al_get_timer_event_source(timer)); al_start_timer(timer); run(); al_destroy_event_queue(ex.queue); return 0; }