home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 505a.lha / GrapicsGems / AALines / AATables.c < prev    next >
C/C++ Source or Header  |  1991-05-01  |  6KB  |  241 lines

  1. /*  FILENAME: AATables.c  [revised 18 AUG 90]
  2.  
  3.     DESCRIPTION:  Initialization of lookup tables and frame buffer
  4.       for anti-aliased line rendering demo.
  5.  
  6.     LINK WITH:
  7.       AALines.h -- Shared variables and symbols for renderer.
  8.       AAMain.c -- Calling routine for renderer.
  9.       AALines.c -- Anti-aliased line rendering code.
  10. */
  11.  
  12. #include <math.h>
  13. #include "AALines.h"
  14.  
  15. /* programs in this file */
  16. extern void Anti_Init();
  17. static void Sqrt_Init();
  18.  
  19. /* globals defined here */
  20. char *fbuff;
  21. UFX *sqrtfunc=0;
  22. int sqrtcells=1024;
  23. int sqrtshift;
  24.  
  25. /* AA sizes */
  26. float line_r=1.0;     /* line radius */
  27. float pix_r=SQRT_2;   /* pixel radius */
  28. FX *coverage=0;
  29. int covercells=128;
  30. int covershift;
  31.  
  32.  
  33.  
  34.  
  35. /*  ************************************
  36.     *                                  *
  37.     *          Anti_Init               *
  38.     *                                  *
  39.     ************************************
  40.  
  41.     DESCRIPTION:  Initialize everything for the anti-aliased line
  42.       renderer in 'AALines.c':  allocate the frame buffer,
  43.       set up lookup tables, etc.
  44.  
  45.       For hints about initializing the coverage table, see 
  46.       "Area of Intersection: Circle and a Thick Line" on pages
  47.       40-42 of _Graphics_Gems_.
  48. */
  49.  
  50. #define FLOAT_TO_CELL(flt)  ((int) ((flt) * 255.0 + 0.5))
  51. #define MAXVAL_CELL         255
  52.  
  53. void Anti_Init ( )
  54. {
  55. int *thiscell;
  56. double maxdist,nowdist,incdist;
  57. int tablebits,radbits;
  58. int tablecells;
  59. static int tablesize=0;
  60. double fnear,ffar,fcover;
  61. double half,invR,invpiRsq,invpi,Rsq;
  62. double sum_r;
  63. double inv_log_2;
  64. extern FX Pmax;
  65.  
  66. /* alloc & init frame buffer */
  67. fbuff = (char *) malloc( xpix*ypix );
  68.   {
  69.   register int i;
  70.   for ( i=xpix*ypix-1; i>=0; --i )  fbuff[i] = 0;
  71.   }
  72.  
  73. /* init */
  74. inv_log_2 = 1.0 / log( 2.0 );
  75. sum_r = line_r + pix_r;
  76. tablebits = (int) ( log((double)covercells) * inv_log_2 + 0.99 );
  77. radbits = (int) ( log((double)sum_r) * inv_log_2 ) + 1;
  78. covershift = FX_FRACBITS - (tablebits-radbits);
  79.  
  80. /* constants */
  81. half = 0.5;
  82. invR = 1.0 / pix_r;
  83. invpi = 1.0 / PI;
  84. invpiRsq = invpi * invR * invR;
  85. Rsq = pix_r * pix_r;
  86. #define FRACCOVER(d) (half - d*sqrt(Rsq-d*d)*invpiRsq - invpi*asin(d*invR))
  87.  
  88. /* allocate table */
  89. Pmax = FLOAT_TO_FX(sum_r);
  90. Pmax >>= covershift;
  91. tablecells = Pmax + 2;
  92. Pmax <<= covershift;
  93. if ( coverage  &&  tablecells > tablesize )
  94.   { free( coverage ); coverage = 0;  tablesize = 0; }
  95. if ( coverage == 0 )
  96.   {
  97.   coverage = (FX *) malloc( tablecells * sizeof(int) );
  98.   tablesize = tablecells;
  99.   }
  100.  
  101. /* init for fill loops */
  102. nowdist = 0.0;
  103. thiscell = coverage;
  104. incdist = sum_r / (double)(tablecells-2);
  105.  
  106. /* fill fat portion */
  107. if ( pix_r <= line_r )
  108.   {
  109.   maxdist = line_r - pix_r;
  110.   for ( ;
  111.       nowdist <= maxdist;
  112.       nowdist += incdist,  ++thiscell
  113.       )
  114.     {
  115.     *thiscell = MAXVAL_CELL;
  116.     }
  117.   }
  118.  
  119. /* fill skinny portion */
  120. else
  121.   {
  122.   /* loop till edge of line, or end of skinny, whichever comes first */
  123.   maxdist = pix_r - line_r;
  124.   if ( maxdist > line_r )
  125.     maxdist = line_r;
  126.   for ( ;
  127.       nowdist < maxdist;
  128.       nowdist += incdist,  ++thiscell
  129.       )
  130.     {
  131.     fnear = line_r - nowdist;
  132.     ffar = line_r + nowdist;
  133.     fcover = 1.0 - FRACCOVER(fnear) - FRACCOVER(ffar);
  134.     *thiscell = FLOAT_TO_CELL(fcover);
  135.     }
  136.  
  137.   /* loop till end of skinny -- only run on super-skinny */
  138.   maxdist = pix_r - line_r;
  139.   for ( ;
  140.       nowdist < maxdist;
  141.       nowdist += incdist,  ++thiscell
  142.       )
  143.     {
  144.     fnear = nowdist - line_r;
  145.     ffar = nowdist + line_r;
  146.     fcover = FRACCOVER(fnear) - FRACCOVER(ffar);
  147.     *thiscell = FLOAT_TO_CELL(fcover);
  148.     }
  149.   }
  150.  
  151. /* loop till edge of line */
  152. maxdist = line_r;
  153. for ( ;
  154.     nowdist < maxdist;
  155.     nowdist += incdist,  ++thiscell
  156.     )
  157.   {
  158.   fnear = line_r - nowdist;
  159.   fcover = 1.0 - FRACCOVER(fnear);
  160.   *thiscell = FLOAT_TO_CELL(fcover);
  161.   }
  162.  
  163. /* loop till max separation */
  164. maxdist = line_r + pix_r;
  165. for ( ;
  166.     nowdist < maxdist;
  167.     nowdist += incdist,  ++thiscell
  168.     )
  169.   {
  170.   fnear = nowdist - line_r;
  171.   fcover = FRACCOVER(fnear);
  172.   *thiscell = FLOAT_TO_CELL(fcover);
  173.   }
  174.  
  175. /* finish off table */
  176. *thiscell = FLOAT_TO_CELL(0.0);
  177. coverage[tablecells-1] = FLOAT_TO_CELL(0.0);
  178.  
  179. Sqrt_Init();
  180. }
  181.  
  182.  
  183.  
  184.  
  185. /*  *******************************
  186.     *                             *
  187.     *       Sqrt_Init             *
  188.     *                             *
  189.     *******************************
  190.  
  191.     DESCRIPTION:  Initialize the lookup table for the function
  192.       sqrt(1/(1+x^2))).  The table takes a shifted fixed-point
  193.       value as an index and returns a fixed-point value.  Input
  194.       values are in the range [0,1] inclusive.  The number of
  195.       cells in the table is a power of two plus one (the extra
  196.       cell provides an entry for an input value of exactly 1).
  197.  
  198.     GLOBALS:
  199.       sqrtcells -- Number of cells to use in the table (must
  200.     be set before calling this routine).  This number is
  201.     rounded up to the nearest power of two (the global
  202.     variable itself is unchanged).
  203.       sqrtshift -- Bits to shift a fixed-point (FX) number
  204.     to generate a table index.
  205.       sqrtfunc -- Lookup table for the function.
  206. */
  207.  
  208. static void Sqrt_Init ( )
  209. {
  210. UFX *thiscell;
  211. double nowval,incval;
  212. int tablebits;
  213. int tablecells;
  214. double one;
  215.  
  216. /* init */
  217. tablebits = (int) ( log((double)sqrtcells) / log(2.0) + 0.999 );
  218. tablecells = (1 << tablebits) + 1;  /* one more that requested */
  219. sqrtshift = FX_FRACBITS - tablebits;
  220. one = 1.0;
  221.  
  222. /* allocate table */
  223. if ( sqrtfunc )
  224.   free( sqrtfunc );
  225. sqrtfunc = (UFX *) malloc( tablecells * sizeof(int) );
  226.  
  227. /* init for fill loop */
  228. incval = one / (double)(tablecells-1);  /* a negative power of two */
  229.  
  230. for (
  231.     nowval = 0.0,      thiscell = sqrtfunc;
  232.     nowval < 1.0;
  233.     nowval += incval,  ++thiscell
  234.     )
  235.   {
  236.   *thiscell = FLOAT_TO_FX( sqrt(one/(one+nowval*nowval)) );
  237.   }
  238.  
  239. sqrtfunc[tablecells-1] = FLOAT_TO_FX( sqrt(0.5) );
  240. }
  241.