#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 */
The linesmooth subroutine.
Pixel Coverage in GL3.2 Version 4 for AIX: Programming Concepts.