Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » ALLEGRO_LOCKED_REGION confusion

This thread is locked; no one can reply to it. rss feed Print
ALLEGRO_LOCKED_REGION confusion
William Labbett
Member #4,486
March 2004
avatar

Hi, in this code, the part starting at the line (comment) I've highlighted achieves the
same result as the second section of code, yet the offsets are 3, 2, and 1 for r, g and b in the first section and are 2, 1, 0 for the r, g and b in the section patch.
I got the second to work partly by using cout for debugging so I got it working. The problem is it doesn't make any sense to me why they both achieve the same thing. Can anyone help? me understand?

#SelectExpand
1int rotate_picture(ALLEGRO_CONFIG *config, ALLEGRO_FONT *ttf) 2{ 3 ALLEGRO_EVENT event; 4 ALLEGRO_EVENT_QUEUE *rotate_queue = NULL; 5 bool finished = false; 6 float rotate_angle = 0.0f; 7 ALLEGRO_BITMAP *bitmap_to_rotate = NULL; 8 ALLEGRO_BITMAP *guide_bitmap = NULL; 9 /* copy_bitmap : for a copy of the original bitmap to be rotated. */ 10 ALLEGRO_BITMAP *copy_bitmap = NULL; 11 ALLEGRO_BITMAP *bitmap_to_save = NULL; 12 /* int x, int y : for running through pixels of guide bitmap. */ 13 int x = 0; 14 int y = 0; 15 ALLEGRO_LOCKED_REGION *locked_region = NULL; 16 /* integers for getting pixel components from guide bitmap */ 17 int ri = 0; 18 int gi = 0; 19 int bi = 0; 20 unsigned char *pixel_ptr = NULL; 21 uint32_t new_pixel = 0; 22 /* Integers for moving the guide bitmap up, down, left and right. */ 23 int guide_x = 0; 24 int guide_y = 0; 25 26 27 rotate_queue = al_create_event_queue(); 28 al_register_event_source(rotate_queue, al_get_keyboard_event_source()); 29 30 /* Load the bitmap which is to be rotated and the guide bitmap from 31 the configuration. */ 32 33 if( get_bitmaps(&bitmap_to_rotate, &guide_bitmap, "bitmap_to_rotate", "guide_bitmap", config) != 0) 34 { 35 cout << "Failed to load a bitmap from the configuration file while doing a rotate job.\n"; 36 return GENERAL_ABORT_FORCING_ERROR; 37 } 38 else 39 { 40 cout << "Loaded bitmaps for rotate job.\n"; 41 } 42 43 copy_bitmap = al_create_bitmap(SCREEN_WIDTH, SCREEN_HEIGHT); 44 if(copy_bitmap == NULL) 45 { 46 cout << "Couldn't create bitmap for copy_bitmap pointer.\n"; 47 return GENERAL_ABORT_FORCING_ERROR; 48 } 49 50 /* Draw a scaled version of the source bitmap to be rotated to 51 the screen sized bitmap copy_bitmap. */ 52 53 al_set_target_bitmap(copy_bitmap); 54 al_draw_scaled_bitmap(bitmap_to_rotate, 0, 0, al_get_bitmap_width(bitmap_to_rotate), al_get_bitmap_height(bitmap_to_rotate) , 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0); 55 56 /* Make the pixels which were specified to be translucent on the guide 57 bitmap actually translucent (0 for alpha component). */ 58 59 locked_region = al_lock_bitmap( guide_bitmap, ALLEGRO_PIXEL_FORMAT_RGBA_8888, ALLEGRO_LOCK_READWRITE ); 60 if(locked_region == NULL) 61 { 62 cout << "Couldn't lock the guide bitmap.\n\n"; 63 return GENERAL_ABORT_FORCING_ERROR; 64 } 65
66 for(x = 0; x < SCREEN_WIDTH; ++x)
67 { 68 for(y = 0; y < SCREEN_HEIGHT; ++y) 69 { 70 pixel_ptr = ((unsigned char *) locked_region->data) + locked_region->pitch * y + x * NUMBER_OF_BYTES_PER_PIXEL; 71 72 ri = (int) *(pixel_ptr + 3); 73 gi = (int) *(pixel_ptr + 2); 74 bi = (int) *(pixel_ptr + 1); 75 76 if(ri == 2044 && gi == 64 && bi == 2) 77 { 78 *((uint32_t *) pixel_ptr) = (uint32_t) 0x00000000; 79 } 80 else 81 { 82 new_pixel = (( unsigned char ) ri << 24) | (( unsigned char ) gi << 16 ) | ( (unsigned char) bi << 8 ) | ((unsigned char) 150); 83 84 *((uint32_t *) (pixel_ptr)) = new_pixel; 85 } 86 } 87 } 88 89 90 al_unlock_bitmap(guide_bitmap); 91 92 do 93 { 94 do 95 { 96 al_get_next_event(rotate_queue, &event); 97 98 switch(event.type) 99 { 100 case ALLEGRO_EVENT_KEY_DOWN: 101 switch(event.keyboard.keycode) 102 { 103 case ALLEGRO_KEY_ESCAPE: 104 finished = true; 105 break; 106 case ALLEGRO_KEY_S: 107 bitmap_to_save = al_create_bitmap((int) (al_get_bitmap_width(bitmap_to_rotate)*(cos(rotate_angle)+sin(rotate_angle))),(int) ((al_get_bitmap_height(bitmap_to_rotate)*cos(rotate_angle))+(al_get_bitmap_width(bitmap_to_rotate)*sin(rotate_angle)))); 108 if(bitmap_to_save == NULL) 109 { 110 cout << "Couldn't create bitmap to save.\n"; 111 return GENERAL_ABORT_FORCING_ERROR; 112 } 113 al_set_target_bitmap(bitmap_to_save); 114 al_clear_to_color(BLACK); 115 al_draw_rotated_bitmap(bitmap_to_rotate, al_get_bitmap_width(bitmap_to_rotate)/2,al_get_bitmap_height(bitmap_to_rotate)/2, al_get_bitmap_width(bitmap_to_save)/2, al_get_bitmap_height(bitmap_to_save)/2, rotate_angle, 0); 116 cout << "Saving bitmap.\n"; 117 al_save_bitmap("output.png", bitmap_to_save); 118 /* Clear up. */ 119 al_destroy_bitmap(bitmap_to_rotate); 120 al_destroy_bitmap(guide_bitmap); 121 al_destroy_bitmap(copy_bitmap); 122 al_destroy_bitmap(bitmap_to_save); 123 return BITMAP_SAVED; 124 case ALLEGRO_KEY_UP: 125 rotate_angle -= 0.002f; 126 break; 127 case ALLEGRO_KEY_DOWN: 128 rotate_angle += 0.002f; 129 break; 130 case ALLEGRO_KEY_Q: 131 guide_y -= 1; 132 break; 133 case ALLEGRO_KEY_A: 134 guide_y += 1; 135 break; 136 case ALLEGRO_KEY_O: 137 guide_x -= 1; 138 break; 139 case ALLEGRO_KEY_P: 140 guide_x += 1; 141 break; 142 } 143 break; 144 case ALLEGRO_EVENT_DISPLAY_CLOSE: 145 finished = true; 146 break; 147 } 148 149 make_display_target(); 150 al_clear_to_color(BLACK); 151 al_draw_rotated_bitmap(copy_bitmap, al_get_bitmap_width(copy_bitmap)/2, al_get_bitmap_height(copy_bitmap)/2, SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, rotate_angle, NO_FLAGS); 152 al_draw_bitmap(guide_bitmap, guide_x, guide_y, NO_FLAGS); 153 al_draw_textf(ttf, WHITE, 100, 650, ALLEGRO_ALIGN_CENTRE, "%f radians", rotate_angle); 154 al_flip_display(); 155 156 } while(!al_is_event_queue_empty(rotate_queue)); 157 158 } while(finished != true); 159 160 return ROTATE_ABORTED; 161}

#SelectExpand
1int change_mask_to_transparent_pixel(ALLEGRO_LOCKED_REGION *locked_region_1, ALLEGRO_LOCKED_REGION *locked_region_2, ALLEGRO_LOCKED_REGION *locked_region_3, int h1, int h2, int h3) 2{ 3 int r, g, b; 4 unsigned char *pixel_ptr; 5 int x = 0, y = 0; 6 7 if(locked_region_1 == NULL) return 1; 8 9 for(x = 0; x < locked_region_1->pitch >> 2; ++x) 10 { 11 for(y = 0; y < h1; ++y) 12 { 13 pixel_ptr = ((unsigned char *) locked_region_1->data) + locked_region_1->pitch * y + x * NUMBER_OF_BYTES_PER_PIXEL; 14 15 r = (int) *(pixel_ptr + 2); 16 g = (int) *(pixel_ptr + 1); 17 b = (int) *(pixel_ptr + 0); 18 19 if(r == 204 && g == 64 && b == 2) 20 { 21 *((uint32_t *) pixel_ptr) = (uint32_t) 0x00000000; 22 } 23 else 24 { 25 *(pixel_ptr + 3) = 150; 26 } 27 } 28 } 29 30 return 0; 31}

pmprog
Member #11,579
January 2010
avatar

To be honest, I'm kind of surprised the first works at all.

Line 72 pulls an unsigned char into an int, and on 76 you're comparing it to the value 2044... But even though it's now an int, the highest value you could ever pull would be 255.

Also, I don't know if it'll help, but I always use "ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE" when locking my region. The documentation states

Quote:

Like the version without _LE, but the component order is guaranteed to be red, green, blue, alpha. This only makes a difference on big endian systems, on little endian it is just an alias

Though I not sure what actually happens when using ALLEGRO_PIXEL_FORMAT_ABGR_8888 or ALLEGRO_PIXEL_FORMAT_ARGB_8888?

William Labbett
Member #4,486
March 2004
avatar

Thanks for your reply.

That 2044 should have been 204.

I had to edit the code of the first section and made a mistake.

pmprog
Member #11,579
January 2010
avatar

I'd be interested to know your results... In fact, you don't post your pixel format for the second section. Maybe you accidently selected a different format on your calls?

William Labbett
Member #4,486
March 2004
avatar

Thanks again.

I didn't post the pixel format for section either.

I presume by "I'd like to see your results." you want me to try with some of those

pixel formats you suggested. I'm happy to do so. Do I need to use one of the al_set….() functions?

pmprog
Member #11,579
January 2010
avatar

Line 59: ALLEGRO_PIXEL_FORMAT_RGBA_8888

It's up to you if you want to test, but it wouldn't surprise me if you were using a different format to lock the region for the second section

I think it's worth a try to set them all to ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE

William Labbett
Member #4,486
March 2004
avatar

Thanks. I realised what I did. I put ALLEGRO_LOCK_READWRITE for the pixel format when
I locked it in the code that calls the second section.

I've fixed that and put ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE for the pixel format for both of them and now the two ways of doing it do different things. Neither of them come out
how I need.

Is there a way to infer from ABGR what (ptr + 0), (ptr + 1), (ptr + 2), (ptr + 3)

point to. Is it the alpha component, the blue component, the green component and the red component in that order, as would seem intuitive?

pmprog
Member #11,579
January 2010
avatar

This is what I use, and never have a problem

#SelectExpand
1typedef struct PackedARGB 2{ 3 unsigned char r; 4 unsigned char g; 5 unsigned char b; 6 unsigned char a; 7} PackedARGB; 8 9 10 11 // Load source 12 ALLEGRO_BITMAP* b = al_load_bitmap(argv[1]); 13 ALLEGRO_LOCKED_REGION* r = al_lock_bitmap(b, ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE, ALLEGRO_LOCK_READONLY); 14 unsigned char* raw = (unsigned char*)r->data; 15 16 for (int y = 0; y < al_get_bitmap_height(b); y++) 17 { 18 for (int x = 0; x < al_get_bitmap_width(b); x++) 19 { 20 PackedARGB* p = (PackedARGB*)(raw + (y * r->pitch) + (x * r->pixel_size)); 21 22 // Values are: p->r, p->g, p->b, p->a 23 24 } 25 }

William Labbett
Member #4,486
March 2004
avatar

Thanks very much for the help.

It's working now and I understand it better.

pmprog
Member #11,579
January 2010
avatar

Good stuff. You're welcome

Go to: