lesson 3 basic 2d graphics programming with allegro

75
Lesson 3 Basic 2D Graphics Programming with Allegro

Upload: benjamin-prall

Post on 14-Dec-2015

232 views

Category:

Documents


0 download

TRANSCRIPT

Lesson 3

Basic 2D Graphics Programming with Allegro

Doing 2D with AllegroDoing 2D with Allegro

Because we are pushing the 2D Because we are pushing the 2D envelope to the limit in this course, it envelope to the limit in this course, it is fitting that we should start at the is fitting that we should start at the beginning and cover vector graphics. beginning and cover vector graphics.

The term The term vectorvector describes the CRT describes the CRT ((Cathode Ray Tube)Cathode Ray Tube) monitors of the monitors of the past and the vector graphics past and the vector graphics hardware built into the computers hardware built into the computers that used this early technology. that used this early technology.

Doing 2D with AllegroDoing 2D with Allegro

A A graphics primitivegraphics primitive is a function that is a function that draws a simple geometric shape, draws a simple geometric shape, such as a point, line, rectangle, or such as a point, line, rectangle, or circle. circle.

I should point out also that these I should point out also that these graphics primitives form the basis of graphics primitives form the basis of all 3D graphics, past and present; all 3D graphics, past and present; after all, the mantra of the 3D card is after all, the mantra of the 3D card is the holy polygon. the holy polygon.

Video CardsVideo Cards

The fact of the matter is that video cards The fact of the matter is that video cards are not designed to render games; they are not designed to render games; they are designed to render geometric are designed to render geometric primitives with special effects. As far as primitives with special effects. As far as the video card is concerned, there is only the video card is concerned, there is only one triangle on the screen. one triangle on the screen.

It is the programmer who tells the video It is the programmer who tells the video card to move from one triangle to the card to move from one triangle to the next. The video card does this so quickly next. The video card does this so quickly (on the order of 100 million or more (on the order of 100 million or more polygons per second) that it fools the polygons per second) that it fools the viewer into believing that the video card is viewer into believing that the video card is rendering an entire scene on its own. rendering an entire scene on its own.

Video CardsVideo Cards

The triangles are hidden away in the The triangles are hidden away in the matrix of the scene (so to speak), matrix of the scene (so to speak), and it is becoming more and more and it is becoming more and more difficult to discern reality from virtual difficult to discern reality from virtual reality due to the advanced features reality due to the advanced features built into the latest graphics chips.built into the latest graphics chips.

Xbox 360Xbox 360

The Xbox 360 can The Xbox 360 can crunch through 3 crunch through 3 trillion operations trillion operations per second with per second with its triple-core, its triple-core, hexa-threaded hexa-threaded processor.processor.

Taken a step closer, each triangle is made up of three vertices, which is really all the graphics chip cares about.

Filling pixels between the three points and applying effects (such as lighting) are tasks that the graphics chip has been designed to do quickly and efficiently.

VerticesVertices

2D Acceleration2D Acceleration

The earliest The earliest Windows acceleratorsWindows accelerators, as they , as they were known, produced for Windows 3.1 and were known, produced for Windows 3.1 and Windows 95 provided hardware blitting. Windows 95 provided hardware blitting. BlitBlit is a term that means bit-block transfer, a is a term that means bit-block transfer, a method of transferring a chunk of memory method of transferring a chunk of memory from one place to another. from one place to another.

In the case of a graphical blit, the process In the case of a graphical blit, the process involves copying a chunk of data from involves copying a chunk of data from system memory through the bus to the system memory through the bus to the memory present on the video card. In the memory present on the video card. In the early years of the PC, video cards were early years of the PC, video cards were lucky to have 1 MB of memory.lucky to have 1 MB of memory.

Video MemoryVideo Memory

Contrast this with the latest 3D cards that Contrast this with the latest 3D cards that have 256 MB of DDR (have 256 MB of DDR (Double Data RateDouble Data Rate) ) memory and are enhanced with direct memory and are enhanced with direct access to the AGP bus! access to the AGP bus!

It simply must be as fast as possible to It simply must be as fast as possible to keep feeding the ravenous graphics chip, keep feeding the ravenous graphics chip, which eats textures in video memory and which eats textures in video memory and spews them out into the frame buffer, spews them out into the frame buffer, which is sent directly to the screen.which is sent directly to the screen.

Parallel ProcessingParallel Processing

In a very real sense, the graphics card In a very real sense, the graphics card is a small computer on its own. When is a small computer on its own. When you consider that the typical high-end you consider that the typical high-end PC also has a high-performance sound PC also has a high-performance sound processing card (such as the Sound processing card (such as the Sound Blaster Audigy 2 by Creative Labs) Blaster Audigy 2 by Creative Labs) capable of Dolby DTS and Dolby capable of Dolby DTS and Dolby Digital 5.1 surround sound, what we Digital 5.1 surround sound, what we are really talking about here is a multi-are really talking about here is a multi-processor system. processor system.

Graphics FundamentalsGraphics Fundamentals

The basis of this entire chapter can The basis of this entire chapter can be summarized in a single word: be summarized in a single word: pixelpixel. .

The word "pixel" is short for "picture The word "pixel" is short for "picture element," sort of the atomic element element," sort of the atomic element of the screen. of the screen.

The pixel is the smallest unit of The pixel is the smallest unit of measurement in a video system. measurement in a video system.

Graphics FundamentalsGraphics Fundamentals

But like the atom you know from physics, But like the atom you know from physics, even the smallest building block is even the smallest building block is comprised of yet smaller things. comprised of yet smaller things.

In the case of a pixel, those quantum In the case of a pixel, those quantum elements of the pixel are red, green, and elements of the pixel are red, green, and blue electron streams that give each pixel a blue electron streams that give each pixel a specific color. specific color.

This is not mere theory or analogy; each This is not mere theory or analogy; each pixel is comprised of three small streams of pixel is comprised of three small streams of electrons of varying shades of red, green, electrons of varying shades of red, green, and blue and blue

Allegro GraphicsAllegro Graphics

Starting with this most basic building Starting with this most basic building block, you can construct an entire block, you can construct an entire game one pixel at a time.game one pixel at a time.

Allegro creates a global screen Allegro creates a global screen pointer when you call pointer when you call allegro_initallegro_init. .

This simple pointer is called This simple pointer is called screenscreen, , and you can pass it to all of the and you can pass it to all of the drawing functions. drawing functions.

Allegro GraphicsAllegro Graphics

A technique called double-buffering A technique called double-buffering (which uses off-screen rendering for (which uses off-screen rendering for speed) works like this: drawing speed) works like this: drawing routines must draw out to a memory routines must draw out to a memory bitmap, which is then blitted to the bitmap, which is then blitted to the screen in a single function call. screen in a single function call.

Until you start using a double buffer, Until you start using a double buffer, you'll just work with the global you'll just work with the global screenscreen object. object.

Setting Graphics ModeSetting Graphics Mode

The first function you'll learn about is The first function you'll learn about is set_gfx_modeset_gfx_mode, which sets the graphics mode., which sets the graphics mode.

This function is really loaded, although you This function is really loaded, although you would not know that just from calling it.would not know that just from calling it.

set_gfx_modeset_gfx_mode does a lot of work when called: does a lot of work when called: detecting the graphics carddetecting the graphics card identifying and initializing the graphics systemidentifying and initializing the graphics system verifying or setting the color depthverifying or setting the color depth entering full-screen or windowed modeentering full-screen or windowed mode setting the resolutionsetting the resolution

Setting Graphics ModeSetting Graphics Mode

A comparable DirectX initialization is A comparable DirectX initialization is 20 to 30 lines of code. 20 to 30 lines of code.

This function has the following This function has the following declaration:declaration: int set_gfx_mode(int card, int w, int h, int v_w, int v_h);int set_gfx_mode(int card, int w, int h, int v_w, int v_h);

Setting Graphics ModeSetting Graphics Mode

If an error occurs setting a particular video If an error occurs setting a particular video mode, mode, set_gfx_modeset_gfx_mode will return a non-zero will return a non-zero value (0 is success) and store an error value (0 is success) and store an error message in message in allegro_errorallegro_error, which you can , which you can then print out. then print out.

For an example, try using an invalid For an example, try using an invalid resolution for a full-screen display, like resolution for a full-screen display, like this:this:

ret = set_gfx_mode(GFX_AUTODETECT_FULLSCREEN, 645, 485, 0, ret = set_gfx_mode(GFX_AUTODETECT_FULLSCREEN, 645, 485, 0, 0);0);

Setting Graphics ModeSetting Graphics Mode

However, if you specify However, if you specify GFX_AUTODETECTGFX_AUTODETECT and send an invalid width and height to and send an invalid width and height to set_gfx_modeset_gfx_mode, it will actually run in a , it will actually run in a window with the resolution you wanted.window with the resolution you wanted.

Running in windowed mode is a good idea Running in windowed mode is a good idea when you are testing a game and you when you are testing a game and you don't want it to jump into and out of full-don't want it to jump into and out of full-screen mode every time you run the screen mode every time you run the program.program.

Setting Graphics ModeSetting Graphics Mode

The first parameter, The first parameter, int cardint card, specifies the , specifies the display mode (or the video card in a dual-display mode (or the video card in a dual-card configuration) and will usually be card configuration) and will usually be GFX_AUTODETECTGFX_AUTODETECT. .

If you want a full-screen display, you can If you want a full-screen display, you can use use GFX_AUTODETECT_FULLSCREENGFX_AUTODETECT_FULLSCREEN, , while you can invoke a windowed display while you can invoke a windowed display using using GFX_AUTODETECT_WINDOWEDGFX_AUTODETECT_WINDOWED. .

Setting Graphics ModeSetting Graphics Mode

The next two parameters, The next two parameters, int wint w and and int hint h, specify the desired resolution, , specify the desired resolution, such as 640x480, 800x600, or such as 640x480, 800x600, or 1024x768. 1024x768.

The final two parameters, The final two parameters, int v_wint v_w and and int v_hint v_h, specify the virtual , specify the virtual resolution and are used to create a resolution and are used to create a large virtual screen for hardware large virtual screen for hardware scrolling or page flipping. scrolling or page flipping.

Setting Graphics ModeSetting Graphics Mode

After you have called After you have called set_gfx_modeset_gfx_mode to change the video mode, Allegro to change the video mode, Allegro populates the variables populates the variables SCREEN_WSCREEN_W, , SCREEN_HSCREEN_H, , VIRTUAL_WVIRTUAL_W, and , and VIRTUAL_HVIRTUAL_H with the appropriate with the appropriate values, which come in handy when values, which come in handy when you prefer not to hard-code the you prefer not to hard-code the screen resolution in your programs.screen resolution in your programs.

#include "allegro.h"#include "allegro.h"void main(void)void main(void){{

allegro_init(); //initialize Allegroallegro_init(); //initialize Allegro install_keyboard(); //initialize the keyboardinstall_keyboard(); //initialize the keyboard

//initialize video mode to 640x480//initialize video mode to 640x480 int ret = set_gfx_mode(GFX_AUTODETECT_WINDOWED, int ret = set_gfx_mode(GFX_AUTODETECT_WINDOWED,

640, 480, 0, 0);640, 480, 0, 0); if (ret != 0) {if (ret != 0) { allegro_message(allegro_error);allegro_message(allegro_error); return;return; }}

//display screen resolution//display screen resolution textprintf(screen, font, 0, 0, makecol(255, 255, 255), textprintf(screen, font, 0, 0, makecol(255, 255, 255), "%dx%d", SCREEN_W, SCREEN_H);"%dx%d", SCREEN_W, SCREEN_H);

while(!key[KEY_ESC]);while(!key[KEY_ESC]);allegro_exit();allegro_exit();

}}END_OF_MAIN();END_OF_MAIN();

textprintftextprintf

Another interesting function is Another interesting function is textprintftextprintf,, which, as you might have which, as you might have guessed, displays a message in any guessed, displays a message in any video mode. video mode.

The first parameter specifies the The first parameter specifies the destination, which can be the destination, which can be the physical display screen or a memory physical display screen or a memory bitmap. bitmap.

void textprintf(BITMAP *bmp, const FONT *f, int x, y, color, void textprintf(BITMAP *bmp, const FONT *f, int x, y, color, const char *fmt, ...);const char *fmt, ...);

ColorsColors

You might have noticed a function called You might have noticed a function called makecolmakecol. This function creates an RGB . This function creates an RGB color using the component colors passed color using the component colors passed to it.to it.

If you want to define custom colors you If you want to define custom colors you can create your own colors like this:can create your own colors like this:

#define COLOR_BROWN #define COLOR_BROWN makecol(174,123,0)makecol(174,123,0)

allegro_exitallegro_exit

The last function that you should be aware The last function that you should be aware of is of is allegro_exitallegro_exit, which shuts down the , which shuts down the graphics system and destroys the memory graphics system and destroys the memory used by Allegro. used by Allegro.

In theory, the destructors will take care of In theory, the destructors will take care of removing everything from memory, but it’s a removing everything from memory, but it’s a good idea to call this function explicitly. One good idea to call this function explicitly. One very important reason why is for the benefit very important reason why is for the benefit of restoring the video display. of restoring the video display.

(Failure to call (Failure to call allegro_exitallegro_exit might leave the might leave the desktop in an altered resolution or color desktop in an altered resolution or color depth depending on the graphics card being depth depending on the graphics card being used.)used.)

Drawing BitmapsDrawing Bitmaps

Use the load_bitmap function to load Use the load_bitmap function to load an image file (multiple formats an image file (multiple formats supported).supported).

Then use the blit function to draw the Then use the blit function to draw the bitmap.bitmap.

I’ll go over bitmaps and sprites in I’ll go over bitmaps and sprites in more detail in the next lesson.more detail in the next lesson.

#include "allegro.h"#include "allegro.h"void main(void)void main(void){{ char *filename = "allegro.pcx";char *filename = "allegro.pcx"; int colordepth = 32;int colordepth = 32;

BITMAP *image;BITMAP *image; int ret;int ret;

allegro_init(); allegro_init(); install_keyboard(); install_keyboard(); set_color_depth(colordepth);set_color_depth(colordepth);

ret = set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0);ret = set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0); if (ret != 0) {if (ret != 0) { allegro_message(allegro_error);allegro_message(allegro_error); return;return; }}

//load the image file//load the image file image = load_bitmap(filename, NULL);image = load_bitmap(filename, NULL); if (!image) {if (!image) { allegro_message("Error loading %s", filename);allegro_message("Error loading %s", filename); return;return; }}

//display the image//display the image blit(image, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);blit(image, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);

//done drawing--delete bitmap from memory//done drawing--delete bitmap from memory destroy_bitmap(image);destroy_bitmap(image);

//draw font with transparency//draw font with transparency text_mode(-1);text_mode(-1); //display video mode information//display video mode information textprintf(screen, font, 0, 0, makecol(255, 255, 255), textprintf(screen, font, 0, 0, makecol(255, 255, 255), "%dx%d %ibpp", SCREEN_W, SCREEN_H, colordepth);"%dx%d %ibpp", SCREEN_W, SCREEN_H, colordepth); //wait for keypress//wait for keypress while (!key[KEY_ESC]);while (!key[KEY_ESC]); //exit program//exit program allegro_exit();allegro_exit();}}END_OF_MAIN();END_OF_MAIN();

Loading A BitmapLoading A Bitmap

Obviously you'll need a PCX file to Obviously you'll need a PCX file to run this program. However, you can run this program. However, you can just as easily use a BMP, PCX, PNG, just as easily use a BMP, PCX, PNG, GIF, or JPG for the graphics file if you GIF, or JPG for the graphics file if you want because Allegro supports all of want because Allegro supports all of these formats! these formats!

Graphics PrimitivesGraphics Primitives

All of the graphics in a vector system All of the graphics in a vector system are comprised of lines (including are comprised of lines (including circles, rectangles, arcs, which are circles, rectangles, arcs, which are made up of small lines). made up of small lines).

Vector displays are contrasted with Vector displays are contrasted with bitmapped displays, in which the bitmapped displays, in which the screen is a bitmap array (the video screen is a bitmap array (the video buffer). On the contrary, a vector buffer). On the contrary, a vector system does not have a linear video system does not have a linear video buffer. buffer.

Drawing PixelsDrawing Pixels

The simplest graphics primitive is The simplest graphics primitive is obviously the pixel-drawing function, obviously the pixel-drawing function, and Allegro provides one:and Allegro provides one:

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

Drawing PixelsDrawing Pixels

while(!key[KEY_ESC])while(!key[KEY_ESC]) {{ //set a random location//set a random location x = 10 + rand() % (SCREEN_W-20);x = 10 + rand() % (SCREEN_W-20); y = 10 + rand() % (SCREEN_H-20);y = 10 + rand() % (SCREEN_H-20); //set a random color//set a random color red = rand() % 255;red = rand() % 255; green = rand() % 255;green = rand() % 255; blue = rand() % 255;blue = rand() % 255; color = makecol(red,green,blue);color = makecol(red,green,blue); //draw the pixel//draw the pixel putpixel(screen, x, y, color);putpixel(screen, x, y, color); }}

Drawing LinesDrawing Lines

The horizontal line-drawing function The horizontal line-drawing function is called is called hlinehline, while the vertical line , while the vertical line function is called vline:function is called vline:

void hline(BITMAP *bmp, int x1, int y, int x2, int void hline(BITMAP *bmp, int x1, int y, int x2, int color);color);

void vline(BITMAP *bmp, int x, int y1, int y2, int void vline(BITMAP *bmp, int x, int y1, int y2, int color);color);

Drawing LinesDrawing Lines

The special-case lines functions for The special-case lines functions for drawing horizontal and vertical lines are drawing horizontal and vertical lines are not used often. not used often.

The following line function will simply call The following line function will simply call hline or vline if the slope of the line is hline or vline if the slope of the line is perfectly horizontal or vertical: perfectly horizontal or vertical:

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

Drawing LinesDrawing Lines

while(!key[KEY_ESC])while(!key[KEY_ESC]) {{ //set a random location//set a random location x1 = 10 + rand() % (SCREEN_W-20);x1 = 10 + rand() % (SCREEN_W-20); y1 = 10 + rand() % (SCREEN_H-20);y1 = 10 + rand() % (SCREEN_H-20); x2 = 10 + rand() % (SCREEN_W-20);x2 = 10 + rand() % (SCREEN_W-20); y2 = 10 + rand() % (SCREEN_H-20);y2 = 10 + rand() % (SCREEN_H-20); //set a random color//set a random color red = rand() % 255;red = rand() % 255; green = rand() % 255;green = rand() % 255; blue = rand() % 255;blue = rand() % 255; color = makecol(red,green,blue);color = makecol(red,green,blue); //draw the line//draw the line line(screen, x1,y1,x2,y2,color);line(screen, x1,y1,x2,y2,color); }}

Drawing RectanglesDrawing Rectangles

The next logical step is a two-The next logical step is a two-dimensional object containing points dimensional object containing points in both the X-axis and the Y-axis. in both the X-axis and the Y-axis. Here is the Here is the rectrect function: function:

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

Drawing RectanglesDrawing Rectangles

while(!key[KEY_ESC])while(!key[KEY_ESC]) {{ //set a random location//set a random location x1 = 10 + rand() % (SCREEN_W-20);x1 = 10 + rand() % (SCREEN_W-20); y1 = 10 + rand() % (SCREEN_H-20);y1 = 10 + rand() % (SCREEN_H-20); x2 = 10 + rand() % (SCREEN_W-20);x2 = 10 + rand() % (SCREEN_W-20); y2 = 10 + rand() % (SCREEN_H-20);y2 = 10 + rand() % (SCREEN_H-20); //set a random color//set a random color red = rand() % 255;red = rand() % 255; green = rand() % 255;green = rand() % 255; blue = rand() % 255;blue = rand() % 255; color = makecol(red,green,blue);color = makecol(red,green,blue); //draw the rectangle//draw the rectangle rect(screen,x1,y1,x2,y2,color);rect(screen,x1,y1,x2,y2,color); }}

Drawing Filled RectanglesDrawing Filled Rectangles

Outlined rectangles are boring, if you Outlined rectangles are boring, if you ask me. They are almost too thin to ask me. They are almost too thin to be noticed when drawn. On the other be noticed when drawn. On the other hand, a true rectangle is filled in with hand, a true rectangle is filled in with a specific color! That is where the a specific color! That is where the rectfillrectfill function comes in handy: function comes in handy:

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

Line-Drawing Callback Line-Drawing Callback FeatureFeature

Allegro provides a really fascinating Allegro provides a really fascinating feature in that it will draw an abstract line feature in that it will draw an abstract line by firing off a call to a callback function of by firing off a call to a callback function of your making (in which, presumably, you your making (in which, presumably, you would want to draw a pixel at the specified would want to draw a pixel at the specified (x,y) location.(x,y) location.

To use the callback, you must call the To use the callback, you must call the do_linedo_line function, which looks like this:function, which looks like this:

void do_line(BITMAP *bmp, int x1, y1, x2, y2, void do_line(BITMAP *bmp, int x1, y1, x2, y2, int d, void (*proc))int d, void (*proc))

Line-Drawing Callback Line-Drawing Callback FeatureFeature

The callback function has this format:The callback function has this format:

void doline_callback(BITMAP *bmp, int x, int y, void doline_callback(BITMAP *bmp, int x, int y, int d)int d)

To use the callback, you want to call To use the callback, you want to call the the do_linedo_line function like you would function like you would call the normal call the normal lineline function, with the function, with the addition of the callback pointer as addition of the callback pointer as the last parameter. the last parameter.

Line-Drawing Callback Line-Drawing Callback FeatureFeature

To fully demonstrate how useful this can be, I To fully demonstrate how useful this can be, I wrote a short program that draws random wrote a short program that draws random lines on the screen. lines on the screen.

But before drawing each pixel of the line, a But before drawing each pixel of the line, a check is performed on the new position to check is performed on the new position to determine whether a pixel is already present. determine whether a pixel is already present.

This indicates an intersection or collision. This indicates an intersection or collision. When this occurs, the line is ended and a When this occurs, the line is ended and a small circle is drawn to indicate the small circle is drawn to indicate the intersection. intersection.

Line-Drawing Callback Line-Drawing Callback FeatureFeature

while(!key[KEY_ESC])while(!key[KEY_ESC]) {{ //set a random location//set a random location x1 = 10 + rand() % (SCREEN_W-20);x1 = 10 + rand() % (SCREEN_W-20); y1 = 10 + rand() % (SCREEN_H-20);y1 = 10 + rand() % (SCREEN_H-20); x2 = 10 + rand() % (SCREEN_W-20);x2 = 10 + rand() % (SCREEN_W-20); y2 = 10 + rand() % (SCREEN_H-20);y2 = 10 + rand() % (SCREEN_H-20); //set a random color//set a random color red = rand() % 255;red = rand() % 255; green = rand() % 255;green = rand() % 255; blue = rand() % 255;blue = rand() % 255; color = makecol(red,green,blue);color = makecol(red,green,blue); //draw the line using the callback function//draw the line using the callback function stop = 0;stop = 0; do_line(screen,x1,y1,x2,y2,color,*doline);do_line(screen,x1,y1,x2,y2,color,*doline); rest(200);rest(200); }}

Line-Drawing Callback Line-Drawing Callback FeatureFeature

//doline is the callback function for do_line//doline is the callback function for do_linevoid doline(BITMAP *bmp, int x, int y, int color)void doline(BITMAP *bmp, int x, int y, int color){{ if (!stop)if (!stop) {{ if (getpixel(bmp,x,y) == 0)if (getpixel(bmp,x,y) == 0) {{ putpixel(bmp, x, y, color);putpixel(bmp, x, y, color); rest(5);rest(5); }} elseelse {{ stop = 1;stop = 1; circle(bmp, x, y, 5, 7);circle(bmp, x, y, 5, 7); }} }}}}

Drawing Circles / EllipsesDrawing Circles / Ellipses

The circle function has this The circle function has this declaration:declaration: void circle(BITMAP *bmp, int x, int y, int radius, int void circle(BITMAP *bmp, int x, int y, int radius, int

color);color);

The hollow circle function is The hollow circle function is interesting, but really seeing the full interesting, but really seeing the full effect of circles requires the effect of circles requires the circlefillcirclefill function:function: void circlefill(BITMAP *bmp, int x, int y, int void circlefill(BITMAP *bmp, int x, int y, int

radius, int color);radius, int color);

Drawing Circles / EllipsesDrawing Circles / Ellipses

The ellipse function is similar to the The ellipse function is similar to the circle function, although the radius is circle function, although the radius is divided into two parameters, one for divided into two parameters, one for the horizontal and another for the the horizontal and another for the vertical:vertical:

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

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

Drawing Circles / EllipsesDrawing Circles / Ellipses

while(!key[KEY_ESC])while(!key[KEY_ESC]) {{ //set a random location//set a random location x = 30 + rand() % (SCREEN_W-60);x = 30 + rand() % (SCREEN_W-60); y = 30 + rand() % (SCREEN_H-60);y = 30 + rand() % (SCREEN_H-60); radiusx = rand() % 30;radiusx = rand() % 30; radiusy = rand() % 30;radiusy = rand() % 30; //set a random color//set a random color red = rand() % 255;red = rand() % 255; green = rand() % 255;green = rand() % 255; blue = rand() % 255;blue = rand() % 255; color = makecol(red,green,blue);color = makecol(red,green,blue); //draw the ellipse//draw the ellipse ellipsefill(screen, x, y, radiusx, radiusy, color);ellipsefill(screen, x, y, radiusx, radiusy, color); rest(25);rest(25); }}

Circle Callback FunctionCircle Callback Function

Allegro provides a circle-drawing Allegro provides a circle-drawing callback function just as it did with the callback function just as it did with the line callback function. To use line callback function. To use do_circledo_circle, you must declare a callback , you must declare a callback function and pass a pointer to this function and pass a pointer to this function to function to do_circle.do_circle. void docircle(BITMAP *bmp, int x, int y, void docircle(BITMAP *bmp, int x, int y,

int d)int d) void do_circle(BITMAP *bmp, int x, int y, void do_circle(BITMAP *bmp, int x, int y,

int radius, int d);int radius, int d);

Drawing Spline CurvesDrawing Spline Curves

The The splinespline function draws a set of function draws a set of curves based on a set of four input curves based on a set of four input points stored in an array. points stored in an array.

The function calculates a smooth The function calculates a smooth curve from the first set of points, curve from the first set of points, through the second and third, toward through the second and third, toward the fourth point:the fourth point:

void spline(BITMAP *bmp, const int points[8], int color);void spline(BITMAP *bmp, const int points[8], int color);

int points[8] = {0,240,300,0,200,0,639,240};int points[8] = {0,240,300,0,200,0,639,240}; int y1 = 0;int y1 = 0; int y2 = SCREEN_H;int y2 = SCREEN_H; int dir1 = 10;int dir1 = 10; int dir2 = -10;int dir2 = -10;

while(!key[KEY_ESC])while(!key[KEY_ESC]) {{ //modify the first spline point//modify the first spline point y1 += dir1;y1 += dir1; if (y1 > SCREEN_H) dir1 = -10; if (y1 > SCREEN_H) dir1 = -10; if (y1 < 0) dir1 = 10;if (y1 < 0) dir1 = 10; points[3] = y1;points[3] = y1; //modify the second spline point//modify the second spline point y2 += dir2;y2 += dir2; if (y2++ > SCREEN_H) dir2 = -10;if (y2++ > SCREEN_H) dir2 = -10; if (y2 < 0) dir2 = 10;if (y2 < 0) dir2 = 10; points[5] = y2;points[5] = y2; //draw the spline, pause, then erase it//draw the spline, pause, then erase it spline(screen, points, 15);spline(screen, points, 15); rest(30);rest(30); spline(screen, points, 0);spline(screen, points, 0); }}

Drawing TrianglesDrawing Triangles

You can draw triangles using the You can draw triangles using the triangletriangle function, which takes three function, which takes three (x,y) points and a color parameter:(x,y) points and a color parameter:

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

Drawing TrianglesDrawing Triangles

while(!key[KEY_ESC])while(!key[KEY_ESC]) {{ //set a random location//set a random location x1 = 10 + rand() % (SCREEN_W-20);x1 = 10 + rand() % (SCREEN_W-20); y1 = 10 + rand() % (SCREEN_H-20);y1 = 10 + rand() % (SCREEN_H-20); x2 = 10 + rand() % (SCREEN_W-20);x2 = 10 + rand() % (SCREEN_W-20); y2 = 10 + rand() % (SCREEN_H-20);y2 = 10 + rand() % (SCREEN_H-20); x3 = 10 + rand() % (SCREEN_W-20);x3 = 10 + rand() % (SCREEN_W-20); y3 = 10 + rand() % (SCREEN_H-20);y3 = 10 + rand() % (SCREEN_H-20); //set a random color//set a random color red = rand() % 255;red = rand() % 255; green = rand() % 255;green = rand() % 255; blue = rand() % 255;blue = rand() % 255; color = makecol(red,green,blue);color = makecol(red,green,blue); //draw the triangle//draw the triangle triangle(screen,x1,y1,x2,y2,x3,y3,color);triangle(screen,x1,y1,x2,y2,x3,y3,color); rest(100);rest(100); }}

Drawing PolygonsDrawing Polygons

You have already seen polygons in You have already seen polygons in action with the action with the TrianglesTriangles program, program, because any geometric shape with because any geometric shape with three or more points comprises a three or more points comprises a polygon. To draw polygons in Allegro, polygon. To draw polygons in Allegro, you use the you use the polygonpolygon function with a function with a pointer to an array of points: pointer to an array of points:

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

while(!key[KEY_ESC])while(!key[KEY_ESC]) {{ //set a random location//set a random location vertices[0] = 10 + rand() % (SCREEN_W-20);vertices[0] = 10 + rand() % (SCREEN_W-20); vertices[1] = 10 + rand() % (SCREEN_H-20);vertices[1] = 10 + rand() % (SCREEN_H-20); vertices[2] = vertices[0] + (rand() % 30)+50;vertices[2] = vertices[0] + (rand() % 30)+50; vertices[3] = vertices[1] + (rand() % 30)+50;vertices[3] = vertices[1] + (rand() % 30)+50; vertices[4] = vertices[2] + (rand() % 30)-100;vertices[4] = vertices[2] + (rand() % 30)-100; vertices[5] = vertices[3] + (rand() % 30)+50;vertices[5] = vertices[3] + (rand() % 30)+50; vertices[6] = vertices[4] + (rand() % 30);vertices[6] = vertices[4] + (rand() % 30); vertices[7] = vertices[5] + (rand() % 30)-100;vertices[7] = vertices[5] + (rand() % 30)-100; //set a random color//set a random color red = rand() % 255;red = rand() % 255; green = rand() % 255;green = rand() % 255; blue = rand() % 255;blue = rand() % 255; color = makecol(red,green,blue);color = makecol(red,green,blue); //draw the polygon//draw the polygon polygon(screen,4,vertices,color);polygon(screen,4,vertices,color); rest(50);rest(50); }}

Filling RegionsFilling Regions

The last function I want to introduce The last function I want to introduce to you in this chapter is to you in this chapter is floodfillfloodfill, , which fills in a region on the which fills in a region on the destination bitmap (which can be the destination bitmap (which can be the screen) with the color of your choice:screen) with the color of your choice:

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

Drawing TextDrawing Text

The The text_modetext_mode function sets text function sets text output to draw with an opaque or output to draw with an opaque or transparent background. transparent background.

Passing a value of -1 will set the Passing a value of -1 will set the background to transparent, while background to transparent, while passing any other value will set the passing any other value will set the background to a specific color. background to a specific color. int text_mode(int mode);int text_mode(int mode);

Drawing TextDrawing Text

The The textouttextout function is the basic text function is the basic text output function for Allegro. There are output function for Allegro. There are three alternate vesions that align the three alternate vesions that align the text in different ways:text in different ways:

void textout(BITMAP *bmp, const FONT *f, const char *s, int x, y, int void textout(BITMAP *bmp, const FONT *f, const char *s, int x, y, int color);color);

void textout_centre(BITMAP *bmp, const FONT *f, const char *s, int x, y, void textout_centre(BITMAP *bmp, const FONT *f, const char *s, int x, y, color);color);

void textout_right(BITMAP *bmp, const FONT *f, const char *s, int x, y, void textout_right(BITMAP *bmp, const FONT *f, const char *s, int x, y, color);color);

Drawing TextDrawing Text

A slightly different take on the matter of text A slightly different take on the matter of text output is textout_justify, which includes two X output is textout_justify, which includes two X coordinates, one for the left edge of the text coordinates, one for the left edge of the text and one for the right edge, along with the Y and one for the right edge, along with the Y position. position.

In effect, this function tries to draw the text In effect, this function tries to draw the text between the two points. This really is more between the two points. This really is more useful when you are using custom fonts.useful when you are using custom fonts.

void textout_justify(BITMAP *bmp, const FONT *f, void textout_justify(BITMAP *bmp, const FONT *f, const char *s, int x1, int x2, int y, int diff, int color);const char *s, int x1, int x2, int y, int diff, int color);

Drawing TextDrawing Text

Allegro provides several very useful Allegro provides several very useful text output functions that mimic the text output functions that mimic the standard C standard C printfprintf function, providing function, providing the capability of formatting the text the capability of formatting the text and displaying variables. The base and displaying variables. The base function is function is textprintftextprintf, and it looks like , and it looks like this:this:

void textprintf(BITMAP *bmp, const FONT void textprintf(BITMAP *bmp, const FONT *f, int x, y, color, const char *fmt, ...);*f, int x, y, color, const char *fmt, ...);