[ Previous | Next | Contents | Glossary | Home | Search ]
GL3.2 for AIX: Graphics Library (GL) Technical Reference

alias.c Example C Language Program

#include <gl/gl.h>
#include <gl/device.h>
#include <stdlib.h>
#include <math.h>
/* 
* This program illustrates the drawing of antialiased lines, of
* multiple foreground colors, on an arbitrary multi-colored
* background.
*
* Note that this style of drawing is limited as to the number
* of foreground and background colors. The total number of
* colors is one-sixteenth of the total number of color map
* entries.
* 
* The basic idea behind the algorithm is to divide the
* available bitplanes into three groups: those containing
* the background image, those containing the foreground line
* colors and those containing the antialiasing coverage
* information. Color ramps are loaded in the color map ranges
* corresponding to the coverage information. The color ramps
* must blend between all possible foreground and all possible
* background colors.
*
* Note that proper gamma correction is absolutely vital to 
* getting antialiased lines that look truly smooth to the user.
* The gamma exponent depends on the monitor (specifically, on
* the type of phosphors) and therefore needs to be tuned to the
* model of the monitor.
* 
* Antialiased lines are supported on the 8 and 24 bit 3D adapters.
* Colormode antialiased lines is not supported on the
* High Speed Graphics Adapter.
*/ 
draw_fan()
{
  /* draw fan */
  
  int i;
  for (i=0; i<= 90; i+=10) {
    pushmatrix();
    rot (-(float) i, 'z');
    move (0.0, 0.0, 0.0);
    draw (0.0, 300.0, 0.0);
    popmatrix();
  }
}
/* experimentally determined gamma factor */
double gammy = 2.4;
/* color map data area */
short rramp[256], gramp[256], bramp[256];
/* a utility macro used to build the color ramp */
#define ADD_TO_RAMP(COL,back_r,back_g,back_b)             \ 
{                                                         \ 
  for (j=0; j<16; j++){                                   \ 
     col_idx = COL + j;                                   \ 
     rramp[col_idx] = (j*fore_r + (16-j)*back_r) / 16;    \ 
     gramp[col_idx] = (j*fore_g + (16-j)*back_g) / 16;    \ 
     bramp[col_idx] = (j*fore_b + (16-j)*back_b) / 16;    \ 
     corr = 255.0 * pow (((double) rramp[col_idx])/255.0, \ 
       1.0/gammy);                                        \ 
     rramp[col_idx] = (int) corr;                         \ 
     corr = 255.0 * pow (((double) gramp[col_idx])/255.0, \ 
       1.0/gammy);                                        \ 
     gramp[col_idx] = (int) corr;                         \ 
     corr = 255.0 * pow (((double) bramp[col_idx])/255.0, \ 
       1.0/gammy);                                        \ 
     bramp[col_idx] = (int) corr;                         \ 
  }                                                       \ 
}
/* a utility that blends the supplied foreground color
 * to several backgrounds */
void blend_background_cmap (int offset, short fore_r, short
                            fore_g, short fore_b)
{
  int j, col_idx;
  double corr;
    /* blend to background of green */
  ADD_TO_RAMP (offset, 0, 255, 0);
    /* blend to background of purple */
  ADD_TO_RAMP (offset+16, 155, 0, 255);
    /* blend to background of black */
  ADD_TO_RAMP (offset+32, 0, 0, 0);
    /* blend to background of cyan */
  ADD_TO_RAMP (offset+48, 20, 150, 150);
}
/* the main color map routine, builds cross-ramps between various 
 * front and back colors */
void load_cross_ramp ()
{
    /* blend to foreground of white */
  blend_background_cmap (0, 255, 255, 255);
    /* blend to foreground of yellow */
  blend_background_cmap (64, 255, 255, 0);
    /* blend to foreground of red */
  blend_background_cmap (128, 255, 0, 0);
    /* blend to foreground of blue */
  blend_background_cmap (192, 0, 0, 255);
  mapcolors (0, 255, rramp, gramp, bramp);
}
#define RRRANDO ( (float) (400*rand()/32767));
/* This routine draws a background of random polygons.
 * One of four colors are selected randomly.  */
void draw_background()
{
  float vv[2];
  int i, j;
  srand (24515);
  color (0);
  clear();
    /* the writemask guarantees that drawing is occurring only
     * into the "background" bitplanes */
  writemask (0x30);
  for (j=0; j<12; j++) {
    color (16*((4*rand())/32767));
    bgnpolygon();
    for (i=0; i<6; i++) {
      vv[0] = RRRANDO;
      vv[1] = RRRANDO;
      v2f (vv);
    }
    endpolygon();
  }
}
main (argc, argv )
int argc;
char **argv;
{
  long l_lop;
  prefsize (400.0, 400.0);
  winopen ("antialiased lines");
  cmode();
  doublebuffer();
  gconfig();
#if 0
    /* zsource (ZSRC_COLOR) only High Performance 3-D adapter */
    /* enable update comparison to improve line intersections */
  zbuffer (TRUE);
  zclear();
    /* use color, not depth values, to determine if pixel is 
     * written */
  zsource (ZSRC_COLOR);
    /* foreground colors always have greater values than 
     * background */
  zfunction (ZF_GEQUAL);
    /* create the color ramp */
#endif
  save_cmap();
  load_cross_ramp();
    /* draw the random background */
  draw_background();
  swapbuffers ();
  draw_background();
    /* the writemask write-protects the background while lines
     * are being drawn */
  writemask (0xcf);
  if (argc==2) {
      l_lop=atol(argv[1]);
      logicop (l_lop);
      printf ("The logic op is: %ld\n",l_lop);
   }
    /* loop until the right mouse button is depressed */
  while (!getbutton(RIGHTMOUSE) && !getbutton(ESCKEY)) {
    color (0);
    clear ();
    pushmatrix();        /* draw normal, jaggy lines */
    linesmooth(FALSE);
    color (15); /* maximum shade of white */
    pushmatrix();
    translate (10.0, 10.0, 0.0);
    rotate( 500-getvaluator (MOUSEY), 'z');
    draw_fan();
    popmatrix();         /* draw smooth, antialiased lines -- lower right*/
    linesmooth(TRUE);
    color (64);  /* yellow */
    pushmatrix();
    translate (390.0, 30.0, 0.0);
    rotate( getvaluator (MOUSEY) + 400, 'z');
    draw_fan();
    popmatrix();            /* draw smooth, antialiased lines -- upper right */
    color (128);   /* red */
    pushmatrix();
    translate (390.0, 390.0, 0.0);
    rotate( getvaluator (MOUSEX) -2300, 'z');
    draw_fan();
    popmatrix();         /* draw smooth, antialiased lines -- upper left */
    color (192);   /* blue */
    pushmatrix();
    translate (30.0, 360.0, 0.0);
    rotate( -400 - getvaluator (MOUSEX), 'z');
    draw_fan();
    popmatrix();
    popmatrix();
    swapbuffers();
  }
  restore_cmap();
}
/*This saves the colormap*/
#define lo_end 0
#define hi_end 255
short *CarrayR, *CarrayG, *CarrayB;
save_cmap()
{
  CarrayR = calloc (lo_end+hi_end,sizeof(short));
  CarrayG = calloc (lo_end+hi_end,sizeof(short));
  CarrayB = calloc (lo_end+hi_end,sizeof(short));
  getmcolors ((Int16 const)lo_end,(Int16 const)hi_end,
     CarrayR, CarrayG, CarrayB);
}
/*This restores the colormap*/
restore_cmap()
{
  mapcolors ((Int16 const)lo_end,(Int16 const)hi_end,
     CarrayR, CarrayG, CarrayB);
}
/*
  Changes:
    -  Added the restoring of the colormap
      -  The program now reads the first parameter passed to it for the value
       to serve as the current logic operation
    -  The function calls that set up the z buffer for the z source color
       have been removed. (#if 0 / #endif)
    -  Added escape key and right mouse for clean exit
*/

Related Information

The linesmooth subroutine.

Pixel Coverage in GL3.2 Version 4 for AIX: Programming Concepts.


[ Previous | Next | Contents | Glossary | Home | Search ]