Blit bitmap to display
georg53

Writing single pixels to the screen (using GDI graphics) was very fast in Allegro 4 but in Allegro 5 it is very slow - at least as far as I got it to work. So I want to use bitmaps instead.

I have a program that generates a bitmap in TRUECOLOR8888 pixel format in memory and then asks to write this on the screen giving the address and pitch of the bitmap in memory and the position plus width and height where this block of pixels shall be put on the display.

Do I need to lock this bitmap in memory as an Allegro bitmap? Can I define my display where this bitmap shall be written as a bitmap and how do you do that? How do I then copy from the bitmap in memory to the display? The bitmap in memory can start at any position on the screen and end at a different position on another line on the display. I did some reading on this but found no solution.

RPG Hacker

This easiest approach would probably be this (if I understood what exactly you're trying to do):

1) Create a video bitmap

2) Depending on how many pixels you want to draw:
a) Use al_lock_bitmap + al_put_pixel to modify pixel data (if drawing a lot of pixels)
b) Use al_draw_pixel to draw pixels (if drawing a small or medium amount of pixels)
Probably even try both methods to see which one is faster for you

3) Draw this bitmap to whereever on the display you want it with al_draw_bitmap

georg53

My question probably had too many misunderstandings of the Allegro concepts, sorry.

Anyhow, here is my test program which writes from a flat block of pixels in memory to the display using Allegro. The program I finally want to use Allegro with provides such a block of pixels to have them written to the display.

If anything should be changed, please post.

#SelectExpand
1 2#include "allegro5/allegro.h" 3 4int main(void) 5{ 6 ALLEGRO_DISPLAY *display; 7 ALLEGRO_BITMAP *display_bitmap; 8 ALLEGRO_LOCKED_REGION *locked_region; 9 int lock_flags = ALLEGRO_LOCK_READWRITE; 10 11 al_init(); 12 display = al_create_display(800, 400); 13 14/* access display(i.e. its backbuffer) as ALLEGRO bitmap */ 15 display_bitmap = al_get_backbuffer(display); 16 17/* clear display_bitmap to nice color */ 18 al_set_target_bitmap(display_bitmap); 19 al_clear_to_color(al_map_rgb_f(0.8, 0.8, 0.9)); 20 al_set_target_backbuffer(display); 21 22/* generate flat 32 bit pixel buffer for testing */ 23 char buf[800*4] = { 0, }; 24 uint32_t * buffer = (uint32_t *) buf, i; 25 for(i = 0; i < sizeof(buf) / sizeof(* buffer); ++i) { 26 buffer[i] = 0x0000FF00; //fill with blue 27 } 28 29/* Locking the bitmap means, we work directly with pixel data. */ 30 locked_region = al_lock_bitmap(display_bitmap, ALLEGRO_PIXEL_FORMAT_RGBA_8888, lock_flags); 31 32 int line; //number of display lines written 33 for (line = 0; line < 200; line++) { 34 uint8_t *ptr = (uint8_t*)locked_region->data + line * locked_region->pitch; 35 uint32_t *cptr = (uint32_t*)ptr; 36 memcpy(cptr,buffer,800*4); /* blit pixels into locked backbuffer */ 37 } 38 39 al_unlock_bitmap(display_bitmap); 40 al_flip_display(); 41 42 sleep(5); /* let user gasp in awe */ 43 44 return 0; 45}

#00JMP00

Inmediate strike for captain obious.

You have to call al_init() bevor doing anything. Often used bug:-)

If you don't you will have changing outcomes.

georg53

al_init is in line 11. To keep the example short I do not check if successful.

The example works as expected but maybe I overlooked something.

#00JMP00

Before line 11 you call al_init_display(), respective allegro_display...

In older times, calling anything allegro before init would lead to
strange and unforeseable behaviour, I think.

Thread #615663. Printed from Allegro.cc