ALLEGRO_FULLSCREEN and al_flip_display problem
mickwa

Hi,
I have problem with this code:

#SelectExpand
1#include <allegro5/allegro.h> 2 3int main() 4{ 5 if(!al_init()) { return 1;} 6 ALLEGRO_DISPLAY *display; 7 8 ALLEGRO_DISPLAY_MODE disp_data; 9 al_get_display_mode(al_get_num_display_modes() - 1, &disp_data); 10 al_set_new_display_flags(ALLEGRO_FULLSCREEN); 11 display = al_create_display(disp_data.width, disp_data.height); 12 if(!display) { 13 return 1; 14 } 15 16 al_clear_to_color(al_map_rgb(222,222,2)); 17 al_flip_display(); 18 al_flip_display(); 19 al_rest(4); 20 return 0; 21}

Above code results with black screen.
If I remove duplicated al_flip_display() from line 18 screen is yellow as I expected. Why second al_flip_display() makes screen black again?
If I change ALLEGRO_FULLSCREEN flag to ALLEGRO_FULLSCREEN_WINDOW screen is yellow.
I'm using allegro-5.0.7-msvc-10.0, Windows 7.

William Labbett

The second al_flip_display() flips so that the backbuffer which you haven't drawn to yet is the next one that gets flipped.

Isn't that right guys ?

This should work.

al_clear_to_color(al_map_rgb(222,222,2));
al_flip_display();

/* Draw to hidden buffer. */

al_clear_to_color(al_map_rgb(222,222,2));
al_flip_display();

ie add a line bewteen the al_flip_display()'s

mickwa

William thank You for reply. My understanding is that whenever I invoke al_flip_display(), content from backbuffer is moved to screen, but backbuffer is not erased. So if I invoke al_flip_display(), make no changes to backbuffer, and invoke al_flip_dsplay() for second time, it will have no effect. Am I right? But in this example second al_flip_display() changes what is on screen.

for me, this code works different for ALLEGRO_FULLSCREEN and ALLEGRO_FULLSCREEN_WINDOW display flags and I don't understand why. ALLEGRO_FULLSCREEN flag changes behaviour of al_flip_display()?

I made some additional research:

#SelectExpand
1#include <allegro5/allegro.h> 2#include <allegro5/allegro_font.h> 3#include <allegro5/allegro_ttf.h> 4int main() 5{ 6 if(!al_init()) { return 1;} 7 ALLEGRO_DISPLAY *display; 8 9 ALLEGRO_DISPLAY_MODE disp_data; 10 al_get_display_mode(al_get_num_display_modes() - 1, &disp_data); 11 al_set_new_display_flags(ALLEGRO_FULLSCREEN); 12 display = al_create_display(disp_data.width, disp_data.height); 13 if(!display) { 14 return 1; 15 } 16 17 al_init_font_addon(); 18 al_init_ttf_addon(); 19 ALLEGRO_FONT *debugFont = al_load_ttf_font("gfx/debugFont.ttf",25,NULL); 20 al_clear_to_color(al_map_rgb(222,222,2)); 21 int redraw = 0; 22 while(redraw<20) 23 { 24 al_flip_display(); 25 al_draw_textf(debugFont,al_map_rgb(190,33,33),11,11+redraw*11,0,"redraw %d",redraw); 26 redraw++; 27 al_rest(2); 28 } 29 30 return 0; 31}

it looks like it has TWO backbuffers. Once it draws 0,2,4 and on second 1,3,5 etc. Please see attached two parts of screenshots

William Labbett

Yes, the whole idea behind al_flip_display is that each time you call it, it draws the buffer which is unseen. So there are two backbuffers. The word flip means 'turn over' so think of the bitmap which gets drawn to the screen as having two sides.

Drawing is always to the side not seen. al_flip_display() turns it over so the unseen side is now seen.

I think the whole idea behind it is that the bitmap is completely drawn when it appears on the screen. It's called page flipping.

Otherwise the draws would happen while the screen is being traced out and so frames would get mixed up.

If someone else could correct anything I've said or clarify, that'd be good.

mickwa

Did You try to test my code from first post? Does al_flip_display() work different with ALLEGRO_FULLSCREEN and ALLEGRO_FULLSCREEN_WINDOW flag also for You? I would be very grateful if You could test it and share info how it works for You.

I solved this problem by combining two flags:

#SelectExpand
1al_set_new_display_flags(ALLEGRO_FULLSCREEN_WINDOW); 2al_set_new_display_flags(ALLEGRO_NOFRAME);

Elias

The contents of the backbuffer after al_flip_display are undefined. They may stay unmodified, have the contents of a previous frame, or contain garbage.

mickwa

Thanks Elias. This is new for me. I thought that backbuffer will be unchanged after al_flip_display(). Until now it always stayed unchanged.

Elias

It's the logical thing for DirectX/OpenGL to do. But when the GPU uses multiple buffers, you will get old versions. And for example in X11 without compositing the contents are lost when another window moves in front.

mickwa

I see. This is bad news for me that once used backbuffer can have garbage inside. So I have to allways redraw everything from beginning on backbuffer? Is there way to use once used backbuffer? What do You do in situation when You have to make only small changes to what was previously drawn?

Elias

The way all modern games do it is to completely redraw the backbuffer every frame, yes. You can of course use off-screen targets to keep something around (i.e. al_set_target_bitmap).

Thomas Fjellstrom

With hardware acceleration, redoing the drawing in everything but Crysis level games is incredibly cheap. You have no reason to worry about optimizing drawing for most allegro games. Often, you'll spend more cpu cycles worrying about what not to draw, than it'll take to just draw everything.

mickwa

Now it is clear. Thank You all for Your answers! ;D

Thread #611572. Printed from Allegro.cc