Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » drawing slow

This thread is locked; no one can reply to it. rss feed Print
drawing slow
shadyvillian
Member #12,426
December 2010

I'm having really slow reaction time when the mouse goes over my buttons. I'm using a timer for the drawing and the mouse will be over the image it will take 2 or 3 draw function calls for the over state of the button to show up. this is another window from the original, I'm not sure if that has anything to do with it. I tried increasing the timer speed but that doesn't really do anything.

#SelectExpand
1al_start_timer(RedrawTimer); 2 3 while(Exit == false) 4 { 5 al_wait_for_event(EventQueue, &Event); 6 7 if(Event.type == ALLEGRO_EVENT_TIMER) 8 { 9 if(Event.timer.source == RedrawTimer) 10 { 11 Redraw = true; 12 } 13 } 14 15 if(Event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) 16 { 17 Exit = true; 18 } 19 20 if(Event.type == ALLEGRO_EVENT_MOUSE_AXES) 21 { 22 for(unsigned int i = 0; i < Buttons.size(); i++) 23 { 24 Buttons[i].IsMouseOver(Event.mouse.x, Event.mouse.y); 25 } 26 } 27 28 if(Event.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP) 29 { 30 if(Buttons[PRVW_BUT_MULLIGIAN].IsMouseOver() == true) 31 { 32 if(HandSize == 1) 33 { 34 ShowMessageBox(Screen, "Error", "You can't mulligan to zero", ALLEGRO_MESSAGEBOX_ERROR); 35 } 36 37 if(HandSize > 1) 38 { 39 CardImages.clear(); 40 HandSize--; 41 random_shuffle(PreviewDeck.begin(), PreviewDeck.end()); 42 43 for(int i = 0; i < HandSize; i++) 44 { 45 CardImages.resize(CardImages.size()+1); 46 CardImages[CardImages.size()-1].Load(CardX[i], CardY[i], "Media/Images/Card Images/" + PreviewDeck[i].Set + "/" + PreviewDeck[i].Name + ".jpg"); 47 } 48 } 49 } 50 51 if(Buttons[PRVW_BUT_EXIT].IsMouseOver() == true) 52 { 53 Exit = true; 54 } 55 56 if(Buttons[PRVW_BUT_RESET].IsMouseOver() == true) 57 { 58 CardImages.clear(); 59 HandSize = 7; 60 random_shuffle(PreviewDeck.begin(), PreviewDeck.end()); 61 62 for(int i = 0; i < HandSize; i++) 63 { 64 CardImages.resize(CardImages.size()+1); 65 CardImages[CardImages.size()-1].Load(CardX[i], CardY[i], "Media/Images/Card Images/" + PreviewDeck[i].Set + "/" + PreviewDeck[i].Name + ".jpg"); 66 } 67 } 68 } 69 70 if((Redraw == true) && (al_is_event_queue_empty(EventQueue) == true)) 71 { 72 Redraw = false; 73 Draw(); 74 } 75 }

Software Engineer by day, hacker by night.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

shadyvillian
Member #12,426
December 2010

#SelectExpand
1void IsMouseOver(int MouseX, int MouseY) 2 { 3 if((MouseX >= x1+1) && (MouseX <= x2-1) && (MouseY >= y1+1) && (MouseY <= y2-1)) 4 { 5 Over = true; 6 } 7 8 else 9 { 10 Over = false; 11 } 12 } 13 14 bool IsMouseOver() 15 { 16 return Over; 17 }

Right when I put my mouse over the image over became true and i confirmed it using cout. Could the main window be slowing this window down? When you click a button another window appears and calls a run function that has a loop so you are in that until you close it. I set the backbuffer to the new window and I'm pretty sure you can't do anything in the main window until you get rid of this one(this is how I wanted it)

Software Engineer by day, hacker by night.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

shadyvillian
Member #12,426
December 2010

heres most of the functions

#SelectExpand
1int Initialize() 2{ 3 Screen = NULL; 4 EventQueue = NULL; 5 6 int x = 0, y = 0; 7 al_get_window_position(al_get_current_display(), &x, &y); 8 9 Screen = al_create_display(1050, 765); 10 if(!Screen) 11 { 12 return ShowMessageBox(al_get_current_display(), "Error", "Failed to create screen", ALLEGRO_MESSAGEBOX_ERROR); 13 } 14 15 al_set_window_position(Screen, x+75, y+97); 16 al_set_window_title(Screen, "Preview Hand"); 17 al_set_target_backbuffer(this->Screen); 18 19 ALLEGRO_BITMAP *Icon = NULL; 20 Icon = al_load_bitmap("Media/Images/Ui-Images/Icon.png"); 21 if(!Icon) 22 { 23 return ShowMessageBox(Screen, "Error", "Failed to load screen icon", ALLEGRO_MESSAGEBOX_ERROR); 24 } 25 26 al_set_display_icon(Screen, Icon); 27 28 EventQueue = al_create_event_queue(); 29 RedrawTimer = al_create_timer(1.0 / 30); 30 31 al_register_event_source(EventQueue, al_get_mouse_event_source()); 32 al_register_event_source(EventQueue, al_get_display_event_source(Screen)); 33 al_register_event_source(EventQueue, al_get_timer_event_source(RedrawTimer)); 34 35 return 0; 36} 37 38 39 40void UnloadContent() 41{ 42 al_destroy_display(Screen); 43} 44 45void Draw() 46{ 47 Background.Draw(); 48 49 for(unsigned int i = 0; i < Buttons.size(); i++) 50 { 51 Buttons[i].Draw(); 52 } 53 54 for(unsigned int i = 0; i < CardImages.size(); i++) 55 { 56 CardImages[i].Draw(); 57 } 58 59 al_flip_display(); 60} 61 62void Run(const std::vector<Card> &Deck) 63{ 64 const int CardX[7] = {10, 270, 530, 790, 10, 270, 530}; 65 const int CardY[7] = {10, 10, 10, 10, 370, 370, 370}; 66 67 for(unsigned int i = 0; i < Deck.size(); i++) 68 { 69 for(int j = 0; j < Deck[i].NumOf; j++) 70 { 71 PreviewDeck.push_back(Deck[i]); 72 } 73 } 74 75 random_shuffle(PreviewDeck.begin(), PreviewDeck.end()); 76 77 for(int i = 0; i < 7; i++) 78 { 79 CardImages.resize(CardImages.size()+1); 80 CardImages[CardImages.size()-1].Load(CardX[i], CardY[i], "Media/Images/Card Images/" + PreviewDeck[i].Set + "/" + PreviewDeck[i].Name + ".jpg"); 81 } 82 83 Exit = false; 84 Draw(); 85 al_start_timer(RedrawTimer); 86 87 while(Exit == false) 88 { 89 al_wait_for_event(EventQueue, &Event); 90 91 if(Event.type == ALLEGRO_EVENT_TIMER) 92 { 93 if(Event.timer.source == RedrawTimer) 94 { 95 Redraw = true; 96 } 97 } 98 99 if(Event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) 100 { 101 Exit = true; 102 } 103 104 if(Event.type == ALLEGRO_EVENT_MOUSE_AXES) 105 { 106 for(unsigned int i = 0; i < Buttons.size(); i++) 107 { 108 Buttons[i].IsMouseOver(Event.mouse.x, Event.mouse.y); 109 } 110 } 111 112 if(Event.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP) 113 { 114 if(Buttons[PRVW_BUT_MULLIGIAN].IsMouseOver() == true) 115 { 116 if(HandSize == 1) 117 { 118 ShowMessageBox(Screen, "Error", "You can't mulligan to zero", ALLEGRO_MESSAGEBOX_ERROR); 119 } 120 121 if(HandSize > 1) 122 { 123 CardImages.clear(); 124 HandSize--; 125 random_shuffle(PreviewDeck.begin(), PreviewDeck.end()); 126 127 for(int i = 0; i < HandSize; i++) 128 { 129 CardImages.resize(CardImages.size()+1); 130 CardImages[CardImages.size()-1].Load(CardX[i], CardY[i], "Media/Images/Card Images/" + PreviewDeck[i].Set + "/" + PreviewDeck[i].Name + ".jpg"); 131 } 132 } 133 } 134 135 if(Buttons[PRVW_BUT_EXIT].IsMouseOver() == true) 136 { 137 Exit = true; 138 } 139 140 if(Buttons[PRVW_BUT_RESET].IsMouseOver() == true) 141 { 142 CardImages.clear(); 143 HandSize = 7; 144 random_shuffle(PreviewDeck.begin(), PreviewDeck.end()); 145 146 for(int i = 0; i < HandSize; i++) 147 { 148 CardImages.resize(CardImages.size()+1); 149 CardImages[CardImages.size()-1].Load(CardX[i], CardY[i], "Media/Images/Card Images/" + PreviewDeck[i].Set + "/" + PreviewDeck[i].Name + ".jpg"); 150 } 151 } 152 } 153 154 if((Redraw == true) && (al_is_event_queue_empty(EventQueue) == true)) 155 { 156 Redraw = false; 157 Draw(); 158 } 159 } 160 161 al_stop_timer(RedrawTimer); 162 UnloadContent(); 163}

if i remove the timer and put draw before al_wait_for_event it doesnt even respond. I can't even x out the window it just hangs and I have to force exit using the stop debugger.

EDIT: these functions are part of a class and most of the variables are too. the buttons have their own class

Software Engineer by day, hacker by night.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

I still don't see anything wrong. Your timer is a bit slow, usual timer speed matches the refresh rate of the monitor, typically 60 or 70 Hz.

Are all your buttons slow to show the hover?

You should try timing how long it takes from when your button changes to the hover state to when the display is shown next. Then use a kind of binary search to find out what is taking so long for it to display.

#SelectExpand
1bool hover, old_hover, hover_changed; 2 3if (hover = buttons[X].IsMouseOver()) { 4 hover_changed = (hover != old_hover); 5 old_hover = hover; 6} 7 8if (hover_changed) {start = al_get_time();} 9 10if (redraw) { 11 Draw(); 12 if (hover_changed) { 13 stop = al_get_time(); 14 printf("Hover change took %f seconds to display.\n" , stop - start); 15 } 16}

shadyvillian
Member #12,426
December 2010

the over state changes immediately, but the over state doesn't draw for 5 seconds or so

Software Engineer by day, hacker by night.

LordHolNapul
Member #3,619
June 2003
avatar

hi,
I've not read and understood all your code but you should do the following steps in order to run quickly your images:

1) Preload everything you need from the HD with a load process.

2) Format everything you need to be quickly accessible (i.e. transform BMP into texture and MP3 into the first chunk of wave...)

3) create the main loop using POINTERS to the Graphic and the other data. Every method and function that passes parameters should use pointers unless you are transmitting int/short int/1 char/or Bool.

4) your main loop is ended, destroy everything you created , and quit.

hope this help. ::)

shadyvillian
Member #12,426
December 2010

Ok so I exported this whole module class to a standalone program and everything worked perfect with the code unchanged. What does this tell us edgar?

Software Engineer by day, hacker by night.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

the over state changes immediately, but the over state doesn't draw for 5 seconds or so

Did you measure the time using the method I posted in the post before the one I just quoted? If you did, and it took 5 seconds, then it was your Draw() method taking 5 seconds to complete.

Ok so I exported this whole module class to a standalone program and everything worked perfect with the code unchanged. What does this tell us edgar?

It depends. There has to be something different. In the program that was slow to visually update, you were using a second display. Did you load any resources used in it in the same thread that you created the display in? Or if there were any resources, were they loaded in a separate thread? That would cause them to be slow memory bitmaps. In fact, I don't see you loading your card images anywhere in the code you posted.

Your resources may be attached to another display - you'd have to ask the Allegro devs about that - that might be causing part of the problem.

The first display shouldn't be taking any processor power except for the allegro thread that runs it's window process, which should be minimal.

Still not sure what's wrong though.

shadyvillian
Member #12,426
December 2010

all the images are loaded when the main program is starting. Should I load it after I create the window that these images are being drawn to?

Software Engineer by day, hacker by night.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

I'm not sure, but I would guess that the answer is yes, you should load the resources used when your new display is active.

I think the whole problem is that your resources are not attached to the display that is in use. You should be able to test that fairly easily.

LordHolNapul
Member #3,619
June 2003
avatar

the process of loading is connected to the color depth of your screen...
The Setup of Allegro is always the first step to do...

shadyvillian
Member #12,426
December 2010

No I would initialize allegro then load all content including for the sub windows. then when the user clicks the button to bring up the window and i initialize that window so it shows up. I changed it so when the sub window initializes i made it load the sub windows content and now it works. I really need to learn about threads :P I originally wanted to load all the images in the beginning so when you open a sub window your not sitting with a blank window waiting for all the images to load.

Software Engineer by day, hacker by night.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Go to: