|
One function call cuts my FPS in half |
sadelbrid
Member #15,200
June 2013
|
I am trying to narrow down why my fps is so low. After messing around, I found that my fps drops in half when calling a function. I then went into that function and commented out everything and kept rerunning my program while putting back each line one at a time. Everything was running at 60 fps... until I added one drawing function: al_draw_bitmap_region(player.graphic, 0, player.direction, 26, 26, player.x - 13, player.y - 13, NULL); This is just a 26x104 bitmap of my player sprite. This drawing function cuts my fps from 60 to 30. However the fps doesn't drop when I draw a primitive instead. Any thoughts? |
Edgar Reynaldo
Major Reynaldo
May 2007
|
Make sure you load all your graphics after you create your display otherwise they will be memory bitmaps. That's the major reason a bitmap would draw slowly in A5. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
sadelbrid
Member #15,200
June 2013
|
I create my display before anything else. I pulled the player sprite graphic out of the player struct and declared it in my main function. As expected, that didn't change anything. |
SiegeLord
Member #7,827
October 2006
|
To be 100% sure it's not a memory bitmap, try calling al_get_bitmap_flags(player.graphic) & ALLEGRO_VIDEO_BITMAP and making sure that's not zero. "For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18 |
sadelbrid
Member #15,200
June 2013
|
Calling al_get_bitmap_flags(playerSprite) & ALLEGRO_VIDEO_BITMAP returned 1. If that is how you check, it seems that it isn't a memory bitmap. To be sure, I called al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP) at the beginning of my program. |
Gideon Weems
Member #3,925
October 2003
|
sadelbrid
Member #15,200
June 2013
|
Here is my declaration and my gameloop 1al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP);
2//...
3ALLEGRO_BITMAP *playerSprite = al_load_bitmap("player.png");
4//...
5while(!done)
6 {
7 ALLEGRO_EVENT ev;
8 al_wait_for_event(queue, &ev);
9 if(ev.type == ALLEGRO_EVENT_TIMER)
10 {
11 if(ev.timer.source == mainTimer)
12 {
13 draw = true;
14 if(inputs[W]){player.y -= player.speed; player.direction = UP; player.imageX -= 32;}
15 else if(inputs[S]){player.y += player.speed; player.direction = DOWN; player.imageX -= 32;}
16 else if(inputs[A]){player.x -= player.speed; player.direction = LEFT; player.imageX -= 32;}
17 else if(inputs[D]){player.x += player.speed; player.direction = RIGHT; player.imageX -= 32;}
18
19
20 if(player.imageX < 0){player.imageX = 64;}
21
22 //Bounds checking
23 if (player.x > al_get_bitmap_width(environment)){player.x = al_get_bitmap_width(environment);}
24 else if (player.x < 0){player.x = 0;}
25 if (player.y < 0){player.y = 0;}
26 else if (player.y > al_get_bitmap_height(environment)){player. y = al_get_bitmap_height(environment);}
27
28 HitDetect(player);
29 cloud1x -= 1;
30 cloud2x -= 1;
31 if(cloud1x < -4000){cloud1x = 4000;}
32 if(cloud2x < -4000){cloud2x = 4000;}
33 }
34
35 else if (ev.timer.source == waterTimer)
36 {
37 waterdraw = true;
38 waterUpdateNeeded = true;
39 waterX += 32;
40 if (waterX > 96){waterX = 0;}
41 }
42 }
43
44 else if (ev.type == ALLEGRO_EVENT_KEY_DOWN)
45 {
46 switch (ev.keyboard.keycode)
47 {
48 case ALLEGRO_KEY_W:
49 inputs[W] = true;
50 break;
51 case ALLEGRO_KEY_S:
52 inputs[S] = true;
53 break;
54 case ALLEGRO_KEY_A:
55 inputs[A] = true;
56 break;
57 case ALLEGRO_KEY_D:
58 inputs[D] = true;
59 break;
60 case ALLEGRO_KEY_SPACE:
61 inputs[SPACE] = true;
62 break;
63 case ALLEGRO_KEY_I:
64 inputs[I] = true;
65 inventoryon = !inventoryon;
66
67 break;
68 case ALLEGRO_KEY_ESCAPE:
69 done = true;
70 break;
71 }
72 }
73 else if (ev.type == ALLEGRO_EVENT_KEY_UP)
74 {
75 switch (ev.keyboard.keycode)
76 {
77 case ALLEGRO_KEY_W:
78 inputs[W] = false;
79 break;
80 case ALLEGRO_KEY_S:
81 inputs[S] = false;
82 break;
83 case ALLEGRO_KEY_A:
84 inputs[A] = false;
85 break;
86 case ALLEGRO_KEY_D:
87 inputs[D] = false;
88 break;
89 case ALLEGRO_KEY_SPACE:
90 inputs[SPACE] = false;
91 break;
92 case ALLEGRO_KEY_I:
93 inputs[I] = false;
94 break;
95 }
96 }
97
98 else if (ev.type == ALLEGRO_EVENT_MOUSE_AXES)
99 {
100 maincurser.x = ev.mouse.x;
101 maincurser.y = ev.mouse.y;
102 }
103
104 else if (ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN)
105 {
106
107 }
108
109 if(draw && al_is_event_queue_empty(queue))
110 {
111 //-------------------FPS--------------------------
112 double game_time = al_get_time();
113 if(game_time - old_time >= 1.0)
114 {
115 fps = frames_done / (game_time - old_time);
116 frames_done = 0; old_time = game_time;
117 }
118 frames_done++;
119 cout << fps << endl;
120 //--------------------------------------------------
121 draw = false;
122 //Redraw
123 RedrawEnvironment(environment, water, sand, stone, grass, grassSide, sandSide, waterX, tree, player, trees, blocks, waterdraw, waterUpdateNeeded);
124 RedrawOverlay(overlay, clouds, playerSprite, player, cloud1x, cloud2x, maincurser);
125
126 //Draw Camera/HUD
127 DrawScreen(display, player, screen, environment, overlay);
128
129 //if(inventoryon){DrawInventory(readyBoxes, selficon, display, inventorybox);}
130 al_draw_bitmap(maincurser.graphic, maincurser.x - al_get_bitmap_width(maincurser.graphic)/2,
131 maincurser.y - al_get_bitmap_height(maincurser.graphic)/2, NULL);
132
133 al_flip_display();
134 al_clear_to_color(al_map_rgb_f(0,0,0));
135 }
136 }
When I call RedrayOverlay(), that is when the fps drops. RedrawOverlay() looks like this: void RedrawOverlay(ALLEGRO_BITMAP *&overlay, ALLEGRO_BITMAP *&clouds, ALLEGRO_BITMAP *&playerSprite, Player &player, int cloud1x, int cloud2x, Mouse maincurser) { al_set_target_bitmap(overlay); al_clear_to_color(al_map_rgba_f(0,0,0,0)); al_draw_bitmap_region(playerSprite, 0, player.direction, 26, 26, player.x - 13, player.y - 13, NULL); //al_draw_filled_circle(player.x, player.y, 3, al_map_rgb_f(1,0,1)); //al_draw_bitmap_region(clouds, , , WIDTH, HEIGHT, 0, 0, NULL); //al_draw_bitmap(clouds, cloud2x, 0, NULL); } The al_draw_bitmap_region() is what makes the frame drop. EDIT: After more testing, I found that most my drawing functions drop the frame rate significantly. However, drawing to the screen does not seem to affect it. |
beoran
Member #12,636
March 2011
|
Let me guess, the overlay is a memory bitmap? Drawing to memory bitmaps is also relatively slow... |
Edgar Reynaldo
Major Reynaldo
May 2007
|
There's got to be something more going on here. Drawing a single sprite should never drop your fps from 60 to 30 if it is hardware accelerated. Are you sure all your bitmaps are loaded after the display is created? Your overlay could be a memory bitmap which would explain the slow drawing to it. There's got to be some other explanation. I don't mind looking at the rest of your source code if you want to post it. Zip files are best. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
sadelbrid
Member #15,200
June 2013
|
Okay here is my project folder. |
sadelbrid
Member #15,200
June 2013
|
Well I made an overlay for the hud, player, mobs, and other objects and use environment for things that would not change very often. I made it the same size as environment to avoid some math when drawing. I'll change it and let you know how it goes. |
Edgar Reynaldo
Major Reynaldo
May 2007
|
The general paradigm nowadays is just to blast everything through the video card on every frame. And you can usually get away with it too. But I understand your desire to minimize excess drawing, it's only natural. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
sadelbrid
Member #15,200
June 2013
|
I eliminated the giant 4000x4000 bitmaps and recoded the drawing functions to draw the tiles one at a time and now it's running at 60 fps! Thanks! |
Chris Katko
Member #1,881
January 2002
|
Edgar Reynaldo said: So your overlay texture is 4000 x 4000. That is likely too large of a texture for your graphics card to allocate. Though, for modern systems (*not crappy tablets), it shouldn't be unless perhaps you're trying to update the entire thing by drawing individual tiles to it (including wasting time drawing off the screen boundaries.) That is, it's a throughput limit, not a hardware specification limitation. Any card supporting OpenGL 4.1, for example, is required to support 16,384 x 16,384 as the lowest "maximum texture size" of a card. Which is 16384^2 * 32-bits / 1024 / 1024 / 1024 = 1 GB if uncompressed! There are some that list 2-D texture size at 64Kx64K! The future is amazing. -----sig: |
|