Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Allegro5 Full-Screen Problem

This thread is locked; no one can reply to it. rss feed Print
Allegro5 Full-Screen Problem
GaryT
Member #14,875
January 2013

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
Member #12,491
January 2011
avatar

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.

" There are plenty of wonderful ideas in The Bible, but God isn't one of them." - Derezo
"If your body was a business, thought would be like micro-management and emotions would be like macro-management. If you primarily live your life with emotions, then you are prone to error on the details. If you over-think things all the time you tend to lose scope of priorities." - Mark Oates

Elias
Member #358
May 2000

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.

--
"Either help out or stop whining" - Evert

GaryT
Member #14,875
January 2013

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
Member #5,401
January 2005

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
Member #14,875
January 2013

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.

Go to: