The Allegro Wiki is migrating to github at https://github.com/liballeg/allegro_wiki/wiki

Page flipping

From Allegro Wiki
Jump to: navigation, search

Overview

Page flipping is a method of updating the screen that uses two full screen video bitmaps (referred to as pages). You alternate between the two pages, drawing on one while viewing the other.

Implementation

You must use the v_w and v_h parameters to set_gfx_mode, which set the virtual screen resolution. This way Allegro can be sure to allocate sufficient video memory for your game. For page flipping, you will want twice the space as normal, so if your screen size is 640x480, you would want to set the virtual size to either 1280x480 or 640x960. Note that in one the width was doubled, and the other it was the height. Either of these virtual resolutions should provide the same result.

<highlightSyntax language="C"> set_gfx_mode(GFX_AUTODETECT, 640, 480, 1280, 480); </highlightSyntax>

After setting the video mode, the first thing you'll need to do is create two full screen video bitmaps:

<highlightSyntax language="c"> video_page[0] = create_video_bitmap(SCREEN_W, SCREEN_H); video_page[1] = create_video_bitmap(SCREEN_W, SCREEN_H); </highlightSyntax>

Next, you'll need to pick one of them to start off as the off-screen buffer.

<highlightSyntax language="c"> current_page = 0; </highlightSyntax>

Now video_page[current_page] will point to the one you are supposed to draw on. After you have done all of your drawing, you must flip to the current_page.

<highlightSyntax language="c"> show_video_bitmap(video_page[current_page]); current_page = 1-current_page; </highlightSyntax>

Notes

  • Never use the default screen BITMAP while using page flipping.
  • show_video_bitmap() automatically calls vsync(). You can disable this before with the graphics.disable_vsync configuration option.
  • Reading from video bitmaps is very slow. So try to avoid ever reading from one of your pages (eg. using transcluent drawing).
  • Page flipping is very similar to double and triple buffering. Therefore, its quite simple to create an API that allows your program to use any one of the three.

Demo

<highlightSyntax language="c">

  1. include <allegro.h>

BITMAP *video_page[2]; BITMAP *offscreen; int offscreen_page;

void flip_page(void) { // flip to the buffer show_video_bitmap(offscreen);

// set the buffer to the other page offscreen = video_page[offscreen_page = 1 - offscreen_page]; }

int init_page_flipping() { // create pages for page flipping video_page[0] = create_video_bitmap(SCREEN_W, SCREEN_H); if (!video_page[0]) return FALSE;

video_page[1] = create_video_bitmap(SCREEN_W, SCREEN_H); if (!video_page[1]) { destroy_bitmap(video_page[0]); return FALSE; }

// initialize the buffer offscreen = video_page[offscreen_page = 0]; flip_page();

return TRUE; }

int main() { int x, y;

// install allegro, set graphics mode, etc allegro_init(); install_keyboard();

set_color_depth(32); if (set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640,480, 1280,480)) { allegro_message("Unable to set graphics mode.\n"); return 1; }

// initialize page flipping if (!init_page_flipping()) { set_gfx_mode(GFX_TEXT,0,0,0,0); allegro_message("Unable to initialize page flipping.\n"); return 1; }

// default coordinates for the rectangle x = SCREEN_W / 2 - 5; y = SCREEN_H / 2 - 5;

// main game loop while (!key[KEY_ESC]) { // game logic if (key[KEY_LEFT] && x) --x; if (key[KEY_RIGHT] && x < SCREEN_W-10) ++x; if (key[KEY_UP] && y) --y; if (key[KEY_DOWN] && y < SCREEN_H-10) ++y;

// you draw everything to offscreen clear(offscreen); rect(offscreen, x,y, x+9,y+9, makecol(255,255,255)); textout_centre_ex(offscreen, font, "Use arrow keys to move box. ESC to quit.", SCREEN_W/2, SCREEN_H/2, makecol(255,255,255), -1);

// show the offscreen page flip_page(); }

return 0; } END_OF_MAIN() </highlightSyntax>

See Also