Search code examples
c++allegro5

Why is my Allegro 5 map editor so slow? What could I change to make it faster?


I am creating an Allegro 5 map editor with C/C++ and I need help with it. When I run it, it works fine until I place some bitmaps on the screen. After 4-5 bitmaps are placed on the screen, the program starts to get horribly slow, making the editor almost impossible to use.

Here's the code:

#include <allegro5\allegro.h>
#include <allegro5\allegro_font.h>
#include <allegro5\allegro_image.h>
#include <allegro5\allegro_primitives.h>
#include <stdio.h>
#include <vector>

//CLASS DEFINITION SECTION


class T_center
{
public:
    //place
    int p;
    int y;
    //place bound y up, x left, y down, x right
    int pbyu;
    int pbxl;
    int pbyd;
    int pbxr;
    ALLEGRO_BITMAP *img;
};

const int tileamount = 196;
T_center tile[tileamount];
int height = 700;
int width = 700;
ALLEGRO_DISPLAY *display;
ALLEGRO_EVENT ev;
ALLEGRO_EVENT_QUEUE *queue;
ALLEGRO_BITMAP *curr;
ALLEGRO_BITMAP *ground;

//FUNCTION DECLARATION SECTION


void func_start_system();
void func_start_tiles(int tilesize, T_center *tile, int tilearray, int xsize);
void func_start_variables();
void func_detect_mouse_move(T_center *tile, int tilearray);

//THE TOOL ITSELF

int main()
{
    al_init();
    al_init_font_addon();
    al_init_image_addon();
    al_init_primitives_addon();
    ground = al_load_bitmap("grass.jpg");
    func_start_system();
    func_start_tiles(25, tile, tileamount, tileamount);
    func_start_variables();
    al_flip_display();
    func_detect_mouse_move(tile, tileamount);
}






//FUNCTION DEFINITION SECTION

void func_start_system()
{
    al_install_keyboard();
    al_install_mouse();
}

void func_start_tiles(int tilesize, T_center *tile, int tilearray, int xsize)
{
    int xcount = 0;
    int tile_x = tilesize;
    int tile_y = tilesize;
    int y_count = 1;
    for (int i = 0; i < tilearray; i++)
    {
        if (xcount == 14)
        {
            xcount = 0;
            tile_y = tile[i-1].pbyd + tilesize;
            tile_x = tilesize;
        }
        tile[i].p = tile_x, tile[i].y = tile_y, tile[i].pbxl = tile_x - tilesize, tile[i].pbxr = tile_x + tilesize, tile[i].pbyu = tile_y - tilesize, tile[i].pbyd = tile_y + tilesize;
        tile_x = tile[i].pbxr + tilesize;
        printf("%i, %i, left: %i\n", tile[i].p, tile[i].y, tile[i].pbxl);
        xcount++;
    }
}

void func_start_variables()
{
    curr = al_load_bitmap("grass.jpg");
    display = al_create_display(width, height);
    queue = al_create_event_queue();
    al_register_event_source(queue, al_get_mouse_event_source());
    al_register_event_source(queue, al_get_keyboard_event_source());
    al_register_event_source(queue, al_get_display_event_source(display));
}

void func_detect_mouse_move(T_center *tile, int tilearray)
{
    bool a = true;
    while (a)
    {
        for (int i = 0; i < tilearray; i++)
            if (tile[i].img != NULL)
                al_draw_bitmap(tile[i].img, tile[i].pbxl, tile[i].pbyu, 0);
        al_wait_for_event(queue, &ev);
        if (ALLEGRO_EVENT_MOUSE_AXES)
        {
            for (int i = 0; i < tilearray; i++)
                if (ev.mouse.x >= tile[i].pbxl && ev.mouse.x < tile[i].pbxr && ev.mouse.y >= tile[i].pbyu && ev.mouse.y < tile[i].pbyd)
                {
                    al_draw_tinted_bitmap(curr, al_map_rgb(100, 60, 60), tile[i].pbxl, tile[i].pbyu, 0);
                    al_flip_display();
                }
            al_clear_to_color(al_map_rgb(0, 0, 0));
        }
        if (ALLEGRO_EVENT_MOUSE_BUTTON_DOWN)
        {
            if (ev.mouse.button & 1)
            {
                for (int i = 0; i < tilearray; i++)
                {
                    if (ev.mouse.x >= tile[i].pbxl && ev.mouse.x < tile[i].pbxr && ev.mouse.y >= tile[i].pbyu && ev.mouse.y < tile[i].pbyd)
                        tile[i].img = curr;
                }
            }
        }
    }
}

I might be doing something really stupid when it comes to drawing things on the screen, but I have no idea of what I am doing wrong.

Do you have any tips for me?


Solution

  • You are creating and loading bitmaps before a display is created. This bitmaps reside on system memory instead of video memory. The reason they don´t use video memory is that Allegro has no other place to put them because the display is not loaded first.

    You need to start the display as soon as possible and then load the bitmaps inside it. Or, as an alternative, you can load them to system memory and then, after you create your display, you copy them to the video memory using al_convert_bitmaps. Keep in mind you need to do that after a valid display is created.

    My recommendation? Move display creation from func_start_variables() to a better place: Inside your main, right after al_init().

    The reason memory bitmaps are slow, in case you would like to know, is that everytime you need to draw they have to be copied by the cpu to the graphic card, then it discards them. A video bitmap stays on the GPU so it is only a matter of displaying the contents already on memory. No copy operation is done by the CPU.