Page 1 of 1

Intro to allegro. As per thread--Request a C++ tutorial Rate Topic: -----

#1 polymath  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 52
  • View blog
  • Posts: 670
  • Joined: 04-April 08

Posted 24 June 2008 - 02:57 PM

Allegro is a game programming library that is widly used to create graphics and such. To download it, i'd reccomend the binaries at www.allegro.cc/files .

That is as simple as copying and pasting into the correct folder. If they don't have a binary fo your compiler, you can download the source and build it.

Don't you love open source projects! :)

You kinda need to have a basic understanding of C to "get" this tutorial.

With that settled, let's begin. A sample allegro program, which i'll dissect in a second, is right here:
#include <allegro.h>
#define SCREENWIDTH 640
#define SCREENHEIGHT 480

int main() {
	allegro_init();
	install_keyboard();
	set_gfx_mode( GFX_AUTODETECT, SCREENWIDTH, SCREENHEIGHT, 0, 0);
	acquire_screen();
	textout_ex(screen, font, "Hello World!", 10, 10, makecol(255, 0, 0), makecol(0, 0, 0));
	textout_ex(screen, font, "Press Escape To Exit.", 10, 20, makecol(255, 0, 0), makecol(0, 0, 0));
	release_screen();
	while ( !key[KEY_ESC] ) {
		clear_keybuf();
		acquire_screen();
		if ( key[KEY_Z] ) textout_ex(screen, font, "I caught you pressing Z!", 10, 30, makecol(255,0,0), makecol(0,0,0));
		release_screen();
		rest(100);
	}
	return 0;
}
END_OF_MAIN();



SO... WHAT DOES THIS ALL MEAN!? Well, we obviously have to include the allegro library, which we do on line 1. For this program, allegro contains all the

functions we need. On lines two and three, I define two constants, screenwidth and screenheight. These make it easier to reference a full-screen mode.

Next, on line 5 is the main function. No questions there. Line 6 uses the function allegro_init();, which (obviously) gets allegro ready to work. Then,

on line 7, install_keyboard(); lets us find which keys are being pressed by the user. For line 8, set_gfx_mode(...) gets the screen ready. You should NOT

modify this beyond replacing the constants SCREENWIDTH and SCREENHEIGHT by the width and height you want the screen to be. Then we use acquire_screen(); to

tell allegro that we are going to be drawing to the screen. On the next two lines, we use textout_ex(...) to tell draw text to the screen, like printf

(...). The first arg is the bitmap we want to draw to, more on that later with buffering, so leave it with screen for now. The next arg is the font, which

you should leave to the default font, font (isn't that convenient) for now. Arg 3 is the string we want to display. Args 4 and 5 are the x and y

cordinates of the string you want to output, respectivly. NOTE: Anywhere x and y are referenced in allegro, the origin of the cordinates is the top-left

of the screen. In other words, the x cordinate is the distance in pixels from the LEFT of the screen and the y cordinate is the distance from the TOP of

the screen. The final two arguments to the textout_ex function are the font color and background color/highlighting of the text. We use the makecol

function to give us the color for 3*256 RGB values (the intensity of the red, then green, then blue, in a number between 0 and 255).

That sets up our screen. Thats quite a bit, huh!? But trust me, its a lot less than many other ways to make a screen. But now we want our window to stay

open. So we create a loop that executes as long as the exit condition is false. In this case, when <esc> is not depressed. So, we use while(!key

[KEY_ESC]). We could just leave it at that, but to demonstrate some other stuff, i've added other stuff in. In that loop (which runs as long as the screen

should stay open), we have five lines. The first of those, clear_keybuf(); will make sure that if a button has been released it will reset itself to not

being pressed. In other words, if i pressed the c key, it would say I pressed that key, but as soon as I released it, clear_keybuf() would tell the

computer I am no longer pressing it down. Thats a little of an oversimplification, but it works for now. We then use acquire_screen() again. Then, if the

user presses the Z key, we use the textout_ex function to output, "I caught you pressing Z!". Then we release the screen, and follow that up with a rest

statement to let the computer pause for 100 milliseconds. When the user presses the Escape key, the function will return 0 and terminate. The last line of

all is the END_OF_MAIN(); function call. This tells allegro that we're done. For compiling, this must be AFTER the main function in the global section.

Oh, did i mention that if you just want them to press ANY key, and wait until they do, you can use the readkey(); function. Its kind of like getch().

Now we're all done. As you can see, there is quite a bit of work behind that little bit of code that allegro is doing for us. Nice, huh!? In case you

want to use keys other than escape and z, the keys that allegro recognizes are:

KEY_A - KEY_Z,
KEY_0 - KEY_9,
KEY_0_PAD - KEY_9_PAD,
KEY_F1 - KEY_F12,

KEY_ESC, KEY_TILDE, KEY_MINUS, KEY_EQUALS,
KEY_BACKSPACE, KEY_TAB, KEY_OPENBRACE, KEY_CLOSEBRACE,
KEY_ENTER, KEY_COLON, KEY_QUOTE, KEY_BACKSLASH,
KEY_BACKSLASH2, KEY_COMMA, KEY_STOP, KEY_SLASH,
KEY_SPACE,

KEY_INSERT, KEY_DEL, KEY_HOME, KEY_END, KEY_PGUP,
KEY_PGDN, KEY_LEFT, KEY_RIGHT, KEY_UP, KEY_DOWN,

KEY_SLASH_PAD, KEY_ASTERISK, KEY_MINUS_PAD,
KEY_PLUS_PAD, KEY_DEL_PAD, KEY_ENTER_PAD,

KEY_PRTSCR, KEY_PAUSE,

KEY_ABNT_C1, KEY_YEN, KEY_KANA, KEY_CONVERT, KEY_NOCONVERT,
KEY_AT, KEY_CIRCUMFLEX, KEY_COLON2, KEY_KANJI,

KEY_LSHIFT, KEY_RSHIFT,
KEY_LCONTROL, KEY_RCONTROL,
KEY_ALT, KEY_ALTGR,
KEY_LWIN, KEY_RWIN, KEY_MENU,
KEY_SCRLOCK, KEY_NUMLOCK, KEY_CAPSLOCK

KEY_EQUALS_PAD, KEY_BACKQUOTE, KEY_SEMICOLON, KEY_COMMAND

You can put any of these into the brackets for the array key[]. By the way, KEY_LEFT, KEY_RIGHT, KEY_UP, and KEY_DOWN are the arrow keys.

So, we've seen that you can all allegro is is plain old C with a few extra functions. You can use variables of all the standard types, too, and you can use

normal control structures. Now, lets move on to some more drawing functions.

Allegro allows us to create bitmaps for our own use, and has a structure and a few functions for them as well. To create a bitmap use BITMAP *

nameOfBMP;
, and then use the function nameOfBMP=create_bitmap(width, height);. Then, to draw it to another bitmap (which can be

the screen), use draw_sprite(BMPtoDrawTo, nameOfBMP, x, y);. An advantage of drawing everything to a bitmap and then drawing that to the

screen is that it eliminates the flickering that can occur when drawing to the screen often. This is called double buffering. Our previous code can

implement a double buffered system using this code. Here's some bitmaps in action.

#include <allegro.h>
#define SCREENWIDTH 640
#define SCREENHEIGHT 480

int main() {
	allegro_init();
	BITMAP * buffer;
	buffer=create_bitmap(SCREENWIDTH, SCREENHEIGHT);
	install_keyboard();
	set_gfx_mode( GFX_AUTODETECT, SCREENWIDTH, SCREENHEIGHT, 0, 0);
	acquire_screen();
	textout_ex(buffer, font, "Hello World!", 10, 10, makecol(255, 0, 0), makecol(0, 0, 0));
	textout_ex(buffer, font, "Press Escape To Exit.", 10, 20, makecol(255, 0, 0), makecol(0, 0, 0));
	draw_sprite(screen, buffer, 0, 0);
	release_screen();
	while ( !key[KEY_ESC] ) {
		clear_keybuf();
		acquire_screen();
		draw_sprite(buffer, screen, 0, 0); //this syncs the screen and the buffer
		if ( key[KEY_Z] ) textout_ex(buffer, font, "I caught you pressing Z!", 10, 30, makecol(255,0,0), makecol(0,0,0));
		draw_sprite(screen, buffer, 0, 0); //then redraws the result
		release_screen();
		rest(100);
	}
	return 0;
}
END_OF_MAIN();



To draw primitives, use the line, triangle, polygon, rect, rectfill, elipse, elipsefill, circle, circlefill, arc, and floodfill functions. Since you know

about bitmaps, you should be able to understand the allegro documentation with a few abridgements. Here are the function definitions:

Quote

------------------------------------------------------------------

void line(BITMAP *bmp, int x1, int y1, int x2, int y2, int color);

Draws a line onto the bitmap, from point (x1, y1) to (x2, y2).

------------------------------------------------------------------

void triangle(BITMAP *bmp, int x1, y1, x2, y2, x3, y3, int color);

Draws a filled triangle between the three points. This is a non-filled triangle.

------------------------------------------------------------------

void polygon(BITMAP *bmp, int vertices, const int *points, int color);

Draws a filled polygon with an arbitrary number of corners. Pass the number of vertices and an array containing a series of x, y points (a total of

vertices*2 values). Example for a pentagon:

int points[10];

points[0]=100;
points[1]=100;
points[2]=200;
points[3]=100;
points[4]=200;
points[5]=200; //Will draw between points (100,100), (200,100), (200,200), (150,250), (100,200)
points[6]=150;
points[7]=250;
points[8]=100;
points[9]=200;

polygon(screen, 5, points, makecol(0, 0, 0));

------------------------------------------------------------------

void rect(BITMAP *bmp, int x1, int y1, int x2, int y2, int color);

Draws an outline rectangle with the two points as its opposite corners.

------------------------------------------------------------------

void rectfill(BITMAP *bmp, int x1, int y1, int x2, int y2, int color);

Draws a solid, filled rectangle with the two points as its opposite corners.

------------------------------------------------------------------

void circle(BITMAP *bmp, int x, int y, int radius, int color);

Draws a circle with the specified centre and radius.

------------------------------------------------------------------

void circlefill(BITMAP *bmp, int x, int y, int radius, int color);

Draws a filled circle with the specified centre and radius.

------------------------------------------------------------------

void ellipse(BITMAP *bmp, int x, int y, int rx, int ry, int color);

Draws an ellipse with the specified centre and radius.

------------------------------------------------------------------

void ellipsefill(BITMAP *bmp, int x, int y, int rx, int ry, int color);

Draws a filled ellipse with the specified centre and radius.

------------------------------------------------------------------

void arc(BITMAP *bmp, int x, y, fixed ang1, ang2, int r, int color);

Draws a circular arc with centre x, y and radius r, in an anticlockwise direction starting from the angle a1 and ending when it reaches a2. These values are

specified in 16.16 fixed point format, with 256 equal to a full circle, 64 a right angle, etc. Zero is to the right of the centre point, and larger values

rotate anticlockwise from there.

------------------------------------------------------------------

void floodfill(BITMAP *bmp, int x, int y, int color);

Floodfills an enclosed area, starting at point (x, y), with the specified color.

------------------------------------------------------------------


Thats primitives. Pretty simple. Hope I haven't gone too fast. If you noticed, color is actually an integer. Interesting...

Now, for some pixel functions. The most useful is this family of functions: getpixel, getr, getg, getb, putpixel. The function getpixel gets the color of

a pixel on a bitmap. It's syntax is getpixel(BITMAP * bmp, x, y); which gets the color value of pixel (x,y) on bitmap bmp. Then, you can use getr, getg,

and getb on that color to extract the intensity of a color. Think of getr/g/b as the reverse makecol(). Then, putpixel() is used to draw a pixel at the

designated location with the designated color. This function's syntax is putpixel(BITMAP * bmp, x, y, color); you can figure this one out easy. Using these

all together, we get:
//Two options. Both take a pixel from buffer and draw it to screen in the same color, the pixel is at (5,5)

//option 1, uses getr, getb, getg. Note they are unneeded in this case but are used for demonstration purposes.
int color;
int r, g, b;
color=getpixel(buffer, 5, 5);
r=getr(color);
g=getg(color);
b=getb(color);
putpixel(screen, 5, 5, makecol(r, g, B)/>);

//option 2, doesn't use getr/g/b which is unneeded in this case, and eliminates code, but you cannot manipulate the intensities this way
putpixel(screen, 5, 5, getpixel(buffer, 5, 5));


Option 1 is much more flexible and easy to change (say i wanted to add 5 to each color value? couldn't do that with option 2), but is also more code

intensive. Your choice.

One last thing. The bitmap structure. Documentation on ALL allegro structures can be found at

http://docs.mandrago...o/index001.html . If you want to extract the width and height of a bitmap, simply exploit

the structure. To store the height of bitmap bmp to variable height, use height=bmp->h;, which gets the structure value. Similarly, for

width, use width=bmp->w;. Pretty simple, after all.

By now, you know egnough to figure out this snippet: http://www.dreaminco...snippet2060.htm

If you can see what its doing, I have achieved what I wanted with the tutorial. More to come!

Is This A Good Question/Topic? 0
  • +

Replies To: Intro to allegro.

#2 ZachR  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 2
  • View blog
  • Posts: 126
  • Joined: 15-June 08

Posted 29 June 2008 - 05:00 PM

Very nice post! Thanks! :D
Was This Post Helpful? 0
  • +
  • -

#3 polymath  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 52
  • View blog
  • Posts: 670
  • Joined: 04-April 08

Posted 03 July 2008 - 01:31 PM

Your welcome B) Also, I'll add mouse functions too, so you can get input from the mouse!
Was This Post Helpful? 0
  • +
  • -

#4 ZachR  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 2
  • View blog
  • Posts: 126
  • Joined: 15-June 08

Posted 03 July 2008 - 03:35 PM

View Postpolymath, on 3 Jul, 2008 - 12:31 PM, said:

Your welcome B) Also, I'll add mouse functions too, so you can get input from the mouse!

Alright, cool. :D
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1