Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Some help about 2D graphics

This thread is locked; no one can reply to it. rss feed Print
Some help about 2D graphics
Manveru
Member #13,535
September 2011

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.

verthex
Member #11,340
September 2009
avatar

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
Supreme Loser
January 1999
avatar

Are you loading the bitmaps after you create the display?

Johan Halmén
Member #1,550
September 2001

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.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Years of thorough research have revealed that the red "x" that closes a window, really isn't red, but white on red background.

Years of thorough research have revealed that what people find beautiful about the Mandelbrot set is not the set itself, but all the rest.

Edgar Reynaldo
Member #8,592
May 2007
avatar

Trent Gamblin
Member #261
April 2000
avatar

Show us some code.

Matthew Leverton
Supreme Loser
January 1999
avatar

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

Manveru
Member #13,535
September 2011

My main function looks like this:

#SelectExpand
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().

Felix-The-Ghost
Member #9,729
April 2008
avatar

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

#SelectExpand
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();

==========================
<--- The ghost with the most!
---------------------------
[Website] [Youtube]

Manveru
Member #13,535
September 2011

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.

someone972
Member #7,719
August 2006
avatar

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.

______________________________________
As long as it remains classified how long it took me to make I'll be deemed a computer game genius. - William Labbett
Theory is when you know something, but it doesn't work. Practice is when something works, but you don't know why. Programmers combine theory and practice: Nothing works and they don't know why. -Unknown
I have recklessly set in motion a chain of events with the potential to so-drastically change the path of my life that I can only find it to be beautifully frightening.

Manveru
Member #13,535
September 2011

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
Member #8,592
May 2007
avatar

Manveru
Member #13,535
September 2011

My main.cpp code is:

#SelectExpand
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:

#SelectExpand
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:

#SelectExpand
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
Member #8,592
May 2007
avatar

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.

Manveru
Member #13,535
September 2011

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
Member #8,592
May 2007
avatar

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?

Manveru
Member #13,535
September 2011

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
Supreme Loser
January 1999
avatar

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

Manveru
Member #13,535
September 2011

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.

Go to: