Graphics source in C: hsalgs/ftb_pxls.c
Ken Turkowski
ken at turtleva.UUCP
Fri Dec 16 12:55:31 AEST 1983
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!
More information about the Comp.sources.unix
mailing list