Some help about 2D graphics

Hello everyone.

I am having problems learning about moving 2D bitmaps in my game. When i load some bitmaps and i begin to move them, the performance drops dramatically. I having problems when loading backgrounds too.

I had some problems before and you helped me, i am thankful for that, but i think the best help would be if you can tell me a good wiki or documentation about all it, so i can learn and not asking everytime i dont know what to do.

I tried looking in the web, but i cant find what i need, or it was an Allegro 4 wiki, and my English is not very good, so it makes me even harder. I need a begginer's guide or something like that, so i can fill the screen with moving objects :P

Thanks for reading.

Manveru said:

When i load some bitmaps and i begin to move them, the performance drops dramatically.

Yeah me too. I followed the bouncer tutorial for A5 and tried creating bitmaps in the teens and my machine nearly died. I think you need a faster machine.

Matthew Leverton

Are you loading the bitmaps after you create the display?

Johan Halmén

Perhaps you are moving the bitmaps every game loop. If your application runs say 200 loops per second and you add some bitmap moving there, it will get slow. Try to move the bitmaps only every 10th loop. If this helps, you're on the right way. Next step is to put timers in your game.

Edgar Reynaldo

This should not be a problem. With hardware accelerated drawing, you should be able to draw a background and at least a hundred sprites 60 times a second. Something else is going wrong.

Trent Gamblin

Show us some code.

Matthew Leverton

Oh, and don't load the bitmaps on every frame. :-/


My main function looks like this:

1const float FPS = 60; 2const int SCREEN_W = 800; 3const int SCREEN_H = 600; 4 5int main(void) 6{ 7 bool redraw = true; 8 9 al_init(); 10 al_init_image_addon(); 11 al_install_keyboard(); 12 13 ALLEGRO_DISPLAY *display = al_create_display(SCREEN_W, SCREEN_H);; 14 ALLEGRO_TIMER *timer = al_create_timer(1.0 / FPS); 15 ALLEGRO_EVENT_QUEUE *event_queue = al_create_event_queue(); 16 17 al_register_event_source(event_queue, al_get_display_event_source(display)); 18 al_register_event_source(event_queue, al_get_timer_event_source(timer)); 19 al_register_event_source(event_queue, al_get_keyboard_event_source()); 20 21 al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP); 22 al_start_timer(timer); 23 24 level lvl; 25 26 while(1) 27 { 28 ALLEGRO_EVENT ev; 29 al_wait_for_event(event_queue, &ev); 30 31 if(ev.type == ALLEGRO_EVENT_TIMER) redraw = true; 32 else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE || ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) break; 33 34 if(redraw && al_is_event_queue_empty(event_queue)) { 35 redraw = false; 36 al_clear_to_color(al_map_rgb(0,0,0)); 37 lvl.update(); 38 al_flip_display(); 39 } 40 } 41 42 al_destroy_timer(timer); 43 al_destroy_display(display); 44 al_destroy_event_queue(event_queue); 45 46 return 0; 47}

I load all the bitmaps in level constructor, and it draws all bitmaps every lvl.update().


If you edit that post and format it like
Insert code here
it will look nice and pretty for us, and save some vertical space:

1const float FPS = 60; 2const int SCREEN_W = 800; 3const int SCREEN_H = 600;int main(void) 4{ 5 bool redraw = true; 6 7 al_init(); 8 al_init_image_addon(); 9 al_install_keyboard(); ALLEGRO_DISPLAY *display = al_create_display(SCREEN_W, SCREEN_H);; 10 ALLEGRO_TIMER *timer = al_create_timer(1.0 / FPS); 11 ALLEGRO_EVENT_QUEUE *event_queue = al_create_event_queue(); al_register_event_source(event_queue, al_get_display_event_source(display)); 12 al_register_event_source(event_queue, al_get_timer_event_source(timer)); 13 al_register_event_source(event_queue, al_get_keyboard_event_source()); al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP); 14 al_start_timer(timer); level lvl; while(1) 15 { 16 ALLEGRO_EVENT ev; 17 al_wait_for_event(event_queue, &ev); 18 19 if(ev.type == ALLEGRO_EVENT_TIMER) redraw = true; 20 else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE || ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) break; 21 22 if(redraw && al_is_event_queue_empty(event_queue)) { 23 redraw = false; 24 al_clear_to_color(al_map_rgb(0,0,0)); 25 lvl.update(); 26 al_flip_display(); 27 } 28 } 29 30 al_destroy_timer(timer); 31 al_destroy_display(display); 32 al_destroy_event_queue(event_queue); 33 34 return 0; 35}

Edit: Let us see the code for lvl.update();


Thank you for the code boxing, i was asking how to do it ;D

I simplify the program to try to solve my problem: my lvl.update is only a X and Y movement and a al_draw_bitmap with the bitmap of the object.


If the constructor of level loads bitmaps then it might be getting called before the display is created, and therefore would have memory bitmaps instead of video bitmaps (I think). There are a few ways you could change this if that is the case: 1. Separate the bitmap loading into a separate function and call that after the display has been created or 2. Create lvl using new so that the constructor is called at that point (don't forget to delete it). The first option is probably the better choice.


I think i load the bitmaps after creating the display, i create lvl after. The code above is what i have now. I forgot i have the line <#include "level.h"> before the main, but i think the bitmaps dont load untill you call the constructor.

Edgar Reynaldo

Show the code for the level class, including the constructor and update functions.


My main.cpp code is:

1#include <allegro5/allegro.h> 2#include <allegro5/allegro_image.h> 3 4const float FPS = 60; 5const int SCREEN_W = 800; 6const int SCREEN_H = 600; 7 8#include "entity.h" 9#include "level.h" 10 11int main(void) 12{ 13 bool redraw = true; 14 15 al_init(); 16 al_init_image_addon(); 17 al_install_keyboard(); 18 19 ALLEGRO_DISPLAY *display = al_create_display(SCREEN_W, SCREEN_H);; 20 ALLEGRO_TIMER *timer = al_create_timer(1.0 / FPS); 21 ALLEGRO_EVENT_QUEUE *event_queue = al_create_event_queue(); 22 23 al_register_event_source(event_queue, al_get_display_event_source(display)); 24 al_register_event_source(event_queue, al_get_timer_event_source(timer)); 25 al_register_event_source(event_queue, al_get_keyboard_event_source()); 26 27 al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP); 28 al_start_timer(timer); 29 30 level lvl; 31 32 while(1) 33 { 34 ALLEGRO_EVENT ev; 35 al_wait_for_event(event_queue, &ev); 36 37 if(ev.type == ALLEGRO_EVENT_TIMER) redraw = true; 38 else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE || ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) break; 39 40 if(redraw && al_is_event_queue_empty(event_queue)) { 41 redraw = false; 42 al_clear_to_color(al_map_rgb(0,0,0)); 43 lvl.update(); 44 al_flip_display(); 45 } 46 } 47 48 al_destroy_timer(timer); 49 al_destroy_display(display); 50 al_destroy_event_queue(event_queue); 51 52 return 0; 53}

This is the code of level.h:

1class level 2{ 3private: 4 entity *e1, *e2, *e3, *background; 5 ALLEGRO_BITMAP *Se1, *Se2, *Se3, *Sbackground; 6 float angle[3]; 7 8public: 9 level(); 10 ~level(); 11 12 void update(); 13}; 14 15level::level() 16{ 17 Se1 = al_load_bitmap("Sprites/Se1.png"); // 18 Se2 = al_load_bitmap("Sprites/Se2.png"); // A 100x150 bitmap. 19 Se3 = al_load_bitmap("Sprites/Se3.png"); // 20 Sbackground = al_load_bitmap("Sprites/Background.png"); // A 800x600 background 21 22 e1 = new entity(100, 300, Se1); 23 e2 = new entity(300, 300, Se2); 24 e3 = new entity(500, 300, Se3); 25 angle[0] = angle[1] = angle[2] = 0; 26 background = new entity(0, 0, Sbackground); 27} 28 29level::~level() 30{ 31 al_destroy_bitmap(Se1); 32 al_destroy_bitmap(Se2); 33 al_destroy_bitmap(Se3); 34 al_destroy_bitmap(Sbackground); 35} 36 37void level::update() 38{ 39 const float radius = 50, PI = 3.14159265; 40 41 background->draw(); 42 43 e1->set_x(150 + (cos(angle[0]*PI/180) * radius)); 44 e1->set_y(300 + (sin(angle[0]*PI/180) * radius)); 45 angle[0] = (int)(angle[0] + 3) % 360; 46 e1->draw(); 47 48 e2->set_x(350 + (cos(angle[1]*PI/180) * radius)); 49 e2->set_y(300 + (sin(angle[1]*PI/180) * radius)); 50 angle[1] = (int)(angle[1] + 3) % 360; 51 e2->draw(); 52 53 e3->set_x(550 + (cos(angle[2]*PI/180) * radius)); 54 e3->set_y(300 + (sin(angle[2]*PI/180) * radius)); 55 angle[2] = (int)(angle[2] + 3) % 360; 56 e3->draw(); 57}

And the entity.h code:

1class entity 2{ 3private: 4 float x, y; 5 ALLEGRO_BITMAP *sprite; 6public: 7 entity(float px, float py, ALLEGRO_BITMAP *s) 8 { 9 x = px; 10 y = py; 11 sprite = s; 12 } 13 14 void set_x(float px) { x = px; } 15 float get_x() { return x; } 16 void set_y(float py) { y = py; } 17 float get_y() { return y; } 18 19 void draw() { al_draw_bitmap(sprite, x, y, 0); } 20};

With the line 'background->draw()' disabled the movement is slow, but with it enabled the movement is about 1 FPS. With only 1 of 3 of the entities the movement is good.

Edgar Reynaldo

Well, I'm not sure what's going wrong here. You create the display, then you make a level object, which loads all your images and creates entities from them. Then you clear and draw your background and sprites every time the timer ticks. That should all be working much faster than you say it is.

Manveru said:

With the line 'background->draw()' disabled the movement is slow, but with it enabled the movement is about 1 FPS. With only 1 of 3 of the entities the movement is good.

So, disabling the background drawing or reducing the number of entities to 1 both speed up the drawing? ??? Some or all of the bitmaps you loaded must be memory bitmaps. I don't know why they would be, since you used the ALLEGRO_VIDEO_BITMAP flag before loading (and it's the default anyway). Check to make sure using al_get_bitmap_flags.

Oh, and if your background covers the display (and it is solid), you don't need to clear the display then.

You could try updating your graphics drivers and see if that helps.


Thanks for your help, but it continues the same way. I update the graphics drivers, i use al_get_bitmap_flags and all bitmaps returns 1024 (ALLEGRO_VIDEO_BITMAP value) and i have tried ALLEGRO_MEMORY_BITMAP (it is suposed to be slower) and i got the same slow speed.

My graphics card is a NVIDIA GEFORCE FX 5200 with 128mb, and old one but i think it should be enough.

Edgar Reynaldo

Yeah, your GFX card should definitely be capable of handling a background and 3 sprites.

Try running ex_draw_bitmap from the allegro binaries examples and play with the parameters a bit. See how many sprites you can draw with it before it slows down. If it works, then there is something else wrong. Do any other games / applications exhibit this behaviour on your computer?


I ran ex_draw_bitmap: i get 3FPS with 1 bitmap, 2FPS with 2 or 3 and 1FPS with 4+. Changing alpha blending or the texture do not change the results (change size to 1 with only 1 bitmap returns 5FPS).

I do not understand. Im working in another game, a shot'em up one, with a ship and some bullets and enemies in the screen (no background yet) and it is just a bit slow when the screen is full of objects. I copied the main.cpp code of this game to my actual new game, the one that gives me this problem. Maybe it is because in the first game the bitmaps are small, but in the ex_draw_bitmap they are small too...

Matthew Leverton

Have you attached allegro.log anywhere that shows your video modes, etc?


Take a look to it, thanks

EDIT: I had been trying to solve the problem all the morning, trying some changes, but i can´t solve it. I tried an animation and it was ok, fast and very fast if i put 120FPS, but when i began to move the bitmap horizontally it was slow again.
I run the other game i am working on, and it is a bit slow too. I didnt remember before but i usually write in C++ and Allegro in my notebook, and there it was ok. Now in my PC i get this slow speed with bitmap movements.

Before i try C++ with Allegro, i programed in Fenix/Bennu and now i am taking these games to C++. When i run my old games in Bennu, they are ok, perfect speed, so i think it is not a problem of my computer. Anyway, my computer is: AMD 3200 2GHZ, 2GB DDR and NVIDIA GEFORE 5200 128MB (drivers updated to last version). I have DirectX 9.0c, and i dont know if it has something more that should be important.

I still need your help. Without it i am lost and i am sorry for that but i would have to leave Allegro and try other libraries.

Thread #609328. Printed from