Need some tips to make fast allegro programs
anon176

So, I'm developing allegro 5. I know pretty much already and I was making a game but I noticed that the program starts to get very slow, maybe I'm doing some stupid thing that consumes too much memory/fetch time etc... I don't know.

Anyway, I just need a tutorial or some advices on what to do, which details on the code to pay attention to make it run fast and lean.

Thanks.

beoran

Most important performance tip for Allegro is to load all your bitmaps AFTER initializing the screen, otherwise they will be loaded as slow memory bitmaps, not fast screen bitmaps. For more tips, we'd need to see some of your code, if you are willing to share it.

anon176

Well, yes, I'll post a template of my project with the most significant parts:

I have three main headers
a "common" header that #includes all of the libraries that both main.cpp and other_files.cpp have access, like

#include <stdio.h>
#include <stdlib.h>
#include <allegro.h>
#include <allegro5/allegro_image.h>
#include "my_headers.h"
...
etc

The first lines of main are the inicialization of allegro and the display

right after, I load the map reading a 500x500 .png file and converting each pixel into a data in a int[500][500] matrix, each int is a correspondence to a 32x32 tile.

The function that draws the map onto display:
void draw_map_reg(int mapa[][MAX_MAP_SIZE], int desloc_x, int desloc_y, ALLEGRO_BITMAP* tiles); where mapa is the int matrix quoted, and *tiles is a bitmap that contains 32x32 pixels tiles, desloc_x and y are the offset.

for(i = 0 ; i < NUM_BLOCK_X ; i++)
{
for(j = 0 ; j < NUM_BLOCK_Y+1 ; j++)
{
if(i+desloc_x<MAX_MAP_SIZE && j+desloc_y<MAX_MAP_SIZE && i+desloc_x >= 0 && j+desloc_y>=0)
desenha_tile(tiles, mapa[i+desloc_x][j+desloc_y], i, j);
}
}

the if statement within is to avoid accessing the matrix outside its limits. The desenha_tile stands for draw_a_tile, it is a switch between the value of mapa[i+desloc_x][j+desloc_y]. For example:
case 0:
al_draw_bitmap_region(tiles, GRAMA1, BLOCK_SIZE, BLOCK_SIZE, i*BLOCK_SIZE, j*BLOCK_SIZE, 0);
mapa[i+desloc_x][j+desloc_y]
Where GRAMA1 is a macro like:
#define GRAMA1 3 * BLOCK_SIZE , 1 * BLOCK_SIZE
it gets the region of the bitmap where the tile is.

I think the main thing is printing the map, the other stuff done is just printing a player with a sprite, also using draw_bitmap_region

Btw, thanks for the help man. What can I do to make things run faster on the code?

beoran

I'm not sure but it looks like you're drawing the entire 500x500 tile map of 32x32 tiles giving you a whopping 16000x16000 pixels to be drawn. That's bound to be slow. You need to only draw the tiles that are actually visible on the screen!

Secondly it's not a great idea to use a (png) image file for storing tile map data. You could for example use the .tmx map format of tiled (http://www.mapeditor.org/), which will also make the tile map easier to edit. That's what I do in my RPG engine/game at least.

anon176

Ok, I'll fix it. What else can I do? My Graphics Routines are all like:
create *bitmap, set it using al_load_bitmap, then I start using it later. Where to use parallelism on the code, etc...?

beoran

Normally I would load all graphics after opening the screen but before starting the drawing loop, normally when a new "level" is loaded. I wouldn't do too much loading while the game play is ongoing to avoid slowdowns.

anon176

Ok. I've just saw your engine on github, great job man! ;)

beoran

You're welcome, and also welcome to use my engine if you like, as long as you respect the license. :)

anon176

So, I decided to build my own "tiled" because I thought it would be easy. It happens that I'm having the same problems I had with the main game: very slow processing. I don't think that is my computer is fucked up since I run many heavy games without problem... Anyway, I'll post the whole code of the "map maker" on the attachments for you to see, maybe you can help me find wtf is making it run so slow... ???

Thomas Fjellstrom

If you're not using texture atlasing, you should. Especially for tile based graphics. It's rather important.

taronĀ 
anon176 said:

It happens that I'm having the same problems I had with the main game: very slow processing

What do you mean by slow? Low framerate?

You might want to change this

if(draw)

to

if (draw && al_is_event_queue_empty(fila_de_eventos))

Also use al_hold_bitmap_drawing if you use the same bitmap many times in a row. This will improve performance although even without you shouldn't run into performance problems quickly.

anon176

By slow I just mean that it is taking too much time to answer. I put this al_hold_bitmap_drawing and it didn't changed to much. I decided to drop FPS rate to 10 and it get a little better, though I know my computer can run with a much higher rate.

Also, why to draw only if it has no event on the queue? ???

Btw, I put the code of another program I'm making in my last post, if you could please take a look I'd be thankful. Maybe my code is full of noob errors that I don't know... :P

For example: the draw_tile function I have draws using a single .png where all tiles are stored and then It call the tile using al_draw_bitmap_region with the region of the tile

I thought that If I change all multiplications from * to << in the tiles where its X or Y position is a multiple of power of 2... will it make the code at least a little faster? like:

#define TILE_1 0 * BLOCK_SIZE , 4 * BLOCK_SIZE to

#define TILE_1 0 * BLOCK_SIZE , (BLOCK_SIZE << 2)

Thomas Fjellstrom
anon176 said:

Also, why to draw only if it has no event on the queue? ???

If you don't handle all events in the queue every frame, you are only handling one event per frame. You will quickly back up a ton of events in the queue and lag behind.

Hm, so you are using atlasing, using held drawing should help if you're using any other bitmaps. Basically it just makes sure it doesn't actually send any of the drawing data to the gpu till you switch bitmaps, which should help a lot.

Something like:

#SelectExpand
1 2void draw() 3{ 4 al_hold_bitmap_drawing(true); 5 for(int i = 0; i < MAP_HEIGHT; i++) { 6 for(int j = 0; i < MAP_WIDTH; j++) { 7 Tile &t = atlas.tiles[map[i][j]]; // yay for C++ and references 8 al_draw_bitmap_region(atlas.bmp, t.x, t.y, TILE_WIDTH, TILE_HEIGHT, map.x + TILE_WIDTH * j, map.y + TILE_HEIGHT * i); 9 } 10 } 11 12 // draw other things, allegro will decide when to flush the held drawing 13 // just make sure to batch drawing that comes from the same bitmaps together 14 al_hold_bitmap_drawing(false); 15}

Quote:

I thought that If I change all multiplications from * to << in the tiles where its X or Y position is a multiple of power of 2... will it make the code at least a little faster?

If you enable compiler optimizations, that sort of thing should be done for you. You should use what is more readable, and only consider optimizations that you know will help significantly (look into profiling your code to figure out what is taking the most time).

Thread #615151. Printed from Allegro.cc