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

Hardware Accelerated Allegro (AllegroGL)

From Allegro Wiki
Revision as of 13:43, February 15, 2008 by CGamesPlay (talk | contribs) (editing)
Jump to: navigation, search
Merge-arrows.gif
It has been suggested that this article or section be merged with AllegroGL. (Discuss)

This article shows how can you get advantages of hardware accelerated rendering using mostly plain Allegro 4.x API, which you are familiar with. Allegro's drawing API can use OpenGL commands to do the rendering on the screen and video bitmaps. This requires you to have AllegroGL installed, alongside with Allegro, but no OpenGL knowledge is needed. Note that the actual hardware acceleration you will get highly depends on OpenGL implementation on your system, i.e. if you don't have proper drivers installed software rendering will be used, which can be slow and even broken.

Requirements

In order to make Allegro use OpenGL to do the drawing, you will need one of the following two configuration:

  • Allegro 4.2.1 or newer + AllegroGL 0.4.2 or newer
This is the only possible configuration at the time of writing this article. AllegroGL is available as a separate download and has to be installed after you have installed Allegro.
  • Allegro 4.4.x with AllegroGL enabled
Allegro 4.4.x is the forthcoming Allegro branch, aiming to fill a time whole before the Allegro5 comes out. It has AllegroGL (and some other libraries) bundled in the package, with integrated build system for easier use. It isn't available at the time of writing this article. A development (WIP) series 4.3.10+ can also be used.

As AllegroGL is, especially its Allegro driver, under heavy development it is highly recommended that you use the latest version available. Also, keep in mind that AllegroGL's Allegro driver module is quite untested and still in development, so if you notice any bugs or you have problems using it, please report it to AllegroGL developers through the Mailing List, A.cc forums, SF.tracker...

A very special "hello world"

<highlightSyntax language="c">

  1. include <allegro.h>
  2. include <alleggl.h>

int main() {

  if (allegro_init() != 0) {
     return 1;
  }
  if (install_allegro_gl() != 0) {
     return 1;
  }
  install_keyboard();
  install_timer();
  allegro_gl_set(AGL_DOUBLEBUFFER, 1);
  allegro_gl_set(AGL_WINDOWED, TRUE);
  allegro_gl_set(AGL_COLOR_DEPTH, 32);
  allegro_gl_set(AGL_SUGGEST, AGL_DOUBLEBUFFER | AGL_WINDOWED | AGL_COLOR_DEPTH);
  if(set_gfx_mode(GFX_OPENGL, 800, 600, 0, 0)) {
      allegro_message ("Error setting OpenGL graphics mode:\n%s\n"
                       "Allegro GL error : %s\n",
                       allegro_error, allegro_gl_error);
      exit(0);
  }
  allegro_gl_set_allegro_mode();
  textout_ex(screen, font, "Hello World!", 50, 100, makecol(255, 0, 0), -1);
  allegro_gl_unset_allegro_mode();
  allegro_gl_flip();
  readkey();
  return 0;

} END_OF_MAIN() </highlightSyntax>

If you are not familiar with AllegroGL API this code could look quite scary. Let's just say that the code above the textout_ex() call is a standard initialization code you can find in any AllegroGL tutorial and it suggests windowed, double buffered, 32-bit GFX mode. The code bellow the textout_ex() call just flips the buffers and waits for the key press. Refer the AllegroGL tutorials and documentation for more details on AllegroGL functions in this example. Note that although this code may look complicated to you and full of unknown AllegroGL functions, this is all that is required for a AllegroGL program to work. No matter how complex your further development of the program is, this initialization code will remain the same - just a small part of your program.

It's the code between allegro_gl_set_allegro_mode(); and allegro_gl_unset_allegro_mode(); what makes this Hello World so special. As you notice, textout_ex() is a normal Allegro API. What is not so normal about it is that it is executed using OpenGL commands, which gives as a hope that it may be hardware accelerated! Any Allegro function you place in there, that draws to a video bitmap or to the screen BITMAP*, will use OpenGL commands for rendering. For more complex examples you can look at exblend and exalleg AllegroGL examples, or at the Skater Allegro demo program.

Differences in API

For various reasons, some of the Allegro API won't behave as documented, or as you expect them to behave based on your experience.

  • Video Bitmaps
    • Video bitmaps are not allocated from the same space as the screen BITMAP*.
    • Video bitmaps are not always of the same color depth as the screen BITMAP*.
    Their color depth depends on the allegro_gl_set_video_bitmap_color_depth() function. This lets you use video bitmaps with an alpha channel no matter what the current color depth is.
    • Video bitmaps consist of a texture memory (usually on a GFX chip) and a memory copy (in the RAM).
    This implies quite a few things. In general:
    Writing to (drawing to) a video bitmap will be slower then writing to the memory bitmap.
    Reading from (drawing from) a video bitmap will as fast as reading from a memory bitmap.
    • The restriction that allows only memory bitmaps for arguments to functions like drawing_mode(), polygon3d(), stretch_sprite()... is released. Video bitmaps are allowed too.
    • Translucent drawing is not extremely slow on video bitmaps. On the contrary, it's very fast.
    • In general, any drawing of video bitmaps on the screen will be fast.
  • Screen bitmap
    • When drawing something to the screen BITMAP*, it may not be displayed before allegro_gl_flip() is called.
    • When reading from the screen BITMAP* you are actually reading the previous frame, before the flip.
  • Misc
    • All allegro functions which involve video bitmaps or the screen BITMAP* have to be called inside the allegro_gl_set_allegro_mode()/allegro_gl_unset_allegro_mode() block.
    • Look at AllegroGL's bug.txt for differences due to bugs.
    • No need to call set_color_depth(), use AllegroGL functions to set color depth


Differences in game design

There are some patterns which you should follow when designing your game rendering code if you want to take advantage of OpenGL hardware acceleration.

First, the is no need for manual implementation of double buffering, page flipping, dirty rectangles or other screen update mechanisms used with normal Allegro games. All you need is to request AllegroGL's double buffering mode (note that "double buffering" in this context refers to whatever technique the native OpenGL engine uses) and OpenGL will manage buffers for you. All your drawing should be directed to the screen BITMAP*. The content of the screen BITMAP* will be displayed when you call allegro_gl_flip().

Completely redraw your screen every time. Keep in mind that the content of the screen BITMAP* is undefined after the flip.

Use video bitmaps as much as possible. It's recommended that you keep all your sprites in video bitmaps, where they will be easily accessible to the GFX chip. A typical sprite loading routine should look like: <highlightSyntax language="c"> /* Returns a pointer to video bitmap containing a sprite stored in a file named 'filename'. */ BITMAP *load_sprite(const char* filename) {

  BITMAP *tmp, *ret;
  /* convert the sprite to current format, unless it would lose alpha information */
  set_color_conversion(COLORCONV_KEEP_ALPHA);
  tmp = load_bitmap(filename, NULL);
  /* create a video bitmap of the same size and same color depth as the sprite */
  allegro_gl_set_video_bitmap_color_depth(bitmap_color_depth(tmp));
  ret = create_video_bitmap(tmp->w, tmp->h);
  allegro_gl_set_video_bitmap_color_depth(-1);
  /* blit a memory sprite to a video bitmap */
  blit(tmp, ret, 0, 0, 0, 0, tmp->w, tmp->h);
  destroy_bitmap(tmp);
  retrun ret;

} </highlightSyntax>

Try to reduce drawing to the video bitmaps. Drawing to video bitmaps is slow because it requires both uploading a texture fragment onto the GFX memory and updating the memory copy in the main memory.

Use AllegroGL FONTs (Allegro FONTs converted with allegro_gl_convert_allegro_font_ex()). Although you can use plain Allegro FONT* when writing to video bitmaps or to the screen BITMAP*, this is usually very slow.

Use translucent drawing with an alpha channel in favor of masked drawing. Translucent drawing is better supported and does not require expensive blending like software Allegro does.

Do not use 8-bit color depth. OpenGL doesn't deal with palettes any more.

You can also use plain OpenGL commands to do some rendering. This releases you from some Allegro's API limitations. You can do that outside allegro_gl_set_allegro_mode()/allegro_gl_unset_allegro_mode() pair.