ken@turtleva.UUCP (Ken Turkowski) (12/16/83)
echo x - hsalgs/ftb_pxls.c cat >hsalgs/ftb_pxls.c <<'!Funky!Stuff!' /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ftb_pxls.c - writes pixels for front-to-back algorithms using coverage bits Entries: - ftb_pxls(X_pos,pixel,coverage) - getseg(Y_pos,xleft,xrght) - putseg(Y_pos,xleft,xrght) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ #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 MAXOBJ 2 #define sqr(x) ((x)*(x)) short cvr[HRES+2]; 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]; /* ++++++++++++++++++++++++ GETSEG +++++++++++++++++++++++++++++++++++++++ */ getseg(Y_pos,xleft,xrght) /* read and unpack section of scanline */ short Y_pos,xleft,xrght; { short i; unsigned long line[642]; /* for (i=xleft; i<=xrght; i++) line[i] = 0; */ bbread(xleft,Y_pos,&line[xleft],xrght-xleft+1); for (i=xleft; i<=xrght; i++) { cvr[i] = line[i] >> 24; red[i] = (line[i] >> 16) & 255; grn[i] = (line[i] >> 8) & 255; blu[i] = line[i] & 255; } } /* ++++++++++++++++++++++++ PUTSEG ++++++++++++++++++++++++++++++++++++++++ */ putseg(Y_pos,xleft,xrght) /* pack up and write a section of scanline */ short Y_pos,xleft,xrght; { short i; unsigned long line[642]; for (i=xleft; i<=xrght; i++) { line[i] = ( cvr[i] << 24) | ((short)red[i] << 16) | ((short)grn[i] << 8) | (short)blu[i]; } bbwrite(xleft,Y_pos,&line[xleft],xrght-xleft+1); /* printf(" scanline %d written, %d - %d\n",Y_pos,xleft,xrght); */ } /* +++++++++++++++++++++++++++ FTB_PXLS +++++++++++++++++++++++++++++++++++ */ void ftb_pxls(X_pos,pixel,covrge) /* blend pixels using coverage bits */ short X_pos; double pixel[],covrge; { double oldcvr,mag_norm,hilit_value,newred,newgrn,newblu,px_trans,pow(); short i,tx,ty; struct { short r,g,b,t,s; } *txtr_ptr; if (txtr) { double pix_tx_x,pix_tx_y; pix_tx_x = pixel[TX_X]; pix_tx_y = pixel[TX_Y]; while (pix_tx_x < 0.) pix_tx_y += 1.; while (pix_tx_y < 0.) pix_tx_y += 1.; tx = (short)(TX_RES * pix_tx_x) % TX_RES; /* txtr coords */ ty = (short)(TX_RES * pix_tx_y) % TX_RES; txtr_ptr = &texture[object][tx][ty]; if (object > 0) object = object + 1 -1; } newred = pixel[R]; newgrn = pixel[G]; newblu = pixel[B]; if (txtr) /* color from texture */ { newred *= txtr_ptr->r / 255.; newgrn *= txtr_ptr->g / 255.; newblu *= txtr_ptr->b / 255.; } /* transmittance from texture */ px_trans = txtr? pixel[T] * txtr_ptr->t / 255. : pixel[T]; if (hilit_power > 0.) for (i=0; i<num_lights; i++) /* hilight */ { short k; k = NORMS + i*NORM_PARMS; /* offset for highlight normals */ mag_norm = sqr(pixel[k+X]) + sqr(pixel[k+Y]) + sqr(pixel[k+Z]); hilit_value = pow(sqr(pixel[k+Z]) / mag_norm , (double)hilit_power); if (txtr) hilit_value *= txtr_ptr->s / 255.; newred = newred + (pixel[k+LT_R] - newred) * hilit_value; newgrn = newgrn + (pixel[k+LT_G] - newgrn) * hilit_value; newblu = newblu + (pixel[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; } } !Funky!Stuff!