Allegro5 Full-Screen Problem
GaryT

I'm having a problem when using: ALLEGRO_FULLSCREEN

As usual I've provided the most simple short test program to attempt to illustrate the issue.

Also is attached one .exe compiled in FULLSCREEN mode and one .exe compiled in WINDOWED mode.

Description: Displays exactly as expected in WINDOWED mode, but in FULLSCREEN mode the following two problems occur:

1) Drawn objects are not erased properly.

2) Objects that are Not erased, But, also not drawn each frame flicker.

I've tested on three computers, Vista Laptop, Vista Desktop and Windows 7 Laptop, getting exactly the same results.

I know using: al_clear_to_color(al_map_rgb(0,0,0)); instead of erasing only the area required and then re-drawing everything each frame is one possibility, but for various reasons I'm not sure I want to do that.

Surely I'm just implementing FULLSCREEN incorrectly.

Please Help and here's the very simple test program:

#SelectExpand
1#include <allegro5\allegro.h> 2#include <allegro5\allegro_primitives.h> 3#include <allegro5\allegro_font.h> 4 5int main(void) 6{ 7 ALLEGRO_DISPLAY *display = NULL; 8 ALLEGRO_EVENT_QUEUE *event_queue = NULL; 9 ALLEGRO_FONT *font = NULL; 10 11 if(!al_init()) 12 return -1; 13 14 al_set_new_display_option(ALLEGRO_VSYNC, 1, ALLEGRO_REQUIRE); // Always Leave Set Because Even In Full Screen Mode It's Not Always Switched On Automatically! 15 16 // COMMENT FROM HERE 17 ALLEGRO_DISPLAY_MODE disp_data; 18 al_get_display_mode(al_get_num_display_modes() - 1, &disp_data); 19 al_set_new_display_flags(ALLEGRO_FULLSCREEN); 20 display = al_create_display(disp_data.width, disp_data.height); 21 // TO HERE 22 23 //display = al_create_display(800, 600); // UNCOMMENT HERE 24 25 if(!display) 26 return - 1; 27 28 al_init_primitives_addon(); 29 al_install_keyboard(); 30 al_init_font_addon(); 31 32 font = al_create_builtin_font(); 33 34 event_queue = al_create_event_queue(); 35 36 al_register_event_source(event_queue, al_get_keyboard_event_source()); 37 38 ALLEGRO_EVENT ev; 39 40 bool realevent; 41 bool playing = true; 42 43 int y = 400; 44 int x = 350; 45 int rate = 50; 46 47 al_draw_filled_circle(400, 200, 50, al_map_rgb(0, 200, 200)); 48 49 while(playing) 50 { 51 realevent = al_get_next_event(event_queue, &ev); 52 if(realevent) 53 { 54 if(ev.type == ALLEGRO_EVENT_KEY_DOWN) 55 { 56 if(ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) 57 playing = false; 58 59 if(ev.keyboard.keycode == ALLEGRO_KEY_LEFT) 60 x -= rate; 61 62 if(ev.keyboard.keycode == ALLEGRO_KEY_RIGHT) 63 x += rate; 64 65 if(ev.keyboard.keycode == ALLEGRO_KEY_UP) 66 rate += 10; 67 68 if(ev.keyboard.keycode == ALLEGRO_KEY_DOWN) 69 rate -= 10; 70 } 71 } 72 73 al_draw_textf(font, al_map_rgb(0, 150, 255), 395, 100, 0, "%i ", rate); 74 75 al_draw_filled_circle(x, y, 50, al_map_rgb(0, 200, 0)); 76 77 al_flip_display(); 78 79 al_draw_filled_rectangle(395, 100, 430, 110, al_map_rgb(0, 0, 0)); 80 81 al_draw_filled_circle(x, y, 50, al_map_rgb(0, 0, 0)); 82 } 83 84 al_destroy_event_queue(event_queue); 85 al_destroy_display(display); 86 al_destroy_font(font); 87 88 return 0; 89}

J-Gamer

The problem you have is that OpenGL probably has multiple buffers in fullscreen mode, whereas it seems not to have them in windowed mode. You're not drawing to the screen buffer after the al_flip_display(), but to the next screen. There is no need to use dirty rectangles any more, unless you are drawing to a separate bitmap.

Elias

After al_flip_display you have to erase the whole screen with al_clear_to_color because the contents for the next flip get invalidated. That they seem to be preserved for you sometimes in windowed modes was just luck.

GaryT

Okay I think I get what you both mean and thank you for the super fast response!

Please confirm the following:

1) The results in FullScreen mode are what you expect and that if you run the FULLSCREEN .exe or compile the source code yourself, you also see the same result.

2) Even though I've found it to work as I've expected in Windowed Modes during all my testing, I should still probably use: al_clear_to_color for Windowed Modes.

3) To use FullScreen mode I have to use: al_clear_to_color.

Edit: I've just tried: al_update_display_region(x - 25, y - 25, 50, 50); but it's exactly the same. I suppose even though only a region is updated (driver compatible I know) that after flipping it's invalidated regardless of the area updated. Is this correct?

Christopher Bludau
GaryT said:

suppose even though only a region is updated (driver compatible I know) that after flipping it's invalidated regardless of the area updated. Is this correct?

Everything you did before the flip will be gone after you flipped.
In other words: After you flipped you will get only garbage. The easiest way to get rid of that garbage is by clearing the whole screen with al_clear_to_color and then draw whatever you want on that freshly primed canvas :)

GaryT

Thank you Christopher.

Success :) :D

I have a custom draw maze routine that splits the screen into 1488 x 25 pixel squares, which are detected by a rectangle drawn by the mouse. Each of these 1488 squares are stored in a vector as structs.

Now initially cycling through the saved custom maze and drawing it to screen is not a problem, since this is done just once before the main game loop. So then, by erasing the whole screen, the only way I knew how to get the maze back was to cycle through all 1488 squares again, calling: al_draw_bitmap() 1488 times for each frame. This worked but increased CPU from averaging 1 percent to about 12 percent.

Happily I've just found this works great:

ALLEGRO_BITMAP *MazeScreen = NULL;
MazeScreen = al_create_bitmap(WIDTH, HEIGHT);
al_set_target_bitmap(MazeScreen);
al_clear_to_color(al_map_rgb(0,0,0));
(My cycle and draw maze loop)
al_set_target_bitmap(al_get_backbuffer(display));
al_draw_bitmap(MazeScreen, 0, 0, 0);
al_flip_display();

Above is what I now do before the main game loop to load the maze. Then I just: al_draw_bitmap(MazeScreen, 0, 0, 0); once per frame.

It now still only averages 1 percent CPU.

Initially I didn't think this would work since the same amount of screen update was happening. But now I think I was being a bit silly, because if just updating the whole screen area uses this much CPU, then that seems a bit extreme to me.

So my best guess is it's the huge number of calls to: al_draw_bitmap() that was the problem and Not the total screen updated area. :)

Thank you all. I'm extremely pleased. :)

Edit: So far though I've experienced no invalidation of the buffer pixels in any Windowed mode, so I've not needed to consider this before using FullScreen without using al_clear_to_color(), whereas I was using it with: al_clear_to_color() in earlier testing.

Thread #612509. Printed from Allegro.cc