CSCI 240 Lecture Notes - Part 5 - Notes on Allegro C++ Graphics


Graphics functionality is not a part of the C++ language.  However, graphics functionality can be provided by writing a library of functions which access the computer's graphics hardware.  These libraries of functions can be provided by a compiler vendor such as Borland or Microsoft and included in a commercial product, or can be written by knowledgeable individuals and sold or provided free as software that can be added to your development system.  In this course, we will use a (free) software graphics package called Allegro.  It has been installed on the CSCI lab systems, and is provided as part of the 240 Course CD so you can install it on your personal computer.  Since the graphics functions in Allegro are not part of C++, programs written using it will not run on computers that do not have certain Allegro files installed.

Other graphics libraries will likely have similar functions, but their names and arguments will be different in some or most details.

GRAPHICS VS. TEXT

Text

Graphics

Graphics Mode Programs using Quincy

See the document entitled Creating a Graphics Program in Quincy for details on how to create a graphics mode program in Quincy.  The remainder of this document will cover concepts of graphics programming and a set of graphics functions you can use in your programs.  Note that one or two functions presented in the Creating a Graphics... document are used in the examples below.


SCREEN COORDINATE SYSTEM (standard VGA)

Upper left corner is (0, 0)
Upper right corner is (639, 0)
Lower left corner is (0, 479)
Lower right corner is (639, 479)

VGA can support 16, 256, or up to 16 million colors per pixel, depending on the hardware.

Other screen resolutions are possible (800 x 600, etc.)

In Allegro, you can set the screen resolution to one of several allowed values.  The grInit() function presented in the Creating a Graphics... document will set the screen to 640 x 480.  (See the set_gfx_mode() function call in grInit().)

After calling grInit(), you can find the current screen resolution (width and height are ints) by using the Allegro values SCREEN_W and SCREEN_H which act like symbolic constants in your program.

Even though you may know the screen resolution, it is good practice to use these constants in positioning graphics output whenever possible.  This way, if you change the program to use a different resolution, you can keep the relative position of various graphics elements (for example, we will use these to center certain graphics elements).

For example, suppose you want to position a dot in the middle of the screen, for any resolution.

The function to use is putpixel (screen, x, y, color);

where

So, after grInit() call

putpixel(screen, SCREEN_W/2, SCREEN_H/2, 50);

(You can use other numbers 0 .. 255 for the color.)


SKELETON GRAPHICS PROGRAM

#include "allegro.h"

int grInit(void);
void wait_for_keypress();

int main(void)
  {
  int rc;
  // initialize graphics mode - see Creating a Graphics... document 
  rc = grInit();
  // if grInit fails, it returns 1.  So we just quit the program.
  // no point in continuing.
  if (rc == 1)
    return 0;

  // Allegro draw-a-dot function
  putpixel(screen, SCREEN_W/2, SCREEN_H/2, 50); 
  // freeze display until user hits a key.  This also releases the 
  // graphics screen.  See Creating a Graphics... document.
  wait_for_keypress();

  return 0;
  }
END_OF_MAIN();   // <-- ABSOLUTELY REQUIRED EXACTLY HERE
// you must include the code for grInit() and wait_for_keypress() here.

GRAPHICS TEXT DISPLAY

There are facilities for text output in graphics mode. We will use one simple predefined font provided by Allegro.  Text can be output at any screen location.

textout(screen, font, msg, x, y, color);   //displays msg at x, y in color

where

For example:

textout(screen, font, "Hello", 10, 20, 50);

Will display the word "Hello" in light green at screen coordinates 10, 20.

To find the width of a string in pixels (not characters), use:

w = text_length(font, msg); 

Where

This function returns the width of msg in pixels

To find the height of a string in pixels, use:

h = text_height(font);

Where

This function returns the font height in pixels

So to display centered text:

textout(screen, 
        font, 
        msg, 
        SCREEN_W/2 - text_length(font, msg)/2, 
        100, 
        50); 

Where

But actually, Allegro provides a self-centering function:

void textout_centre(screen, font, msg, x, y, color);

Where x is the center of the string, so the center goes at x, y.  So you could just code:

textout_centre(screen, font, msg, SCREEN_W/2, 100, 50);

(Note the British spelling of centre.)
 

Allegro allows the creation and use of different fonts, but these topics will not be covered here.


GEOMETRIC OBJECTS

>>> Lines:

line(screen, x1, y1, x2, y2, color);

where

To do a big "X" on the screen:

line(screen, 0, 0,        SCREEN_W, SCREEN_H, 50);
line(screen, 0, SCREEN_H, SCREEN_W, 0,        50);
 

>>> Circles:

circle(screen, x, y, radius, color);

Where x and y are the coordinates of the center of the circle; the other arguments should be clear by now.

To center a circle on the screen:

circle(screen, SCREEN_W/2, SCREEN_H/2, SCREEN_H/2, 50);


>>> Rectangles:

rect(screen, x1, y1, x2, y2, color);

Where x1, y1 and x2, y2 are the coordinates of the upper left and lower right corners

To draw a series of nested rectangles:

   for (i = 10; i < SCREEN_H/2; i += 10)
    rect(screen, 
         SCREEN_W/2 - i, 
         SCREEN_H/2 - i, 
         SCREEN_W/2 + i, 
         SCREEN_H/2 + i, 
         100);
 

FILLING A REGION

The floodfill() function will fill a bounded region of the screen with a solid color.  To do the floodfill(), you need to supply the coordinates of any point inside the region and the color you want to use in the fill.  floodfill() will change all the background color pixels to the color you specify until it comes to pixels of a different color.  Note that if your region's boundary has even a tiny "hole" in it - where the hole is the background color - the flooding will spill out of the region and fill a large part - or all - of the screen.

floodfill(screen, x, y, color);

Where

Problem: to draw three rectangles of width = Rwd and height = Rht across the middle of the screen, equally spaced, margins = 1/2 of the spacing, and flood fill each of them.

 
w = SCREEN_W;                
h = SCREEN_H;
 
// y coord of rect tops and
// y coord of rect bottoms
top = h/2 - Rht/2;            
bot = h/2 + Rht/2;            
 
// size of space between rects
space = (w - 3*Rwd)/3;            
 
// draw the three rectangles in green
rect(screen, 
     space/2, 
     top, 
     space/2 + Rwd, 
     bot, 
     50); 
rect(screen, 
     1.5*space + Rwd, 
     top, 
     1.5*space + 2*Rwd, 
     bot, 
     50);
rect(screen, 
     2.5*space + 2*Rwd, 
     top, 
     2.5*space + 3*Rwd, 
     bot, 50);
 
 
// calc pt at 1,1 offset from top left of each rect; 
floodfill(screen, 
          space/2 + 1, 
          top + 1, 
          100);
floodfill(screen, 
          1.5*space + Rwd +1, 
          top + 1, 
          150);
floodfill(screen, 
          2.5*space + 2*Rwd + 1, 
          top + 1, 
          200);