I just yesterday decided to switch from using Allegro 4 to 5.
This game I'm working on works with 5 now, but just like with 4, I am having terrible performance problems while trying to draw the isometric tiles. Kinda defeats the purpose of me switching... I was hoping the hardware acceleration would improve it.
What I'm trying to do is draw a fairly large number of tiles... probably comparable to as many as you'd see in your average session of Roller Coaster Tycoon.
I have tile culling in place, but it's still very slow when the map fills the screen. When the camera is on the edges, it's better.
Right now the game is VERY simple. More of a skeleton. So maybe I made some kind of error somewhere.
My INIT function:
#SelectExpand
1int init
() //start up necessary allegro tools and other objects
2{
3 al_init(); //allegro itself
4
5 al_set_new_display_flags(ALLEGRO_FULLSCREEN
);
6
7 int dsk_w
= 1360, dsk_h
=768; //my monitor's native res
8 //get_desktop_resolution(&dsk_w,&dsk_h); //something left over from AL4
9 display
= al_create_display(dsk_w, dsk_h
); //create display
10
11
12 al_init_image_addon(); //bitmaps, pngs, jpegs etc
13 al_init_font_addon(); //for fonts, just bitmap ones
14 al_init_primitives_addon(); //rectangles, circles, triangles etc
15 al_init_ttf_addon(); // true type fonts (scalable vector fonts)
16 al_install_mouse(); //the mouse
17 al_install_keyboard(); //the keyboard
18 al_install_audio(); //for audio, WAVs,
19 al_init_acodec_addon(); //audio codecs like OGG and FLAC
20
21
22 srand(time(NULL
));
23
24 font_default
= al_load_font("font/calibri.ttf",
14,
0);
25
26 return 0;
27}
This is the main part of the screen refreshing function, very basic:
This object's draw event is called once each frame. It draw the world tiles:
Note that BMP["filename"] is the resource map that retrieves a pointer to a loaded bitmap, and loads it if it hasn't already been loaded. It's not in use in the loop.
#SelectExpand
1Session::Session
()
2{
3 Grid_Tiles
= Grid
<ALLEGRO_BITMAP*>(128,
128,NULL
);
4
5 camX
=500;
6 camY
=-200;
7
8 int seed
=rand();
9
10 ALLEGRO_BITMAP* tiletest1
= BMP
["tiletest1.png"];
11 ALLEGRO_BITMAP* tiletest2
= BMP
["tiletest2.png"];
12
13
14 for(int a
=0; a
<Grid_Tiles.w
; a
++)
15 for(int b
=0; b
<Grid_Tiles.h
; b
++)
16 {
17 if (perlin
(a, b,
3, seed
)>0.
4)
18 {
19 Grid_Tiles.set
(a,b,tiletest1
);
20 }
21 else
22 Grid_Tiles.set
(a,b,tiletest2
);
23 }
24
25}
26
27void Session::draw
()
28{
29
30 if (key[ALLEGRO_KEY_UP
]) camY-
=3;
31 if (key[ALLEGRO_KEY_DOWN
]) camY
+=3;
32 if (key[ALLEGRO_KEY_RIGHT
]) camX
+=6;
33 if (key[ALLEGRO_KEY_LEFT
]) camX-
=6;
34
35 selectX
=-1;
36 selectY
=-1;
37
38 int drawX, drawY
;
39
40 int viewX1
=std::max
(0,
(((camX
)/(TILE_W-1
))+(camY
/TILE_H
))-3);
41 int viewX2
=std::min
(Grid_Tiles.w,
((((camX
)+SCREEN_W)/(TILE_W-1
))+((camY
)+SCREEN_H)/TILE_H
)+5);
42 int viewY1
=std::min
(Grid_Tiles.h-1,
((((camX
)+SCREEN_W)/(TILE_W-1
))-(camY
)/TILE_H
)+5);
43 int viewY2
=std::max
(0,
(((camX
)/(TILE_W
))-(((camY
)+SCREEN_H)/TILE_H
))-3);
44
45 //ALLEGRO_BITMAP* selectorback = BMP["tileselector_back.png"];
46 //ALLEGRO_BITMAP* selectorfront = BMP["tileselector_front.png"];
47
48
49 for(int a
=viewX1
; a
<viewX2
; a
++)
50 {
51 for(int b
=viewY1
; b>
=viewY2
; b--
)
52 {
53 drawX
=(b
*(int)(TILE_W
/2-1))+(a
*(int)(TILE_W
/2-1))-camX
;
54 if (drawX
<-TILE_W
|| drawX>SCREEN_W
)
55 continue;
56
57 drawY
=(a
*(int)(TILE_H
/2))-(b
*(int)(TILE_H
/2))-camY
;
58 if(drawY
<-200 || drawY>SCREEN_H
)
59 continue;
60
61
62
63 //TODO: Set selectX and selectY based on where the mouse is pointing
64
65 //if (selectX==a && selectY==b)
66 // al_draw_bitmap(selectorback, drawX, drawY, 0);
67
68 al_draw_bitmap(Grid_Tiles.get
(a,b
), drawX, drawY,
0);
69
70 if (Grid_Actors->get
(a,b
)!=NULL
)
71 {
72 Grid_Actors->get
(a,b
)->draw
(drawX, drawY
);
73 }
74
75 /*if (selectX==a && selectY==b)
76 {
77 al_draw_bitmap(selectorfront, drawX, drawY, 0);
78 al_draw_textf(font_default,al_map_rgb(255,150,30),drawX-20,drawY-10,0, "(%d,%d)",a,b);
79 }*/
80 }
81 }
82
83}
Here is the Bitmap resource handler. Maybe I'm loading them incorrectly?
#SelectExpand
1#include "bitmaps.h"
2#include <allegro5/allegro_native_dialog.h>
3#include <allegro5/allegro_image.h>
4
5
6ALLEGRO_BITMAP* BitmapHandler::operator
[](std::string filename
)
7{
8
9 ALLEGRO_BITMAP* result
= my_map
[filename
];
10
11 if (!result
) //file hasn't been loaded yet
12 {
13 result
=load
(filename
);
14 }
15 if (!result
) //load error
16 {
17 my_map.erase
(filename
);
18 }
19
20 return result
;
21}
22
23ALLEGRO_BITMAP* BitmapHandler::load
(std::string filename
)
24{
25 ALLEGRO_BITMAP* result
= al_load_bitmap((char*)("gfx/"+filename
).c_str
());
26
27 if (!result
)
28 al_show_native_message_box(NULL,
"ERROR",
"Image Could Not Load",
(char*)filename.c_str
(),NULL, ALLEGRO_MESSAGEBOX_ERROR
);
29 else
30 my_map
[filename
] = result
;
31
32 return result
;
33}
34
35//THIS IS NOT USED ANYWHERE YET:
36void BitmapHandler::unload
(std::string filename
)
37{
38
39 al_destroy_bitmap(my_map
[filename
]);
40 my_map.erase
(filename
);
41}
42
43
44//THIS IS NOT USED ANYWHERE YET:
45void BitmapHandler::reload
(std::string filename
)
46{
47 unload
(filename
);
48 my_map
[filename
]=load
(filename
);
49}
50
51void BitmapHandler::clear
()
52{
53 std::map
<std::string,
ALLEGRO_BITMAP*>::iterator it
;
54 for (it
= my_map.begin
(); it
!= my_map.end
(); ++it
)
55 {
56 al_destroy_bitmap((*it
).second
);
57 }
58 my_map.clear
();
59}
And the Grid class that I created. [Needed this to have a structure that returns a default value on an out-of-bounds get()]
#SelectExpand
1#pragma once
2
3#include <vector>
4
5template<class T>
6class Grid
7{
8 private:
9 std::vector<T> field;
10 T default_value;
11
12 public:
13 int w,h,size;
14
15 Grid()
16 {
17 w=0;
18 h=0;
19 size=0;
20 default_value=0;
21 }
22
23 Grid(int W, int H, T def)
24 {
25 w=W;
26 h=H;
27 size=w*h;
28 default_value=def;
29 for ( int i = 0; i < size; i++ )
30 {
31 field.push_back(default_value);
32 }
33 }
34
35 T get(int x, int y)
36 {
37 if (x<0 || y<0 || x>=w || y>=h) return default_value;
38 return field[x + y*w];
39 }
40
41 void set(int x, int y, T val)
42 {
43 if (x<0 || y<0 || x>=w || y>=h) return;
44 field[x + y*w] = val;
45 }
46
47 void fill(T val)
48 {
49 for(int a=0; a<size; a++)
50 {
51 field[a] = val;
52 }
53 }
54};
I'll get yelled at for this, but here's my "global.h". To the main CPP, it declares and initializes global variables. Outside the main.cpp, it declares them as external.
#SelectExpand
1#pragma once
2
3#include <vector>
4#include <algorithm>
5
6#include <allegro5/allegro.h>
7#include <allegro5/allegro_font.h>
8#include <allegro5/allegro_audio.h>
9#include <allegro5/allegro_acodec.h>
10#include <allegro5/allegro_ttf.h>
11#include <allegro5/allegro_image.h>
12#include <allegro5/allegro_primitives.h>
13#include <allegro5/allegro_native_dialog.h>
14
15#include "game.h"
16#include "gameobject.h"
17#include "clarionmath.h"
18#include "grid.h"
19#include "bitmaps.h"
20
21#ifndef MAINCPP
22#define GLOB(X,V) extern X;
23#else
24#define GLOB(X,V) X V;
25#undef MAINCPP
26#endif
27
28
29///GLOBAL DEFINES
30#define SCREEN_W al_get_display_width(display)
31#define SCREEN_H al_get_display_height(display)
32#define SCREEN_BITMAP al_get_backbuffer(display)
33
34///ENUMS
35namespace ROOM
36{
37enum ENUM
38{
39 MENU,
40 GAME
41};
42}
43
44namespace DIR
45{
46enum ENUM
47{
48 NORTH,
49 EAST,
50 SOUTH,
51 WEST,
52 UP,
53 DOWN
54};
55}
56
57
58enum MOUSE_BUTTONS
59{
60 MBLEFT
=0,
61 MBRIGHT
=1,
62 MBMIDDLE
=2
63};
64
65
66///GLOBAL VARS
67//remember to use GLOB(Declaration,Definition) to define global variables and avoid linker errors
68
69GLOB
(Game
* Clarion,
)
70
71GLOB
(const int MASK,
=16711935)
72
73GLOB
(unsigned int LAST_CLOCK,
=clock())
74GLOB
(double FPS,
=1)
75GLOB
(int TARGET_FPS,
=60)
76
77//dimensions of various things
78GLOB
(int TILE_W,
=50)
79GLOB
(int TILE_H,
=25)
80GLOB
(int UI_W,
=200)
81GLOB
(int UI_H,
=120)
82
83//resource holders (hold maps of resources)
84GLOB
(BitmapHandler BMP,
)
85
86//keyboard data
87GLOB
(ALLEGRO_KEYBOARD_STATE KBSTATE,
)
88GLOB
(bool key[ALLEGRO_KEY_MAX
],
)
89GLOB
(bool key_was
[ALLEGRO_KEY_MAX
],
)
90GLOB
(bool key_pressed
[ALLEGRO_KEY_MAX
],
)
91GLOB
(bool key_released
[ALLEGRO_KEY_MAX
],
)
92
93//mouse data
94GLOB
(ALLEGRO_MOUSE_STATE MOUSE,
)
95GLOB
(bool mouse_was
[3],
)
96GLOB
(bool mouse_pressed
[3],
)
97GLOB
(bool mouse_released
[3],
)
98
99//fonts
100GLOB
(ALLEGRO_FONT* font_default,
)
101
102//display
103GLOB
(ALLEGRO_DISPLAY* display,
)
104
105
106
107
108///FUNCTIONS
109int init
(); //start up necessary allegro tools and other objects
110
111void update_input
();
112
113/*void soundplay(ALLEGRO_SAMPLES* S);
114void soundloop(ALLEGRO_SAMPLES* S);*/
115
116void refresh_screen
(); //flips screen
117
118//draw a UI frame using a small picture as the base
119void draw_frame
(ALLEGRO_BITMAP* frame,
int x,
int y,
int w,
int h,
bool inner
=0);
120
121int color_compare
(ALLEGRO_COLOR c1,
ALLEGRO_COLOR c2
);