The Allegro Wiki is migrating to github at https://github.com/liballeg/allegro_wiki/wiki

Allegro 5 Tutorial/Bitmaps

From Allegro Wiki
Jump to: navigation, search

In this section we learn how to create and draw bitmaps.

Current Display/Target

Allegro 5 has the concept that of the current display, and drawing target. They are related, but the target needs not be the current display.

When creating a display, it is made the current display, and its backbuffer is made the drawing target.

All drawing operations draw to the drawing target, which in most cases, is probably also the current display's backbuffer.

Building on the previous example, we will add a bouncing bitmap.

#include <stdio.h>
#include <allegro5/allegro.h>
 
const float FPS = 60;
const int SCREEN_W = 640;
const int SCREEN_H = 480;
const int BOUNCER_SIZE = 32;

int main(int argc, char **argv){
   ALLEGRO_DISPLAY *display = NULL;
   ALLEGRO_EVENT_QUEUE *event_queue = NULL;
   ALLEGRO_TIMER *timer = NULL;
   ALLEGRO_BITMAP *bouncer = NULL;
   float bouncer_x = SCREEN_W / 2.0 - BOUNCER_SIZE / 2.0;
   float bouncer_y = SCREEN_H / 2.0 - BOUNCER_SIZE / 2.0;
   float bouncer_dx = -4.0, bouncer_dy = 4.0;
   bool redraw = true;
 
   if(!al_init()) {
      fprintf(stderr, "failed to initialize allegro!\n");
      return -1;
   }
 
   timer = al_create_timer(1.0 / FPS);
   if(!timer) {
      fprintf(stderr, "failed to create timer!\n");
      return -1;
   }
 
   display = al_create_display(SCREEN_W, SCREEN_H);
   if(!display) {
      fprintf(stderr, "failed to create display!\n");
      al_destroy_timer(timer);
      return -1;
   }

   bouncer = al_create_bitmap(BOUNCER_SIZE, BOUNCER_SIZE);
   if(!bouncer) {
      fprintf(stderr, "failed to create bouncer bitmap!\n");
      al_destroy_display(display);
      al_destroy_timer(timer);
      return -1;
   }

   al_set_target_bitmap(bouncer);

   al_clear_to_color(al_map_rgb(255, 0, 255));

   al_set_target_bitmap(al_get_backbuffer(display));
 
   event_queue = al_create_event_queue();
   if(!event_queue) {
      fprintf(stderr, "failed to create event_queue!\n");
      al_destroy_bitmap(bouncer);
      al_destroy_display(display);
      al_destroy_timer(timer);
      return -1;
   }
 
   al_register_event_source(event_queue, al_get_display_event_source(display));
 
   al_register_event_source(event_queue, al_get_timer_event_source(timer));
 
   al_clear_to_color(al_map_rgb(0,0,0));
 
   al_flip_display();
 
   al_start_timer(timer);
 
   while(1)
   {
      ALLEGRO_EVENT ev;
      al_wait_for_event(event_queue, &ev);
 
      if(ev.type == ALLEGRO_EVENT_TIMER) {
         if(bouncer_x < 0 || bouncer_x > SCREEN_W - BOUNCER_SIZE) {
            bouncer_dx = -bouncer_dx;
         }

         if(bouncer_y < 0 || bouncer_y > SCREEN_H - BOUNCER_SIZE) {
            bouncer_dy = -bouncer_dy;
         }

         bouncer_x += bouncer_dx;
         bouncer_y += bouncer_dy;

         redraw = true;
      }
      else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {
         break;
      }
 
      if(redraw && al_is_event_queue_empty(event_queue)) {
         redraw = false;

         al_clear_to_color(al_map_rgb(0,0,0));

         al_draw_bitmap(bouncer, bouncer_x, bouncer_y, 0);

         al_flip_display();
      }
   }
 
   al_destroy_bitmap(bouncer);
   al_destroy_timer(timer);
   al_destroy_display(display);
   al_destroy_event_queue(event_queue);
 
   return 0;
}

Walk through

Building on the last example we have added a silly bouncing bitmap. We will only cover the new and changed bits.

5 const int SCREEN_W = 640;
6 const int SCREEN_H = 480;
7 const int BOUNCER_SIZE = 32;

Here we've defined a few constants to make our lives a little easier. Two to define the size of the display, and one for the dimensions of the bouncing box.

   bouncer = al_create_bitmap(BOUNCER_SIZE, BOUNCER_SIZE);
   if(!bouncer) {
      fprintf(stderr, "failed to create bouncer bitmap!\n");
      al_destroy_display(display);
      al_destroy_timer(timer);
      return -1;
   }

Here we create our bitmap using al_create_bitmap with a width and height of BOUNCER_SIZE. On failure, al_create_bitmap will return NULL, and our failure handling code will clean up previously created objects, and then exit the program.

   al_set_target_bitmap(bouncer);

Here's a new concept. The target bitmap is the bitmap in which all drawing functions currently draw to. This is normally handled by allegro, but should you need to draw directly to a bitmap (rather than loading one), you call al_set_target_bitmap and then use the drawing functions as normal.

   al_clear_to_color(al_map_rgb(255, 0, 255));

Like before, except now al_clear_to_color clears our bitmap, instead of the display.

   al_set_target_bitmap(al_get_backbuffer(display));

Change the drawing target back to the display we created.

         if(bouncer_x < 0 || bouncer_x > SCREEN_W - BOUNCER_SIZE) {
            bouncer_dx = -bouncer_dx;
         }

         if(bouncer_y < 0 || bouncer_y > SCREEN_H - BOUNCER_SIZE) {
            bouncer_dy = -bouncer_dy;
         }

         bouncer_x += bouncer_dx;
         bouncer_y += bouncer_dy;

Not particularly interesting. But here is the bouncing logic. If the square hits the display's borders, reverse direction. We put the logic in the timer event, so that the bouncing bitmap moves at the same rate on any computer.

         al_draw_bitmap(bouncer, bouncer_x, bouncer_y, 0);

Now draw our bitmap to the display.

   al_destroy_bitmap(bouncer);

Destroy the bouncer bitmap.

That concludes the basic Bitmap use in Allegro 5.