Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * We draw a triangle with various interpolations
  3.  */
  4.  
  5. {
  6.   ZBufferPoint *t,*pr1,*pr2,*l1,*l2;
  7.   float fdx1, fdx2, fdy1, fdy2, fz, d1, d2;
  8.   unsigned short *pz1;
  9.   PIXEL *pp1;
  10.   int part,update_left,update_right;
  11.  
  12.   int nb_lines,dx1,dy1,tmp,dx2,dy2;
  13.  
  14.   int error,derror;
  15.   int x1,dxdy_min,dxdy_max;
  16. /* warning: x2 is multiplied by 2^16 */
  17.   int x2,dx2dy2;  
  18.  
  19. #ifdef INTERP_Z
  20.   int z1,dzdx,dzdy,dzdl_min,dzdl_max;
  21. #endif
  22. #ifdef INTERP_RGB
  23.   int r1,drdx,drdy,drdl_min,drdl_max;
  24.   int g1,dgdx,dgdy,dgdl_min,dgdl_max;
  25.   int b1,dbdx,dbdy,dbdl_min,dbdl_max;
  26. #endif
  27. #ifdef INTERP_ST
  28.   int s1,dsdx,dsdy,dsdl_min,dsdl_max;
  29.   int t1,dtdx,dtdy,dtdl_min,dtdl_max;
  30. #endif
  31. #ifdef INTERP_STZ
  32.   float sz1,dszdx,dszdy,dszdl_min,dszdl_max;
  33.   float tz1,dtzdx,dtzdy,dtzdl_min,dtzdl_max;
  34. #endif
  35.  
  36.   /* we sort the vertex with increasing y */
  37.   if (p1->y < p0->y) {
  38.     t = p0;
  39.     p0 = p1;
  40.     p1 = t;
  41.   }
  42.   if (p2->y < p0->y) {
  43.     t = p2;
  44.     p2 = p1;
  45.     p1 = p0;
  46.     p0 = t;
  47.   } else if (p2->y < p1->y) {
  48.     t = p1;
  49.     p1 = p2;
  50.     p2 = t;
  51.   }
  52.  
  53.   /* we compute dXdx and dXdy for all interpolated values */
  54.  
  55.   fdx1 = p1->x - p0->x;
  56.   fdy1 = p1->y - p0->y;
  57.  
  58.   fdx2 = p2->x - p0->x;
  59.   fdy2 = p2->y - p0->y;
  60.  
  61.   fz = fdx1 * fdy2 - fdx2 * fdy1;
  62.   if (fz == 0)
  63.     return;
  64.   fz = 1.0 / fz;
  65.  
  66.   fdx1 *= fz;
  67.   fdy1 *= fz;
  68.   fdx2 *= fz;
  69.   fdy2 *= fz;
  70.  
  71. #ifdef INTERP_Z
  72.   d1 = p1->z - p0->z;
  73.   d2 = p2->z - p0->z;
  74.   dzdx = (int) (fdy2 * d1 - fdy1 * d2);
  75.   dzdy = (int) (fdx1 * d2 - fdx2 * d1);
  76. #endif
  77.  
  78. #ifdef INTERP_RGB
  79.   d1 = p1->r - p0->r;
  80.   d2 = p2->r - p0->r;
  81.   drdx = (int) (fdy2 * d1 - fdy1 * d2);
  82.   drdy = (int) (fdx1 * d2 - fdx2 * d1);
  83.  
  84.   d1 = p1->g - p0->g;
  85.   d2 = p2->g - p0->g;
  86.   dgdx = (int) (fdy2 * d1 - fdy1 * d2);
  87.   dgdy = (int) (fdx1 * d2 - fdx2 * d1);
  88.  
  89.   d1 = p1->b - p0->b;
  90.   d2 = p2->b - p0->b;
  91.   dbdx = (int) (fdy2 * d1 - fdy1 * d2);
  92.   dbdy = (int) (fdx1 * d2 - fdx2 * d1);
  93.  
  94. #endif
  95.  
  96. #ifdef INTERP_ST
  97.   d1 = p1->s - p0->s;
  98.   d2 = p2->s - p0->s;
  99.   dsdx = (int) (fdy2 * d1 - fdy1 * d2);
  100.   dsdy = (int) (fdx1 * d2 - fdx2 * d1);
  101.  
  102.   d1 = p1->t - p0->t;
  103.   d2 = p2->t - p0->t;
  104.   dtdx = (int) (fdy2 * d1 - fdy1 * d2);
  105.   dtdy = (int) (fdx1 * d2 - fdx2 * d1);
  106. #endif
  107.  
  108. #ifdef INTERP_STZ
  109.   {
  110.     float zz;
  111.     zz=(float) p0->z;
  112.     p0->sz= (float) p0->s * zz;
  113.     p0->tz= (float) p0->t * zz;
  114.     zz=(float) p1->z;
  115.     p1->sz= (float) p1->s * zz;
  116.     p1->tz= (float) p1->t * zz;
  117.     zz=(float) p2->z;
  118.     p2->sz= (float) p2->s * zz;
  119.     p2->tz= (float) p2->t * zz;
  120.  
  121.     d1 = p1->sz - p0->sz;
  122.     d2 = p2->sz - p0->sz;
  123.     dszdx = (fdy2 * d1 - fdy1 * d2);
  124.     dszdy = (fdx1 * d2 - fdx2 * d1);
  125.    
  126.     d1 = p1->tz - p0->tz;
  127.     d2 = p2->tz - p0->tz;
  128.     dtzdx = (fdy2 * d1 - fdy1 * d2);
  129.     dtzdy = (fdx1 * d2 - fdx2 * d1);
  130.   }
  131. #endif
  132.  
  133.   /* screen coordinates */
  134.  
  135.   pp1 = (PIXEL *) ((char *) zb->pbuf + zb->linesize * p0->y);
  136.   pz1 = zb->zbuf + p0->y * zb->xsize;
  137.  
  138.   DRAW_INIT();
  139.  
  140.   for(part=0;part<2;part++) {
  141.     if (part == 0) {
  142.       if (fz > 0) {
  143.         update_left=1;
  144.         update_right=1;
  145.         l1=p0;
  146.         l2=p2;
  147.         pr1=p0;
  148.         pr2=p1;
  149.       } else {
  150.         update_left=1;
  151.         update_right=1;
  152.         l1=p0;
  153.         l2=p1;
  154.         pr1=p0;
  155.         pr2=p2;
  156.       }
  157.       nb_lines = p1->y - p0->y;
  158.     } else {
  159.       /* second part */
  160.       if (fz > 0) {
  161.         update_left=0;
  162.         update_right=1;
  163.         pr1=p1;
  164.         pr2=p2;
  165.       } else {
  166.         update_left=1;
  167.         update_right=0;
  168.         l1=p1;
  169.         l2=p2;
  170.       }
  171.       nb_lines = p2->y - p1->y + 1;
  172.     }
  173.  
  174.     /* compute the values for the left edge */
  175.  
  176.     if (update_left) {
  177.       dy1 = l2->y - l1->y;
  178.       dx1 = l2->x - l1->x;
  179.       if (dy1 > 0)
  180.         tmp = (dx1 << 16) / dy1;
  181.       else
  182.         tmp = 0;
  183.       x1 = l1->x;
  184.       error = 0;
  185.       derror = tmp & 0x0000ffff;
  186.       dxdy_min = tmp >> 16;
  187.       dxdy_max = dxdy_min + 1;
  188.      
  189. #ifdef INTERP_Z
  190.       z1=l1->z;
  191.       dzdl_min=(dzdy + dzdx * dxdy_min);
  192.       dzdl_max=dzdl_min + dzdx;
  193. #endif
  194. #ifdef INTERP_RGB
  195.       r1=l1->r;
  196.       drdl_min=(drdy + drdx * dxdy_min);
  197.       drdl_max=drdl_min + drdx;
  198.      
  199.       g1=l1->g;
  200.       dgdl_min=(dgdy + dgdx * dxdy_min);
  201.       dgdl_max=dgdl_min + dgdx;
  202.      
  203.       b1=l1->b;
  204.       dbdl_min=(dbdy + dbdx * dxdy_min);
  205.       dbdl_max=dbdl_min + dbdx;
  206. #endif
  207. #ifdef INTERP_ST
  208.       s1=l1->s;
  209.       dsdl_min=(dsdy + dsdx * dxdy_min);
  210.       dsdl_max=dsdl_min + dsdx;
  211.      
  212.       t1=l1->t;
  213.       dtdl_min=(dtdy + dtdx * dxdy_min);
  214.       dtdl_max=dtdl_min + dtdx;
  215. #endif
  216. #ifdef INTERP_STZ
  217.       sz1=l1->sz;
  218.       dszdl_min=(dszdy + dszdx * dxdy_min);
  219.       dszdl_max=dszdl_min + dszdx;
  220.      
  221.       tz1=l1->tz;
  222.       dtzdl_min=(dtzdy + dtzdx * dxdy_min);
  223.       dtzdl_max=dtzdl_min + dtzdx;
  224. #endif
  225.     }
  226.  
  227.     /* compute values for the right edge */
  228.  
  229.     if (update_right) {
  230.       dx2 = (pr2->x - pr1->x);
  231.       dy2 = (pr2->y - pr1->y);
  232.       if (dy2>0)
  233.         dx2dy2 = ( dx2 << 16) / dy2;
  234.       else
  235.         dx2dy2 = 0;
  236.       x2 = pr1->x << 16;
  237.     }
  238.  
  239.     /* we draw all the scan line of the part */
  240.  
  241.     while (nb_lines>0) {
  242.       nb_lines--;
  243. #ifndef DRAW_LINE
  244.       /* generic draw line */
  245.       {
  246.           register PIXEL *pp;
  247.           register int n;
  248. #ifdef INTERP_Z
  249.           register unsigned short *pz;
  250.           register unsigned int z,zz;
  251. #endif
  252. #ifdef INTERP_RGB
  253.           register unsigned int or1,og1,ob1;
  254. #endif
  255. #ifdef INTERP_ST
  256.           register unsigned int s,t;
  257. #endif
  258. #ifdef INTERP_STZ
  259.           float sz,tz;
  260. #endif
  261.  
  262.           n=(x2 >> 16) - x1;
  263.           pp=(PIXEL *)((char *)pp1 + x1 * PSZB);
  264. #ifdef INTERP_Z
  265.           pz=pz1+x1;
  266.           z=z1;
  267. #endif
  268. #ifdef INTERP_RGB
  269.           or1 = r1;
  270.           og1 = g1;
  271.           ob1 = b1;
  272. #endif
  273. #ifdef INTERP_ST
  274.           s=s1;
  275.           t=t1;
  276. #endif
  277. #ifdef INTERP_STZ
  278.           sz=sz1;
  279.           tz=tz1;
  280. #endif
  281.           while (n>=3) {
  282.               PUT_PIXEL(0);
  283.               PUT_PIXEL(1);
  284.               PUT_PIXEL(2);
  285.               PUT_PIXEL(3);
  286. #ifdef INTERP_Z
  287.               pz+=4;
  288. #endif
  289.               pp=(PIXEL *)((char *)pp + 4 * PSZB);
  290.               n-=4;
  291.           }
  292.           while (n>=0) {
  293.               PUT_PIXEL(0);
  294. #ifdef INTERP_Z
  295.               pz+=1;
  296. #endif
  297.               pp=(PIXEL *)((char *)pp + PSZB);
  298.               n-=1;
  299.           }
  300.       }
  301. #else
  302.       DRAW_LINE();
  303. #endif
  304.      
  305.       /* left edge */
  306.       error+=derror;
  307.       if (error > 0) {
  308.         error-=0x10000;
  309.         x1+=dxdy_max;
  310. #ifdef INTERP_Z
  311.         z1+=dzdl_max;
  312. #endif      
  313. #ifdef INTERP_RGB
  314.         r1+=drdl_max;
  315.         g1+=dgdl_max;
  316.         b1+=dbdl_max;
  317. #endif
  318. #ifdef INTERP_ST
  319.         s1+=dsdl_max;
  320.         t1+=dtdl_max;
  321. #endif
  322. #ifdef INTERP_STZ
  323.         sz1+=dszdl_max;
  324.         tz1+=dtzdl_max;
  325. #endif
  326.       } else {
  327.         x1+=dxdy_min;
  328. #ifdef INTERP_Z
  329.         z1+=dzdl_min;
  330. #endif      
  331. #ifdef INTERP_RGB
  332.         r1+=drdl_min;
  333.         g1+=dgdl_min;
  334.         b1+=dbdl_min;
  335. #endif
  336. #ifdef INTERP_ST
  337.         s1+=dsdl_min;
  338.         t1+=dtdl_min;
  339. #endif
  340. #ifdef INTERP_STZ
  341.         sz1+=dszdl_min;
  342.         tz1+=dtzdl_min;
  343. #endif
  344.       }
  345.      
  346.       /* right edge */
  347.       x2+=dx2dy2;
  348.  
  349.       /* screen coordinates */
  350.       pp1=(PIXEL *)((char *)pp1 + zb->linesize);
  351.       pz1+=zb->xsize;
  352.     }
  353.   }
  354. }
  355.  
  356. #undef INTERP_Z
  357. #undef INTERP_RGB
  358. #undef INTERP_ST
  359. #undef INTERP_STZ
  360.  
  361. #undef DRAW_INIT
  362. #undef DRAW_LINE  
  363. #undef PUT_PIXEL
  364.