Advertisement
Guest User

scanline cs351

a guest
Dec 17th, 2014
144
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 17.27 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <math.h>
  5. #include "scanline.h"
  6. #include "list.h"
  7. #include "objects.h"
  8. // #include "matrix.h"
  9.  
  10. // define the struct here, because it is local to only this file
  11. typedef struct tEdge {
  12.   float x0, y0;                   /* start point for the edge */
  13.   float x1, y1;                   /* end point for the edge */
  14.   int yStart, yEnd;               /* start row and end row */
  15.   float xIntersect, dxPerScan;    /* where the edge intersects the current scanline and how it changes */
  16.   float zIntersect, dzPerScan;      /* z-buffer things */
  17.   Color cIntersect, dcPerScan;    /* gouraud shading */
  18.   float tIntersect, dtPerScan;
  19.   float sIntersect, dsPerScan;
  20.   // need to add s and t stuff
  21.   /* we'll add more here later */
  22.   struct tEdge *next;
  23. } Edge;
  24.  
  25. /********************
  26. Scanline Fill Algorithm
  27. ********************/
  28.  
  29. inline float max(float a, float b){
  30.   return a>b ? a : b;
  31. }
  32.  
  33. /*
  34.     This is a comparison function that returns a value < 0 if a < b, a
  35.     value > 0 if a > b, and 0 if a = b.  It uses the yStart field of the
  36.     Edge structure.  It is used to sort the overall edge list.
  37.  */
  38. static int compYStart( const void *a, const void *b ) {
  39.     Edge *ea = (Edge *)a;
  40.     Edge *eb = (Edge *)b;
  41.  
  42.     return(ea->yStart - eb->yStart);
  43. }
  44.  
  45.  
  46. /*
  47.     This is a comparison function that returns a value < 0 if a < b, a
  48.     value > 0 if a > b, and 0 if a = b.  It uses the xIntersect field of the
  49.     Edge structure.  It is used to sort the active edge list.
  50.  */
  51. static int compXIntersect( const void *a, const void *b ) {
  52.     Edge *ea = (Edge *)a;
  53.     Edge *eb = (Edge *)b;
  54.  
  55.     if( ea->xIntersect < eb->xIntersect )
  56.         return(-1);
  57.     else if(ea->xIntersect > eb->xIntersect )
  58.         return(1);
  59.  
  60.     return(0);
  61. }
  62.  
  63. /*
  64.     Allocates, creates, fills out, and returns an Edge structure given
  65.     the inputs.
  66.  
  67.     Current inputs are just the start and end location in image space.
  68.     Eventually, the points will be 3D and we'll add color and texture
  69.     coordinates.
  70.  */
  71. static Edge *makeEdgeRec( Point start, Point end, Image *src, int zFlag,
  72.     int dsFlag, Color c1, Color c2, float* s1, float* s2)
  73. {
  74.   Edge *edge;
  75.   float dscan = end.val[1] - start.val[1];
  76.  
  77.   if (start.val[1]>src->rows || end.val[1]<0){
  78.     return ((Edge *)NULL);
  79.     // print("returning NULL\n");
  80.   }
  81.  
  82.   edge = malloc(sizeof(Edge));
  83.   edge->x0 = start.val[0];
  84.   edge->x1 = end.val[0];
  85.   edge->y0 = start.val[1];
  86.   edge->y1 = end.val[1];
  87.  
  88.   edge->yStart = (int)(edge->y0+0.5);
  89.   edge->yEnd = (int)(edge->y1+0.5)-1;
  90.  
  91.   if (edge->yEnd >= src->rows){
  92.     edge->yEnd = src->rows-1;
  93.   }
  94.   edge->dxPerScan = ( edge->x1 - edge->x0 )/(dscan);
  95.   edge->xIntersect = start.val[0];
  96.   if (zFlag != 0){
  97.     edge->zIntersect = 1/start.val[2];
  98.     edge->dzPerScan = ((1/end.val[2])-(1/start.val[2]))/dscan;
  99.   }
  100.   if (dsFlag == 2){ // shade gouraud
  101.     edge->dcPerScan.c[0] = ((c2.c[0]/(1/end.val[2]))-(c1.c[0]/(1/start.val[2])))/dscan;
  102.     edge->dcPerScan.c[1] = ((c2.c[1]/(1/end.val[2]))-(c1.c[1]/(1/start.val[2])))/dscan;
  103.     edge->dcPerScan.c[2] = ((c2.c[2]/(1/end.val[2]))-(c1.c[2]/(1/start.val[2])))/dscan;
  104.     edge->cIntersect.c[0] = c1.c[0]/(1/start.val[2]);
  105.     edge->cIntersect.c[1] = c1.c[1]/(1/start.val[2]);
  106.     edge->cIntersect.c[2] = c1.c[2]/(1/start.val[2]);
  107.   }
  108.   if (dsFlag == 3){ // shade texture
  109.     edge->dsPerScan = ((s2[0]/(1/end.val[2]))-(s1[0]/(1/start.val[2])))/dscan;
  110.     edge->dtPerScan = ((s2[1]/(1/end.val[2]))-(s1[1]/(1/start.val[2])))/dscan;
  111.     edge->sIntersect = s1[0]/(1/start.val[2]);
  112.     edge->tIntersect = s1[1]/(1/start.val[2]);
  113.   }
  114.  
  115.   if (edge->y0 - floor(edge->y0) <= 0.5){
  116.     edge->xIntersect += ((0.5-(floor(edge->y0)-edge->y0))*edge->dxPerScan);
  117.     if (zFlag != 0){
  118.       edge->zIntersect += ((0.5-(floor(edge->y0)-edge->y0))*edge->dzPerScan);
  119.     }
  120.     if (dsFlag == 2){
  121.       edge->cIntersect.c[0] += ((0.5-(floor(edge->y0)-edge->y0))*edge->dcPerScan.c[0]);
  122.       edge->cIntersect.c[1] += ((0.5-(floor(edge->y0)-edge->y0))*edge->dcPerScan.c[1]);
  123.       edge->cIntersect.c[2] += ((0.5-(floor(edge->y0)-edge->y0))*edge->dcPerScan.c[2]);
  124.     }
  125.     else if (dsFlag == 3){
  126.       edge->sIntersect += ((0.5-(floor(edge->y0)-edge->y0))*edge->dsPerScan);
  127.       edge->tIntersect += ((0.5-(floor(edge->y0)-edge->y0))*edge->dtPerScan);
  128.     }
  129.   }
  130.  
  131.   else {
  132.     edge->xIntersect += (((1.0-(floor(edge->y0)-edge->y0))+0.5)*edge->dxPerScan);
  133.     if (zFlag !=0){
  134.       edge->zIntersect += (((1.0-(floor(edge->y0)-edge->y0))+0.5)*edge->dzPerScan);
  135.     }
  136.     if (dsFlag == 2){
  137.       edge->cIntersect.c[0] += (((1.0-(floor(edge->y0)-edge->y0))+0.5)*edge->dcPerScan.c[0]);
  138.       edge->cIntersect.c[1] += (((1.0-(floor(edge->y0)-edge->y0))+0.5)*edge->dcPerScan.c[1]);
  139.       edge->cIntersect.c[2] += (((1.0-(floor(edge->y0)-edge->y0))+0.5)*edge->dcPerScan.c[2]);
  140.     }
  141.     else if (dsFlag == 3){
  142.       edge->sIntersect += (((1.0-(floor(edge->y0)-edge->y0))+0.5)*edge->dsPerScan);
  143.       edge->tIntersect += (((1.0-(floor(edge->y0)-edge->y0))+0.5)*edge->dtPerScan);
  144.     }
  145.   }
  146.  
  147.   if (edge->y0 < 0){
  148.     printf("*** yStart less than zero ***\n");
  149.     edge->yStart = 0;
  150.     edge->xIntersect += fabs(edge->y0)*edge->dxPerScan;
  151.     if (zFlag != 0){
  152.       edge->zIntersect += fabs(edge->y0)*edge->dzPerScan;
  153.     }
  154.     if (dsFlag == 2){
  155.       edge->cIntersect.c[0] += fabs(edge->y0)*edge->dcPerScan.c[0];
  156.       edge->cIntersect.c[1] += fabs(edge->y0)*edge->dcPerScan.c[1];
  157.       edge->cIntersect.c[2] += fabs(edge->y0)*edge->dcPerScan.c[2];
  158.     }
  159.     else if (dsFlag == 3){
  160.       edge->sIntersect += fabs(edge->y0)*edge->dsPerScan;
  161.       edge->tIntersect += fabs(edge->y0)*edge->dtPerScan;
  162.     }
  163.   }
  164.  
  165.   if (edge->dxPerScan > 0 && edge->xIntersect > edge->x1){
  166.     edge->xIntersect = edge->x1;
  167.     if (zFlag != 0){
  168.       edge->zIntersect = 1/end.val[2];
  169.     }
  170.     if (dsFlag == 2){
  171.       edge->cIntersect.c[0] = c2.c[0]/(1/end.val[2]);
  172.       edge->cIntersect.c[1] = c2.c[1]/(1/end.val[2]);
  173.       edge->cIntersect.c[2] = c2.c[2]/(1/end.val[2]);
  174.     }
  175.     else if (dsFlag == 3){
  176.       edge->sIntersect = s2[0]/(1/end.val[2]);
  177.       edge->tIntersect = s2[1]/(1/end.val[2]);
  178.     }
  179.   }
  180.   else if (edge->dxPerScan < 0 && edge->xIntersect < edge->x1){
  181.     edge->xIntersect = edge->x1;
  182.     if (zFlag != 0){
  183.       edge->zIntersect = 1/end.val[2];
  184.     }
  185.     if (dsFlag == 2){
  186.       edge->cIntersect.c[0] = c2.c[0]/(1/end.val[2]);
  187.       edge->cIntersect.c[1] = c2.c[1]/(1/end.val[2]);
  188.       edge->cIntersect.c[2] = c2.c[2]/(1/end.val[2]);
  189.     }
  190.     else if (dsFlag == 3){
  191.       edge->sIntersect = s2[0]/(1/end.val[2]);
  192.       edge->tIntersect = s2[1]/(1/end.val[2]);
  193.     }
  194.   }
  195.   return( edge );
  196. }
  197.  
  198.  
  199. /*
  200.     Returns a list of all the edges in the polygon in sorted order by
  201.     smallest row.
  202. */
  203. static LinkedList *setupEdgeList( Polygon *p, Image *src, int dsFlag) {
  204.   LinkedList *edges = NULL;
  205.   Point v1, v2;
  206.   Color c1, c2;
  207.   int i;
  208.   float s1[2], s2[2];
  209.  
  210.   edges = ll_new();
  211.  
  212.   v1 = p->vertex[p->nVertex-1];
  213.   if (dsFlag == 2){
  214.     color_copy(&c1, &p->color[p->nVertex-1]);
  215.   }
  216.   else if (dsFlag == 3){
  217.     s1[0] = p->s[p->nVertex-1];
  218.     s1[1] = p->t[p->nVertex-1];
  219.   }
  220.  
  221.   for(i=0;i<p->nVertex;i++) {
  222.        
  223.     v2 = p->vertex[i];
  224.     if (dsFlag == 2){
  225.       color_copy(&c2, &p->color[i]);
  226.     }
  227.     else if (dsFlag == 3){
  228.       s2[0] = p->s[i];
  229.       s2[1] = p->t[i];
  230.     }
  231.    
  232.     if( (int)(v1.val[1]+0.5) != (int)(v2.val[1]+0.5) ) {
  233.       Edge *edge;
  234.  
  235.       if( v1.val[1] < v2.val[1] ){
  236.         if (dsFlag == 3){
  237.           edge = makeEdgeRec( v1, v2, src, p->zBuffer, dsFlag, c1, c2, s1, s2);
  238.         }
  239.         else {
  240.           edge = makeEdgeRec( v1, v2, src, p->zBuffer, dsFlag, c1, c2, NULL, NULL);
  241.         }
  242.       }
  243.       else {
  244.         if (dsFlag == 3){
  245.           edge = makeEdgeRec( v2, v1, src, p->zBuffer, dsFlag, c2, c1, s2, s1);
  246.         }
  247.         else {
  248.           edge = makeEdgeRec( v2, v1, src, p->zBuffer, dsFlag, c2, c1, NULL, NULL);
  249.         }
  250.       }
  251.       if( edge ){
  252.         ll_insert( edges, edge, compYStart );
  253.       }        
  254.     }
  255.     v1 = v2;
  256.     if (dsFlag == 2){
  257.       color_copy(&c2, &c1);
  258.     }
  259.     else if (dsFlag == 3){
  260.       s1[0] = s2[0];
  261.       s1[1] = s2[1];
  262.     }
  263.   }
  264.  
  265.   // check for empty edges (like nothing in the viewport)
  266.   if( ll_empty( edges ) ) {
  267.     ll_delete( edges, NULL );
  268.     edges = NULL;
  269.   }
  270.   return(edges);
  271. }
  272.  
  273. /*
  274.     Draw one scanline of a polygon given the scanline, the active edges,
  275.     a DrawState, the image, and some Lights (for Phong shading only).
  276.  */
  277. static void fillScan( int scan, LinkedList *active, Image *src, Color c,
  278.   int zFlag, int dsFlag, Mipmap *mipmap ) {
  279.   Edge *p1, *p2;
  280.   int i, j, start, finish;
  281.   float zBuffer = 1.0, dzPerCol = 0.0;
  282.   Color tc;
  283.   color_copy(&tc, &c);
  284.   Color dcPerCol; // c2,
  285.   float dsPerCol, dtPerCol;
  286.   float s, t;
  287.   float dim, lev, tmp;
  288.   int levUp, levLow;
  289.  
  290.   p1 = ll_head( active );
  291.  
  292.   while(p1) {
  293.     p2 = ll_next( active );
  294.    
  295.     if( !p2 ) {
  296.         printf("*** bad bad bad (your edges are not coming in pairs) ***\n");
  297.         break;
  298.     }
  299.  
  300.     if( p2->xIntersect == p1->xIntersect ) {
  301.       p1 = ll_next( active );
  302.       continue;
  303.     }
  304.  
  305.     start = (int)(p1->xIntersect + 0.5);
  306.     finish = (int)(p2->xIntersect + 0.5);
  307.  
  308.     if (zFlag != 0){
  309.       zBuffer = p1->zIntersect;
  310.       dzPerCol = (p2->zIntersect - p1->zIntersect)/(p2->xIntersect-p1->xIntersect);
  311.     }
  312.  
  313.     if (dsFlag == 2){
  314.       // c2 = p2->cIntersect;
  315.       dcPerCol.c[0] = (p2->cIntersect.c[0]-p1->cIntersect.c[0])/(p2->xIntersect-p1->xIntersect);
  316.       dcPerCol.c[1] = (p2->cIntersect.c[1]-p1->cIntersect.c[1])/(p2->xIntersect-p1->xIntersect);
  317.       dcPerCol.c[2] = (p2->cIntersect.c[0]-p1->cIntersect.c[2])/(p2->xIntersect-p1->xIntersect);
  318.       color_copy(&tc, &p1->cIntersect);
  319.     }
  320.     else if (dsFlag == 3){
  321.       s = p1->sIntersect;
  322.       t = p1->tIntersect;
  323.       dsPerCol = (p2->sIntersect-p1->sIntersect)/(p2->xIntersect-p1->xIntersect);
  324.       dtPerCol = (p2->tIntersect-p1->tIntersect)/(p2->xIntersect-p1->xIntersect);
  325.       float ds1dy = p1->dsPerScan-(p1->dxPerScan*dsPerCol);
  326.       float ds2dy = p2->dsPerScan-(p2->dxPerScan*dsPerCol);
  327.       float dt1dy = p1->dtPerScan-(p1->dxPerScan*dtPerCol);
  328.       float dt2dy = p2->dtPerScan-(p2->dxPerScan*dtPerCol);
  329.       float ds = max(max(dsPerCol, ds1dy),max(ds2dy, dsPerCol+ds2dy-ds1dy));
  330.       float dt = max(max(dtPerCol, dt1dy),max(dt2dy, dtPerCol+dt2dy-dt1dy));
  331.       dim = fabs(max(ds, dt));
  332.       if (dim == 0){
  333.         lev = 1.0/256; // is this right? shouldn't it be 256?
  334.       }
  335.       if (dim<1.0){
  336.         lev = fabs(log2f(256*dim));
  337.       }
  338.       else {
  339.         lev = log2f(256*dim);
  340.       }
  341.       tmp = lev - (int)lev;
  342.       if (lev<8.0){
  343.         levLow = 256;
  344.         levUp = 0;
  345.         for (i=0; i<(int)lev; i++){
  346.           // level 0 ofset is 0
  347.           printf("levLow: %d\nlevUp: %d\n", levLow, levUp);
  348.           levLow += exp2(7-i);
  349.           levUp += exp2(8-i);
  350.         }
  351.       }
  352.       else{
  353.         lev=8.0;
  354.         levUp = 510;
  355.         levLow = 510;
  356.       }
  357.     }
  358.  
  359.     if (start < 0){
  360.       if (zFlag != 0){
  361.         zBuffer += (-start)*dzPerCol;
  362.       }
  363.       if (dsFlag == 2){
  364.         tc.c[0] += (-start)*(dcPerCol.c[0]/zBuffer);
  365.         tc.c[1] += (-start)*(dcPerCol.c[1]/zBuffer);
  366.         tc.c[2] += (-start)*(dcPerCol.c[2]/zBuffer);
  367.       }
  368.       else if (dsFlag == 3){
  369.         s += (-start)*(dsPerCol/zBuffer);
  370.         t += (-start)*(dtPerCol/zBuffer);
  371.       }
  372.       start = 0;
  373.     }
  374.     finish = finish>=src->cols ? src->cols : finish;
  375.  
  376.     for (i=start; i<finish; i++){
  377.       if ( zFlag != 0 && zBuffer < src->data[scan][i].z){
  378.         zBuffer += dzPerCol;
  379.         continue;
  380.       }
  381.       if (dsFlag == 1){
  382.         tc.c[0] = c.c[0]*(1-(1/zBuffer));
  383.         tc.c[1] = c.c[1]*(1-(1/zBuffer));
  384.         tc.c[2] = c.c[2]*(1-(1/zBuffer));
  385.       }
  386.       else if (dsFlag == 3){
  387.         // and here and makeEdgeRec above
  388.         tc.c[0] = ((1.0-tmp)*mipmap->data[levLow+(int)(s*exp2(7-(int)lev))]
  389.                                          [levLow+(int)(t*exp2(7-(int)lev))]) +
  390.             ((1.0-(1.0-tmp))*mipmap->data[levUp+(int)(s*exp2(8-(int)lev))]
  391.                                          [levUp+(int)(t*exp2(8-(int)lev))])/zBuffer;
  392.  
  393.         tc.c[1] = ((1.0-tmp)*mipmap->data[levLow+(int)(s*exp2(7-(int)lev))+(int)exp2(7-(int)lev)]
  394.                                          [levLow+(int)(t*exp2(7-(int)lev))]) +
  395.             ((1.0-(1.0-tmp))*mipmap->data[levUp+(int)(s*exp2(8-(int)lev))+(int)exp2(8-(int)lev)]
  396.                                          [levUp+(int)(t*exp2(8-(int)lev))])/zBuffer;
  397.  
  398.         tc.c[2] = ((1.0-tmp)*mipmap->data[levLow+(int)(s*exp2(7-(int)lev))]
  399.                                          [levLow+(int)(t*exp2(7-(int)lev))+(int)exp2(7-(int)lev)]) +
  400.             ((1.0-(1.0-tmp))*mipmap->data[levUp+(int)(s*exp2(8-(int)lev))]
  401.                                          [levUp+(int)(t*exp2(8-(int)lev))+(int)exp2(8-(int)lev)])/zBuffer;
  402.       }
  403.       src->data[scan][i].z = zBuffer;
  404.       image_setColor(src, scan, i, tc);
  405.       if (zFlag != 0){
  406.         zBuffer += dzPerCol/zBuffer;
  407.       }
  408.       if (dsFlag == 2){
  409.         tc.c[0] += dcPerCol.c[0]/zBuffer;
  410.         tc.c[1] += dcPerCol.c[1]/zBuffer;
  411.         tc.c[2] += dcPerCol.c[2]/zBuffer;
  412.       }
  413.       else if (dsFlag == 3){
  414.         s += dsPerCol/zBuffer;
  415.         t += dtPerCol/zBuffer;
  416.       }
  417.     }
  418.     p1 = ll_next( active );
  419.   }
  420.   return;
  421. }
  422.  
  423. /*
  424.    Process the edge list, assumes the edges list has at least one entry
  425. */
  426. static int processEdgeList( LinkedList *edges, Image *src, Color c, int zFlag, int dsFlag, Mipmap *mipmap ) {
  427.   LinkedList *active = NULL;
  428.   LinkedList *tmplist = NULL;
  429.   LinkedList *transfer = NULL;
  430.   Edge *current;
  431.   Edge *tedge;
  432.   int scan = 0;
  433.  
  434.   active = ll_new( );
  435.   tmplist = ll_new( );
  436.  
  437.   // get a pointer to the first item on the list and reset the current pointer
  438.   current = ll_head( edges );
  439.  
  440.   // start at the first scanline and go until the active list is empty
  441.   for(scan = current->yStart;scan < src->rows;scan++ ) {
  442.  
  443.     // grab all edges starting on this row
  444.     while( current != NULL && current->yStart == scan ) {
  445.       ll_insert( active, current, compXIntersect );
  446.       current = ll_next( edges );
  447.     }
  448.     // current is either null, or the first edge to be handled on some future scanline
  449.  
  450.     if( ll_empty(active) ) {
  451.       break;
  452.     }
  453.  
  454.     // if there are active edges
  455.     // fill out the scanline
  456.     fillScan( scan, active, src, c, zFlag, dsFlag, mipmap);
  457.  
  458.     // remove any ending edges and update the rest
  459.     for( tedge = ll_pop( active ); tedge != NULL; tedge = ll_pop( active ) ) {
  460.  
  461.       // keep anything that's not ending
  462.       if( tedge->yEnd > scan ) {
  463.         float a = 1.0;
  464.  
  465.         // update the edge information with the dPerScan values
  466.         tedge->xIntersect += tedge->dxPerScan;
  467.         if (zFlag != 0){
  468.           tedge->zIntersect += tedge->dzPerScan;
  469.         }
  470.         if (dsFlag == 2){
  471.           tedge->cIntersect.c[0] += tedge->dcPerScan.c[0];
  472.           tedge->cIntersect.c[1] += tedge->dcPerScan.c[1];
  473.           tedge->cIntersect.c[2] += tedge->dcPerScan.c[2];
  474.         }
  475.         else if (dsFlag == 3){
  476.           tedge->sIntersect += tedge->dsPerScan;
  477.           tedge->tIntersect += tedge->dtPerScan;
  478.         }
  479.        
  480.         // adjust in the case of partial overlap
  481.         if( tedge->dxPerScan < 0.0 && tedge->xIntersect < tedge->x1 ) {
  482.           a = (tedge->xIntersect - tedge->x1) / tedge->dxPerScan;
  483.           tedge->xIntersect = tedge->x1;
  484.           if (zFlag!=0){
  485.             tedge->zIntersect += a*tedge->dzPerScan;
  486.           }
  487.           if (dsFlag == 2){
  488.             tedge->cIntersect.c[0] += a*tedge->dcPerScan.c[0];
  489.             tedge->cIntersect.c[1] += a*tedge->dcPerScan.c[1];
  490.             tedge->cIntersect.c[2] += a*tedge->dcPerScan.c[2];
  491.           }
  492.           else if (dsFlag == 3){
  493.             tedge->sIntersect += a*tedge->dsPerScan;
  494.             tedge->tIntersect += a*tedge->dtPerScan;
  495.           }
  496.         }
  497.  
  498.         else if( tedge->dxPerScan > 0.0 && tedge->xIntersect > tedge->x1 ) {
  499.           a = (tedge->xIntersect - tedge->x1) / tedge->dxPerScan;
  500.           tedge->xIntersect = tedge->x1;
  501.           if (zFlag!=0){
  502.             tedge->zIntersect += a*tedge->dzPerScan;
  503.           }
  504.           if (dsFlag == 2){
  505.             tedge->cIntersect.c[0] += a*tedge->dcPerScan.c[0];
  506.             tedge->cIntersect.c[1] += a*tedge->dcPerScan.c[1];
  507.             tedge->cIntersect.c[2] += a*tedge->dcPerScan.c[2];
  508.           }
  509.           else if (dsFlag == 3){
  510.             tedge->sIntersect += a*tedge->dsPerScan;
  511.             tedge->tIntersect += a*tedge->dtPerScan;
  512.           }
  513.         }
  514.         ll_insert( tmplist, tedge, compXIntersect );
  515.       }
  516.     }
  517.     transfer = active;
  518.     active = tmplist;
  519.     tmplist = transfer;
  520.   }
  521.  
  522.   // get rid of the lists, but not the edge records
  523.   ll_delete(active, NULL);
  524.   ll_delete(tmplist, NULL);
  525.  
  526.   return(0);
  527. }
  528.  
  529. void scanline_drawFill(Polygon *p, Image *src, Color c, int dsFlag, Mipmap *mipmap){
  530.     LinkedList *edges = NULL;
  531.  
  532.     edges = setupEdgeList( p, src, dsFlag );
  533.  
  534.     if( !edges ) {
  535.       return;
  536.     }
  537.  
  538.     processEdgeList( edges, src, c, p->zBuffer, dsFlag, mipmap);
  539.  
  540.     ll_delete( edges, (void (*)(const void *))free );
  541.  
  542.     return;
  543. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement