#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.