Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!linus!security!genrad!decvax!decwrl!flairvax!turtleva!ken From: ken@turtleva.UUCP (Ken Turkowski) Newsgroups: net.sources Subject: Graphics source in C: hsalgs/hiq_pxls.c Message-ID: <281@turtleva.UUCP> Date: Thu, 15-Dec-83 22:25:47 EST Article-I.D.: turtleva.281 Posted: Thu Dec 15 22:25:47 1983 Date-Received: Sun, 18-Dec-83 23:32:54 EST Lines: 235 echo x - hsalgs/hiq_pxls.c cat >hsalgs/hiq_pxls.c <<'!Funky!Stuff!' /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ hiq_pxls.c - writes pixels for front-to-back algorithms using coverage bits. Uses four corner points of pixel to properly average over texture and small highlights. Entries: - hiq_pxls(X_pos,coverage,tp_lft_pxl,bt_lft_pxl,tp_rgt_pxl,bt_rgt_pxl) NOTE! - must be loaded with ftb_pxls.c to pick up getseg and putseg ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ #define X 0 #define Y 1 #define Z 2 #define R 0 #define G 1 #define B 2 #define T 3 #define XN 4 #define YN 5 #define ZN 6 #define TX_X 7 #define TX_Y 8 #define NORMS 9 #define NORM_PARMS 6 #define LT_R 3 #define LT_G 4 #define LT_B 5 #define TX_RES 128 /* texture image resolution */ #define HRES 640 #define TRANS_MIN .02 /* minimum effective transmittance */ #define HILIT_MIN .02 /* minimum effective highlight factor */ #define MAXOBJ 2 #define TRUE 1 #define FALSE 0 #define sqr(x) ((x)*(x)) extern short cvr[HRES+2]; extern double red[HRES+2],grn[HRES+2],blu[HRES+2]; /* scanline buffer */ /* global variables for pixel output routine */ extern short num_lights,hilit_power,txtr,object; extern struct { short r,g,b,t,s; } texture[MAXOBJ][TX_RES][TX_RES]; /* +++++++++++++++++++++++++++ HIQ_PXLS +++++++++++++++++++++++++++++++++++ */ void hiq_pxls(X_pos,covrge,tp_lft_pxl,bt_lft_pxl,tp_rgt_pxl,bt_rgt_pxl) /* blend pixels using coverage bits */ short X_pos; double covrge,tp_lft_pxl[],bt_lft_pxl[], tp_rgt_pxl[],bt_rgt_pxl[]; { double oldcvr,newred,newgrn,newblu,px_trans; short i; struct { short r,g,b,t,s; } txtr_val; newred = tp_lft_pxl[R]; newgrn = tp_lft_pxl[G]; newblu = tp_lft_pxl[B]; if (txtr) /* color from texture */ { av_texture(&txtr_val,tp_lft_pxl,bt_lft_pxl,tp_rgt_pxl,bt_rgt_pxl); newred *= txtr_val.r / 255.; newgrn *= txtr_val.g / 255.; newblu *= txtr_val.b / 255.; } /* transmittance from texture */ px_trans = txtr? tp_lft_pxl[T] * txtr_val.t / 255. : tp_lft_pxl[T]; if (hilit_power > 0.) for (i=0; i HILIT_MIN * 2.) || x_cross || y_cross) { if (maj_xc < min_xc) if ((maj_yc < min_yc) || (maj_xc < min_yc)) /* major diag. */ hilit_value = av_hilit(k,bt_lft_pxl,tp_rgt_pxl); else /* minor diag. */ hilit_value = av_hilit(k,bt_rgt_pxl,tp_lft_pxl); else if ((min_yc < maj_yc) || (min_xc < maj_yc)) /* minor diag. */ hilit_value = av_hilit(k,bt_rgt_pxl,tp_lft_pxl); else /* major diag. */ hilit_value = av_hilit(k,bt_lft_pxl,tp_rgt_pxl); } if (txtr) hilit_value *= txtr_val.s / 255.; /* sum highlights */ newred = newred + (tp_lft_pxl[k+LT_R] - newred) * hilit_value; newgrn = newgrn + (tp_lft_pxl[k+LT_G] - newgrn) * hilit_value; newblu = newblu + (tp_lft_pxl[k+LT_B] - newblu) * hilit_value; if (px_trans > (1.0 - hilit_value)) px_trans = 1.0 - hilit_value; } if (px_trans > TRANS_MIN) covrge *= 1.0 - px_trans; /* transmittance */ oldcvr = cvr[X_pos]; /* get previous pixel coverage */ if (oldcvr == 0.) { cvr[X_pos] = covrge * 255. + .5; /* no previous coverage */ if (cvr[X_pos] > 0) { red[X_pos] = newred; grn[X_pos] = newgrn; blu[X_pos] = newblu; } } else if (oldcvr < 255.) /* partial previous coverage */ { oldcvr /= 255.; /* convert to 0. <= oldcvr <= 1. */ if ((oldcvr + covrge) >= 1.) /* pixel fully covered */ { covrge = 1. - oldcvr; cvr[X_pos] = 255; } else /* pixel partially covered */ { double adj; adj = oldcvr + covrge; cvr[X_pos] = adj * 255. + .5; oldcvr /= adj; covrge /= adj; } red[X_pos] = red[X_pos] * oldcvr + newred * covrge; grn[X_pos] = grn[X_pos] * oldcvr + newgrn * covrge; blu[X_pos] = blu[X_pos] * oldcvr + newblu * covrge; } } /* ++++++++++++++++++++++++++++ AV_HILIT ++++++++++++++++++++++++++++++ */ double av_hilit(k,pxl1,pxl2) /* subsample highlight between 2 pixel positions */ short k; double pxl1[],pxl2[]; { double tx,ty,tz,val1,val2,val3,val4,val5,mag_norm,pow(); mag_norm = sqr(pxl1[k+X]) + sqr(pxl1[k+Y]) + sqr(pxl1[k+Z]); val1 = pow(sqr(pxl1[k+Z])/mag_norm , (double)hilit_power); /*hilit at pxl1*/ tx = (pxl1[k+X] + pxl2[k+X])/2; ty = (pxl1[k+Y] + pxl2[k+Y])/2; tz = (pxl1[k+Z] + pxl2[k+Z])/2; mag_norm = sqr(tx) + sqr(ty) + sqr(tz); val3 = pow(sqr(tz)/mag_norm , (double)hilit_power); /*hilit midway between*/ mag_norm = sqr((pxl1[k+X] + tx)/2) + sqr((pxl1[k+Y] + ty)/2) + sqr((pxl1[k+Z] + tz)/2); val2 = pow(sqr((pxl1[k+Z] + tz)/2)/mag_norm,(double)hilit_power);/*1/4 pt.*/ mag_norm = sqr((pxl2[k+X] + tx)/2) + sqr((pxl2[k+Y] + ty)/2) + sqr((pxl2[k+Z] + tz)/2); val4 = pow(sqr((pxl2[k+Z] + tz)/2)/mag_norm,(double)hilit_power);/*3/4 pt.*/ mag_norm = sqr(pxl2[k+X]) + sqr(pxl2[k+Y]) + sqr(pxl2[k+Z]); val5 = pow(sqr(pxl2[k+Z])/mag_norm , (double)hilit_power); /*hilit at pxl2*/ return (val1 + val2 + val3 + val4 + val5) / 5.; } /* ++++++++++++++++++++++ AV_TEXTURE ++++++++++++++++++++++++++++++++ */ av_texture(txtr_val,tp_lft_pxl,bt_lft_pxl,tp_rgt_pxl,bt_rgt_pxl) /* average texture values for anti-aliasing */ double tp_lft_pxl[],bt_lft_pxl[],tp_rgt_pxl[],bt_rgt_pxl[]; struct { short r,g,b,t,s; } *txtr_val; { short tx_tl,tx_bl,tx_tr,tx_br,ty_tl,ty_bl,ty_tr,ty_br; struct { short r,g,b,t,s; } maj_avrge,min_avrge; /* texture coordinates at 4 corners */ tx_tl = (short)(TX_RES * tp_lft_pxl[TX_X]); ty_tl = (short)(TX_RES * tp_lft_pxl[TX_Y]); tx_bl = (short)(TX_RES * bt_lft_pxl[TX_X]); ty_bl = (short)(TX_RES * bt_lft_pxl[TX_Y]); tx_tr = (short)(TX_RES * tp_rgt_pxl[TX_X]); ty_tr = (short)(TX_RES * tp_rgt_pxl[TX_Y]); tx_br = (short)(TX_RES * bt_rgt_pxl[TX_X]); ty_br = (short)(TX_RES * bt_rgt_pxl[TX_Y]); crawl_to(&maj_avrge,tx_tl,ty_tl,tx_br,ty_br); crawl_to(&min_avrge,tx_bl,ty_bl,tx_tr,ty_tr); txtr_val->r = (maj_avrge.r + min_avrge.r) / 2; txtr_val->g = (maj_avrge.g + min_avrge.g) / 2; txtr_val->b = (maj_avrge.b + min_avrge.b) / 2; txtr_val->t = (maj_avrge.t + min_avrge.t) / 2; txtr_val->s = (maj_avrge.s + min_avrge.s) / 2; } /* +++++++++++++++++++++++++++ CRAWL_TO ++++++++++++++++++++++++++++++++ */ crawl_to(value,x1,y1,x2,y2) /* iterate from p1 to p2 averaging en route */ struct {short r,g,b,t,s; } *value; short x1,y1,x2,y2; { short i,sign,temp; struct {short r,g,b,t,s; } *txtr_ptr; if (y2 < y1) /* ensure y goes positively */ { temp = y2; y2 = y1; y1 = temp; temp = x2; x2 = x1; x1 = temp; } if (x2 < x1) sign = -1; else sign = 1; txtr_ptr = &texture[object][x1%TX_RES][y1%TX_RES]; /* store initial pt. */ value->r = txtr_ptr->r; value->g = txtr_ptr->g; value->b = txtr_ptr->b; value->t = txtr_ptr->t; value->s = txtr_ptr->s; i = 1; while ((x1 != x2) && (y1 != y2)) { if ((y2 - y1)/2 >= abs(x2 - x1)) y1++; else if (abs((x2 - x1)/2) >= (y2 - y1)) x1 += sign; else { x1 += sign; y1++; } txtr_ptr = &texture[object][x1%TX_RES][y1%TX_RES]; /* add new values */ value->r += txtr_ptr->r; value->g += txtr_ptr->g; value->b += txtr_ptr->b; value->t += txtr_ptr->t; value->s += txtr_ptr->s; i++; } value->r /= i; value->g /= i; value->b /= i; value->t /= i; value->s /= i; } !Funky!Stuff!