Question on increasing "render" speed
djtschke

Hello everbody,

I am quite new to C++ and Allegro and started by following this tutorial Demoscene C++ Allegro Tutorial. I was even able to convert the code to Allegro Version 5 and everything worked fine. Then I started on the task with the snow piling up (at the bottom part of the Tutorial). After a while I also managed to solve this task. Now my problem is that the application is running very slow as you will see if you compile it by yourself. I guess this is because I am working with a Bitmap. My question now is how can I speed up the whole application ?

Here is the code:

#SelectExpand
1#include <stdio.h> 2#include <math.h> 3#include <allegro5/allegro.h> 4 5using namespace std; 6 7// data structures for snow flaxes = very simple 8const int total_flakes=900; 9const int total_layers=3; 10 11struct particle 12{ 13 int x,y; 14 int layer; 15}; 16 17// global data - okay for a simple example like this 18particle flakes[total_flakes]; 19particle lyingFlakes[total_flakes]; 20 21// This function initalizes the particle flakes 22void initalize_particle_flakes(void) 23{ 24 int i; 25 for (i=0;i<total_flakes;i++) 26 { 27 flakes[i].x=rand()%320; // 0-319 [x] 28 flakes[i].y=rand()%200; // 0-199 [y] 29 flakes[i].layer=rand()%total_layers;// [0-2] [layer] 30 31 lyingFlakes[i].x = ceilf((i / 2.8125)); 32 lyingFlakes[i].y = 199; 33 } 34} 35 36void check_for_piling(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *haufen) { 37 for (int i=0;i<total_flakes;i++) 38 { 39 ALLEGRO_COLOR particelColor = al_map_rgb(255,255,255); 40 ALLEGRO_COLOR pixelColor = al_get_pixel(haufen,flakes[i].x, flakes[i].y); 41 42 if((particelColor.r == pixelColor.r) && (particelColor.g == pixelColor.g) && (particelColor.b == pixelColor.b)) { 43 // if((flakes[i].y >= 199)) { 44 al_set_target_bitmap(haufen); 45 al_put_pixel(flakes[i].x, (flakes[i].y - 1), particelColor); 46 al_set_target_bitmap(al_get_backbuffer(display)); 47 al_draw_bitmap(haufen, 0.0, 0.0, 0); 48 al_flip_display(); 49 // } 50 } 51 } 52} 53 54// This function draws all the particle flakes 55void draw_particle_flakes(ALLEGRO_DISPLAY *display) 56{ 57 int i; 58 59 for (i=0;i<total_flakes;i++) 60 { 61 al_put_pixel(flakes[i].x, flakes[i].y, al_map_rgb(255,255,255)); 62 } 63} 64 65// This updates the particle flakes 66void update_particle_flakes(ALLEGRO_DISPLAY *display) 67{ 68 int i; 69 70 for (i=0;i<total_flakes;i++) 71 { 72 ALLEGRO_COLOR pixelColor = al_get_pixel(al_get_backbuffer(display),flakes[i].x, flakes[i].y); 73 ALLEGRO_COLOR particelColor = al_map_rgb(255,255,255); 74 75 // drop the particle down - depending on layer 76 // [plus one - since layer zero would result 77 // in no motion otherwize] 78 flakes[i].y+=flakes[i].layer+1; 79 80 // check for wrap around 81 if (flakes[i].y>199) 82 { 83 flakes[i].x=rand()%320; 84 flakes[i].y=0; 85 flakes[i].layer=rand()%total_layers; 86 } 87 88 // new x position 89 flakes[i].x=(flakes[i].x+(2-rand()%5)) % 320; 90 } 91} 92 93void update_display(ALLEGRO_DISPLAY *display) { 94 update_particle_flakes(display); 95 al_clear_to_color(al_map_rgb(0,0,0)); 96 draw_particle_flakes(display); 97 al_flip_display(); 98} 99 100// main program 101int main(int argc, char *argv[]) { 102 int i; 103 104 al_init(); // init Allegro 105 al_install_keyboard(); // setup allegro keyboard 106 107 ALLEGRO_DISPLAY *display = NULL; 108 display = al_create_display(320, 200); 109 110 ALLEGRO_BITMAP *haufen = NULL; 111 haufen = al_create_bitmap(320, 200); 112 113 ALLEGRO_EVENT_QUEUE *event_queue = NULL; 114 event_queue = al_create_event_queue(); 115 116 al_register_event_source(event_queue, al_get_display_event_source(display)); 117 118 ALLEGRO_EVENT ev; 119 ALLEGRO_TIMEOUT timeout; 120 al_init_timeout(&timeout, 0.06); 121 122 bool got_event = al_wait_for_event_until(event_queue, &ev, &timeout); 123 124 ALLEGRO_COLOR white = al_map_rgb(255,255,255); 125 126 initalize_particle_flakes(); 127 128 al_set_target_bitmap(haufen); 129 for (i=0;i<total_flakes;i++) { 130 al_put_pixel(lyingFlakes[i].x, lyingFlakes[i].y, al_map_rgb(255,255,255)); 131 } 132 al_set_target_bitmap(al_get_backbuffer(display)); 133 al_draw_bitmap(haufen, 0.0, 0.0, 0); 134 al_flip_display(); 135 136 while (true) { 137 update_display(display); 138 check_for_piling(display, haufen); 139 }; 140 141 return 0; 142}

best regards and many thanks for any help !

djtschke

jmasterx

Putting pixels is expensive in A5 and likely your bottleneck. Look into bitmap locking or blit your particle to a bitmap then draw that bitmap instead with al_hold_bitmap_drawing set to true.

djtschke

I already looked into the al_lock_bitmap() function and experimented a bit. But it didn't really help anything. Also I must confess I didn't quite get the clue of how that function works.

best regards,

djtschke

jmasterx

Then try the other method. create a new bitmap, set it as the target bitmap, draw your pattern, then set the target back to the back buffer, now instead of calls to al_draw_pixel, right before the for loop call:

al_hold_bitmap_drawing(true);

then in your for loop, draw the bitmap.
then after the for loop call:

al_hold_bitmap_drawing(false);

SiegeLord

Try al_draw_prim with ALLEGRO_PRIM_POINT_LIST and a custom vertex declaration (see ex_prim example).

North~

A bit off-topic but that's a horrible gap in the tutorial I see. It goes from basically the smallest possible allegro program to a slightly extensive particle snow tutorial.

weapon_S

Very much off-topic:

Tutorial said:

I run my laptop at 60hz, but my PC at 120.

Yesterday I discovered my CRT monitor had a 120Hz mode ;D
I didn't know of al_draw_prim. Interesting. How do you define colour when using NULL as a texture?

SiegeLord

ALLEGRO_VERTEX has a color parameter. Custom vertex declarations also have a method to specify the color.

Thread #608009. Printed from Allegro.cc