Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » [A5] pixel alpha // al_put_pixel() ?! game loop

This thread is locked; no one can reply to it. rss feed Print
[A5] pixel alpha // al_put_pixel() ?! game loop
Alon3k
Member #15,476
January 2014

Could anyone explain to me why is this happening?

When I have "ALLEGRO_BITMAP* image" stored in main.cpp and I use code:

#SelectExpand
1if(buttonLeft) 2{ 3 al_lock_bitmap(image, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_WRITEONLY); 4 5 al_set_target_bitmap(image); 6 7 al_put_pixel(mouseX,mouseY,al_map_rgba(255,255,255,255)); 8 9 al_unlock_bitmap(image); 10 11 al_set_target_bitmap(al_get_backbuffer(Display)); 12 13 buttonLeft = false; 14}

Bitmap pixel is modified and it works perfectly fine bit slow but fine.

But when I store the bitmap in the class Terrain and I call this method

#SelectExpand
2 3void Map::removePixel(float x, float y) 4{ 5al_lock_bitmap(image, al_get_bitmap_format(image), ALLEGRO_LOCK_WRITEONLY); 6 7al_set_target_bitmap(image); 8 9al_put_pixel(x,y,al_map_rgba(255,255,255,255)); // Set to white for testing 10 11al_unlock_bitmap(image); 12}

and the main call

#SelectExpand
3if(buttonRight) 4{ 5terrain->removePixel(mouseX,mouseY); 6 7al_set_target_bitmap(al_get_backbuffer(Display)); 8 9buttonRight = false; 10}

Nothing happens any idea why ?? Actually game stops stops for a bit

this is my game loop logic:

#SelectExpand
4while(game != DONE) 5{ 6process_events(); 7 8while(consecutive_logic_updates-- > 0) 9{ 10// LOGIC UPDATES KEY INPUT, COLLISION, AI etc. 11} 12 13while(render_frame) 14{ 15render_frame = false; 16// DRAW EVERYTHING 17 al_flip_display(); // Flip display to show everything that has been drawn 18 al_clear_to_color(al_map_rgba(0,0,0,0)); 19} 20} 21 22 23// Process events method 24void process_events() 25{ 26 ALLEGRO_EVENT allegro_event; 27 28 bool got_event; 29 while (got_event = al_get_next_event(event_queue, &allegro_event)) 30 { 31 if(got_event && allegro_event.type == ALLEGRO_EVENT_KEY_DOWN) 32 { 33 switch(allegro_event.keyboard.keycode) 34 { 35 case ALLEGRO_KEY_ESCAPE: keys_pressed[KEY_ESCAPE] = true; 36 break; 37 case ALLEGRO_KEY_RIGHT: keys_pressed[KEY_RIGHT] = true; 38 break; 39 case ALLEGRO_KEY_LEFT: keys_pressed[KEY_LEFT] = true; 40 break; 41 case ALLEGRO_KEY_DOWN: keys_pressed[KEY_DOWN] = true; 42 break; 43 case ALLEGRO_KEY_UP: keys_pressed[KEY_UP] = true; 44 break; 45 } 46 } 47 else if(got_event && allegro_event.type == ALLEGRO_EVENT_KEY_UP) 48 { 49 switch(allegro_event.keyboard.keycode) 50 { 51 case ALLEGRO_KEY_ESCAPE: keys_pressed[KEY_ESCAPE] = false; 52 break; 53 case ALLEGRO_KEY_RIGHT: keys_pressed[KEY_RIGHT] = false; 54 break; 55 case ALLEGRO_KEY_LEFT: keys_pressed[KEY_LEFT] = false; 56 break; 57 case ALLEGRO_KEY_DOWN: keys_pressed[KEY_DOWN] = false; 58 break; 59 case ALLEGRO_KEY_UP: keys_pressed[KEY_UP] = false; 60 break; 61 } 62 } 63 else if(got_event && allegro_event.type == ALLEGRO_EVENT_MOUSE_AXES) 64 { 65 mouseX = allegro_event.mouse.x; 66 mouseY = allegro_event.mouse.y; 67 } 68 else if(got_event && allegro_event.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) 69 { 70 if(allegro_event.mouse.button & 1) buttonLeft = true; 71 else if(allegro_event.mouse.button & 2) buttonRight = true; 72 } 73 else if(got_event && allegro_event.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP) 74 { 75 if(allegro_event.mouse.button & 1) buttonLeft = false; 76 else if(allegro_event.mouse.button & 2) buttonRight = false; 77 } 78 } 79 80 if(LogicState == STATE_RENDER) 81 { 82 al_flush_event_queue(timer_event_queue); 83 render_frame = true; 84 LogicState = STATE_LOGIC; 85 } 86 else 87 { 88 consecutive_logic_updates = 0; 89 90 while( al_get_next_event(timer_event_queue, &allegro_event) ) 91 { 92 consecutive_logic_updates++; 93 LogicState = STATE_RENDER; 94 } 95 }

Any ideas or what can I chance improve? thanks!

Edgar Reynaldo
Member #8,592
May 2007
avatar

One thing you need to be aware of is that when you lock an entire bitmap as ALLEGRO_LOCK_WRITEONLY, then you need to write to every pixel in the locked region. That is why you should only lock the region you are interested in.

ALLEGRO_LOCK_WRITEONLY - The locked region will not be read from. This can be faster if the bitmap is a video texture, as no data need to be read from the video card. You are required to fill in all pixels before unlocking the bitmap again, so be careful when using this flag.

And I'm not sure about this, but I think you want to set the bitmap target before you lock it to draw your pixel.

Alon3k said:

while (render_frame) {
   render_frame = false;
   // draw
}

An if statement would be more appropriate, as you only want to draw once.

As for general programming practices I think you're overcomplicating things by using more than one event queue. Just register your timer to your main event queue. Process all events at once, including timer events, and when you get a timer event run your logic. Then draw, and then wait until you get another event.

Alon3k
Member #15,476
January 2014

Thanks for the answer it didn't help but I found the mistake.

As I was using two bitmaps one "image" second "locked" and both were pointers to two allegro bitmap my idea was to use " locked" as copy of image so that I don't have to call lock bitmap unlock each time I want to check the pixel.

Problem is both were pointers so when I set locked = image; I made a copy of a pointer that was pointing to the same bitmap while "locked" was locked in the constructor as READONLY causing the problem :x

Is there any way to copy data that pointer points to to another pointer without making it point to the same data file bitmap in this case? Assuming they both point to a different bitmap at the start and I want to make a copy of it which would save a lot of trouble I could have one that is always locked and I would read from it to preform checks while only time I would unlock it would be when some change was done and large amount of pixels changed.

Edgar Reynaldo
Member #8,592
May 2007
avatar

Alon3k
Member #15,476
January 2014

NVM GOT IT ;d al_clone ;d

Go to: