| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502 |
- /*
- * We draw a triangle with various interpolations
- */
- {
- ZBufferPoint *t,*pr1,*pr2,*l1,*l2;
- float fdx1, fdx2, fdy1, fdy2, fz, d1, d2;
- ZPOINT *pz1;
- PIXEL *pp1;
- int part, update_left, update_right;
- int nb_lines, dx1, dy1, tmp, dx2, dy2;
- int error, derror;
- int x1, dxdy_min, dxdy_max;
- /* warning: x2 is multiplied by 2^16 */
- int x2, dx2dy2;
- #ifdef INTERP_Z
- int z1 = 0, dzdx = 0, dzdy = 0, dzdl_min = 0, dzdl_max = 0;
- #endif
- #ifdef INTERP_RGB
- int r1 = 0, drdx = 0, drdy = 0, drdl_min = 0, drdl_max = 0;
- int g1 = 0, dgdx = 0, dgdy = 0, dgdl_min = 0, dgdl_max = 0;
- int b1 = 0, dbdx = 0, dbdy = 0, dbdl_min = 0, dbdl_max = 0;
- int a1 = 0, dadx = 0, dady = 0, dadl_min = 0, dadl_max = 0;
- #endif
- #ifdef INTERP_ST
- int s1 = 0, dsdx = 0, dsdy = 0, dsdl_min = 0, dsdl_max = 0;
- int t1 = 0, dtdx = 0, dtdy = 0, dtdl_min = 0, dtdl_max = 0;
- #endif
- #ifdef INTERP_STZ
- float sz1 = 0, dszdx = 0, dszdy = 0, dszdl_min = 0, dszdl_max = 0;
- float tz1 = 0, dtzdx = 0, dtzdy = 0, dtzdl_min = 0, dtzdl_max = 0;
- #endif
- #ifdef INTERP_STZA
- float sza1 = 0, dszadx = 0, dszady = 0, dszadl_min = 0, dszadl_max = 0;
- float tza1 = 0, dtzadx = 0, dtzady = 0, dtzadl_min = 0, dtzadl_max = 0;
- #endif
- #ifdef INTERP_STZB
- float szb1 = 0, dszbdx = 0, dszbdy = 0, dszbdl_min = 0, dszbdl_max = 0;
- float tzb1 = 0, dtzbdx = 0, dtzbdy = 0, dtzbdl_min = 0, dtzbdl_max = 0;
- #endif
- #if defined(INTERP_MIPMAP) && (defined(INTERP_ST) || defined(INTERP_STZ))
- unsigned int mipmap_dx = 0, mipmap_level = 0;
- #endif
- #if defined(INTERP_MIPMAP) && defined(INTERP_STZA)
- unsigned int mipmap_dxa = 0, mipmap_levela = 0;
- #endif
- #if defined(INTERP_MIPMAP) && defined(INTERP_STZB)
- unsigned int mipmap_dxb = 0, mipmap_levelb = 0;
- #endif
- EARLY_OUT();
- COUNT_PIXELS(PIXEL_COUNT, p0, p1, p2);
- /* we sort the vertex with increasing y */
- if (p1->y < p0->y) {
- t = p0;
- p0 = p1;
- p1 = t;
- }
- if (p2->y < p0->y) {
- t = p2;
- p2 = p1;
- p1 = p0;
- p0 = t;
- } else if (p2->y < p1->y) {
- t = p1;
- p1 = p2;
- p2 = t;
- }
- /* we compute dXdx and dXdy for all interpolated values */
-
- fdx1 = (float) (p1->x - p0->x);
- fdy1 = (float) (p1->y - p0->y);
- fdx2 = (float) (p2->x - p0->x);
- fdy2 = (float) (p2->y - p0->y);
- fz = fdx1 * fdy2 - fdx2 * fdy1;
- if (fz == 0)
- return;
- fz = 1.0f / fz;
- fdx1 *= fz;
- fdy1 *= fz;
- fdx2 *= fz;
- fdy2 *= fz;
- #ifdef INTERP_Z
- d1 = (float) (p1->z - p0->z);
- d2 = (float) (p2->z - p0->z);
- dzdx = (int) (fdy2 * d1 - fdy1 * d2);
- dzdy = (int) (fdx1 * d2 - fdx2 * d1);
- #endif
- #ifdef INTERP_RGB
- d1 = (float) (p1->r - p0->r);
- d2 = (float) (p2->r - p0->r);
- drdx = (int) (fdy2 * d1 - fdy1 * d2);
- drdy = (int) (fdx1 * d2 - fdx2 * d1);
- d1 = (float) (p1->g - p0->g);
- d2 = (float) (p2->g - p0->g);
- dgdx = (int) (fdy2 * d1 - fdy1 * d2);
- dgdy = (int) (fdx1 * d2 - fdx2 * d1);
- d1 = (float) (p1->b - p0->b);
- d2 = (float) (p2->b - p0->b);
- dbdx = (int) (fdy2 * d1 - fdy1 * d2);
- dbdy = (int) (fdx1 * d2 - fdx2 * d1);
- d1 = (float) (p1->a - p0->a);
- d2 = (float) (p2->a - p0->a);
- dadx = (int) (fdy2 * d1 - fdy1 * d2);
- dady = (int) (fdx1 * d2 - fdx2 * d1);
- #endif
-
- #ifdef INTERP_ST
- d1 = (float) (p1->s - p0->s);
- d2 = (float) (p2->s - p0->s);
- dsdx = (int) (fdy2 * d1 - fdy1 * d2);
- dsdy = (int) (fdx1 * d2 - fdx2 * d1);
-
- d1 = (float) (p1->t - p0->t);
- d2 = (float) (p2->t - p0->t);
- dtdx = (int) (fdy2 * d1 - fdy1 * d2);
- dtdy = (int) (fdx1 * d2 - fdx2 * d1);
- CALC_MIPMAP_LEVEL(mipmap_level, mipmap_dx, dsdx, dtdx);
- #endif
- #ifdef INTERP_STZ
- {
- float zz;
- zz=(float) p0->z;
- p0->sz= (float) p0->s * zz;
- p0->tz= (float) p0->t * zz;
- zz=(float) p1->z;
- p1->sz= (float) p1->s * zz;
- p1->tz= (float) p1->t * zz;
- zz=(float) p2->z;
- p2->sz= (float) p2->s * zz;
- p2->tz= (float) p2->t * zz;
- d1 = p1->sz - p0->sz;
- d2 = p2->sz - p0->sz;
- dszdx = (fdy2 * d1 - fdy1 * d2);
- dszdy = (fdx1 * d2 - fdx2 * d1);
-
- d1 = p1->tz - p0->tz;
- d2 = p2->tz - p0->tz;
- dtzdx = (fdy2 * d1 - fdy1 * d2);
- dtzdy = (fdx1 * d2 - fdx2 * d1);
- }
- #endif
- #ifdef INTERP_STZA
- {
- float zz;
- zz=(float) p0->z;
- p0->sza= (float) p0->sa * zz;
- p0->tza= (float) p0->ta * zz;
- zz=(float) p1->z;
- p1->sza= (float) p1->sa * zz;
- p1->tza= (float) p1->ta * zz;
- zz=(float) p2->z;
- p2->sza= (float) p2->sa * zz;
- p2->tza= (float) p2->ta * zz;
- d1 = p1->sza - p0->sza;
- d2 = p2->sza - p0->sza;
- dszadx = (fdy2 * d1 - fdy1 * d2);
- dszady = (fdx1 * d2 - fdx2 * d1);
-
- d1 = p1->tza - p0->tza;
- d2 = p2->tza - p0->tza;
- dtzadx = (fdy2 * d1 - fdy1 * d2);
- dtzady = (fdx1 * d2 - fdx2 * d1);
- }
- #endif
- #ifdef INTERP_STZB
- {
- float zz;
- zz=(float) p0->z;
- p0->szb= (float) p0->sb * zz;
- p0->tzb= (float) p0->tb * zz;
- zz=(float) p1->z;
- p1->szb= (float) p1->sb * zz;
- p1->tzb= (float) p1->tb * zz;
- zz=(float) p2->z;
- p2->szb= (float) p2->sb * zz;
- p2->tzb= (float) p2->tb * zz;
- d1 = p1->szb - p0->szb;
- d2 = p2->szb - p0->szb;
- dszbdx = (fdy2 * d1 - fdy1 * d2);
- dszbdy = (fdx1 * d2 - fdx2 * d1);
-
- d1 = p1->tzb - p0->tzb;
- d2 = p2->tzb - p0->tzb;
- dtzbdx = (fdy2 * d1 - fdy1 * d2);
- dtzbdy = (fdx1 * d2 - fdx2 * d1);
- }
- #endif
- /* screen coordinates */
- pp1 = (PIXEL *) ((char *) zb->pbuf + zb->linesize * p0->y);
- pz1 = zb->zbuf + p0->y * zb->xsize;
- DRAW_INIT();
- for(part=0;part<2;part++) {
- if (part == 0) {
- if (fz > 0) {
- update_left=1;
- update_right=1;
- l1=p0;
- l2=p2;
- pr1=p0;
- pr2=p1;
- } else {
- update_left=1;
- update_right=1;
- l1=p0;
- l2=p1;
- pr1=p0;
- pr2=p2;
- }
- nb_lines = p1->y - p0->y;
- } else {
- /* second part */
- if (fz > 0) {
- update_left=0;
- update_right=1;
- pr1=p1;
- pr2=p2;
- } else {
- update_left=1;
- update_right=0;
- l1=p1;
- l2=p2;
- }
- nb_lines = p2->y - p1->y + 1;
- }
- /* compute the values for the left edge */
- if (update_left) {
- dy1 = l2->y - l1->y;
- dx1 = l2->x - l1->x;
- if (dy1 > 0)
- tmp = (dx1 << 16) / dy1;
- else
- tmp = 0;
- x1 = l1->x;
- error = 0;
- derror = tmp & 0x0000ffff;
- dxdy_min = tmp >> 16;
- dxdy_max = dxdy_min + 1;
-
- #ifdef INTERP_Z
- z1=l1->z;
- dzdl_min=(dzdy + dzdx * dxdy_min);
- dzdl_max=dzdl_min + dzdx;
- #endif
- #ifdef INTERP_RGB
- r1=l1->r;
- drdl_min=(drdy + drdx * dxdy_min);
- drdl_max=drdl_min + drdx;
-
- g1=l1->g;
- dgdl_min=(dgdy + dgdx * dxdy_min);
- dgdl_max=dgdl_min + dgdx;
-
- b1=l1->b;
- dbdl_min=(dbdy + dbdx * dxdy_min);
- dbdl_max=dbdl_min + dbdx;
-
- a1=l1->a;
- dadl_min=(dady + dadx * dxdy_min);
- dadl_max=dadl_min + dadx;
- #endif
- #ifdef INTERP_ST
- s1=l1->s;
- dsdl_min=(dsdy + dsdx * dxdy_min);
- dsdl_max=dsdl_min + dsdx;
-
- t1=l1->t;
- dtdl_min=(dtdy + dtdx * dxdy_min);
- dtdl_max=dtdl_min + dtdx;
- #endif
- #ifdef INTERP_STZ
- sz1=l1->sz;
- dszdl_min=(dszdy + dszdx * dxdy_min);
- dszdl_max=dszdl_min + dszdx;
-
- tz1=l1->tz;
- dtzdl_min=(dtzdy + dtzdx * dxdy_min);
- dtzdl_max=dtzdl_min + dtzdx;
- #endif
- #ifdef INTERP_STZA
- sza1=l1->sza;
- dszadl_min=(dszady + dszadx * dxdy_min);
- dszadl_max=dszadl_min + dszadx;
-
- tza1=l1->tza;
- dtzadl_min=(dtzady + dtzadx * dxdy_min);
- dtzadl_max=dtzadl_min + dtzadx;
- #endif
- #ifdef INTERP_STZB
- szb1=l1->szb;
- dszbdl_min=(dszbdy + dszbdx * dxdy_min);
- dszbdl_max=dszbdl_min + dszbdx;
-
- tzb1=l1->tzb;
- dtzbdl_min=(dtzbdy + dtzbdx * dxdy_min);
- dtzbdl_max=dtzbdl_min + dtzbdx;
- #endif
- }
- /* compute values for the right edge */
- if (update_right) {
- dx2 = (pr2->x - pr1->x);
- dy2 = (pr2->y - pr1->y);
- if (dy2>0)
- dx2dy2 = ( dx2 << 16) / dy2;
- else
- dx2dy2 = 0;
- x2 = pr1->x << 16;
- }
- /* we draw all the scan line of the part */
- while (nb_lines>0) {
- nb_lines--;
- #ifndef DRAW_LINE
- /* generic draw line */
- {
- register PIXEL *pp;
- register int n;
- #ifdef INTERP_Z
- register ZPOINT *pz;
- register unsigned int z,zz;
- #endif
- #ifdef INTERP_RGB
- register unsigned int or1,og1,ob1,oa1;
- #endif
- #ifdef INTERP_ST
- register unsigned int s,t;
- #endif
- #ifdef INTERP_STZ
- float sz,tz;
- #endif
- #ifdef INTERP_STZA
- float sza,tza;
- #endif
- #ifdef INTERP_STZB
- float szb,tzb;
- #endif
- n=(x2 >> 16) - x1;
- pp=(PIXEL *)((char *)pp1 + x1 * PSZB);
- #ifdef INTERP_Z
- pz=pz1+x1;
- z=z1;
- #endif
- #ifdef INTERP_RGB
- or1 = r1;
- og1 = g1;
- ob1 = b1;
- oa1 = a1;
- #endif
- #ifdef INTERP_ST
- s=s1;
- t=t1;
- #endif
- #ifdef INTERP_STZ
- sz=sz1;
- tz=tz1;
- #endif
- #ifdef INTERP_STZA
- sza=sza1;
- tza=tza1;
- #endif
- #ifdef INTERP_STZB
- szb=szb1;
- tzb=tzb1;
- #endif
- while (n>=3) {
- PUT_PIXEL(0);
- PUT_PIXEL(1);
- PUT_PIXEL(2);
- PUT_PIXEL(3);
- #ifdef INTERP_Z
- pz+=4;
- #endif
- pp=(PIXEL *)((char *)pp + 4 * PSZB);
- n-=4;
- }
- while (n>=0) {
- PUT_PIXEL(0);
- #ifdef INTERP_Z
- pz+=1;
- #endif
- pp=(PIXEL *)((char *)pp + PSZB);
- n-=1;
- }
- }
- #else
- DRAW_LINE();
- #endif
-
- /* left edge */
- error+=derror;
- if (error > 0) {
- error-=0x10000;
- x1+=dxdy_max;
- #ifdef INTERP_Z
- z1+=dzdl_max;
- #endif
- #ifdef INTERP_RGB
- r1+=drdl_max;
- g1+=dgdl_max;
- b1+=dbdl_max;
- a1+=dadl_max;
- #endif
- #ifdef INTERP_ST
- s1+=dsdl_max;
- t1+=dtdl_max;
- #endif
- #ifdef INTERP_STZ
- sz1+=dszdl_max;
- tz1+=dtzdl_max;
- #endif
- #ifdef INTERP_STZA
- sza1+=dszadl_max;
- tza1+=dtzadl_max;
- #endif
- #ifdef INTERP_STZB
- szb1+=dszbdl_max;
- tzb1+=dtzbdl_max;
- #endif
- } else {
- x1+=dxdy_min;
- #ifdef INTERP_Z
- z1+=dzdl_min;
- #endif
- #ifdef INTERP_RGB
- r1+=drdl_min;
- g1+=dgdl_min;
- b1+=dbdl_min;
- a1+=dadl_min;
- #endif
- #ifdef INTERP_ST
- s1+=dsdl_min;
- t1+=dtdl_min;
- #endif
- #ifdef INTERP_STZ
- sz1+=dszdl_min;
- tz1+=dtzdl_min;
- #endif
- #ifdef INTERP_STZA
- sza1+=dszadl_min;
- tza1+=dtzadl_min;
- #endif
- #ifdef INTERP_STZB
- szb1+=dszbdl_min;
- tzb1+=dtzbdl_min;
- #endif
- }
-
- /* right edge */
- x2+=dx2dy2;
- /* screen coordinates */
- pp1=(PIXEL *)((char *)pp1 + zb->linesize);
- pz1+=zb->xsize;
- }
- }
- }
- #undef INTERP_Z
- #undef INTERP_RGB
- #undef INTERP_ST
- #undef INTERP_STZ
- #undef INTERP_STZA
- #undef INTERP_STZB
- #undef EARLY_OUT
- #undef EARLY_OUT_FZ
- #undef DRAW_INIT
- #undef DRAW_LINE
- #undef PUT_PIXEL
- #undef PIXEL_COUNT
|