home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #6 / amigamamagazinepolishissue1998.iso / coders / mesa-1.2.8 / src / polytemp.h < prev    next >
C/C++ Source or Header  |  1996-05-27  |  9KB  |  371 lines

  1. /* $Id: polytemp.h,v 1.8 1996/05/09 16:46:34 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  1.2
  6.  * Copyright (C) 1995-1996  Brian Paul  (brianp@ssec.wisc.edu)
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25. $Log: polytemp.h,v $
  26.  * Revision 1.8  1996/05/09  16:46:34  brianp
  27.  * faster edge table construction
  28.  *
  29.  * Revision 1.7  1996/01/19  19:17:19  brianp
  30.  * fixed uninitialized len problem for flat-shaded polygons
  31.  *
  32.  * Revision 1.6  1996/01/19  18:10:09  brianp
  33.  * fixed floating point exception due to float->integer conversion overflow
  34.  *
  35.  * Revision 1.5  1996/01/11  22:52:44  brianp
  36.  * new zptr computation
  37.  *
  38.  * Revision 1.4  1996/01/11  15:47:35  brianp
  39.  * added Y-axis clipping
  40.  *
  41.  * Revision 1.3  1996/01/02  22:13:40  brianp
  42.  * removed old fixed-point macros
  43.  *
  44.  * Revision 1.2  1995/12/30  00:59:40  brianp
  45.  * use integer vertex colors instead of floating point
  46.  * faster computation of z from x and y
  47.  *
  48.  * Revision 1.1  1995/12/21  18:00:57  brianp
  49.  * Initial revision
  50.  *
  51.  */
  52.  
  53.  
  54.  
  55. /*
  56.  * Polygon rasterizer template.
  57.  *
  58.  * By defining certain preprocessor symbols, this general polygon
  59.  * rasterizer is used to generate a number of custom-purpose
  60.  * polygon rasterizers.  See polygons.c and xmesa3.c for examples.
  61.  */
  62.  
  63.  
  64. /*
  65.  * Preprocessor symbols:
  66.  *
  67.  * INTERP_COLOR   - if defined, generate RGB channel interpolation code
  68.  * INTERP_ALPHA   - if defined, also generate alpha channel interpolation code
  69.  * INTERP_Z       - if defined, generate Z-buffer code
  70.  * INTERP_INDEX   - if defined, generate Color Index interpolation code
  71.  *
  72.  * SETUP_CODE     - this optional macro is code which will be executed
  73.  *                  at the top of the polygon function; typically used
  74.  *                  to setup the pixel used for mono-colored polygons
  75.  *
  76.  * INNER_CODE     - this is a macro which must be defined before including
  77.  *                  this file.  It's the innermost code of the rasterizer
  78.  *                  which writes pixels to the color buffer.
  79.  */
  80.  
  81.  
  82.  
  83.  
  84. /*
  85.  * Function header required in .c file:
  86.  *
  87.  *   static void your_polygon_name( GLuint n, GLuint vlist[], GLuint pv )
  88.  *
  89.  */
  90. {
  91.    GLint vert;
  92.    GLint y, ymin, ymax;
  93.    GLfloat yf;
  94.    GLfloat dzdx;
  95.    GLfixed fdzdx;
  96.    GLfloat planea = CC.PlaneA;
  97.    GLfloat planeb = CC.PlaneB;
  98.    GLfloat planec = 1.0F / CC.PlaneC;
  99.    GLfloat planed = CC.PlaneD;
  100.    GLdepth *zrow;
  101.    GLint zrowinc = CC.BufferWidth;
  102.  
  103.    /* Optional, user-supplied setup code: */
  104. #ifdef SETUP_CODE
  105.    SETUP_CODE
  106. #endif
  107.  
  108. #ifdef INTERP_Z
  109.    /* compute fixed point dz/dx */
  110.    dzdx = -planea * planec;
  111.    if (dzdx<-1.0F)      fdzdx = -MAX_DEPTH;
  112.    else if (dzdx>1.0F)  fdzdx = MAX_DEPTH;
  113.    else                 fdzdx = FloatToFixed( dzdx * DEPTH_SCALE );
  114. #endif
  115.  
  116.    ymin = MAX_HEIGHT;
  117.    ymax = -1;
  118.  
  119.    /*** PART 1:  process edges to compute span bounds ***/
  120.    for (vert=0;vert<n;vert++) {
  121.       GLuint j0, j1;
  122.       GLfloat dxdy, b;
  123.       GLint iy0, iy1, idy;
  124.       GLfloat x0, y0, x1, y1;
  125.       GLfixed fx, fdxdy;
  126.       GLfixed r0, dr, g0, dg, b0, db, a0, da;
  127.       GLfixed i0, i1, di;
  128.       GLint len;    /* vertical length of edge */
  129.       GLint leftflag;
  130.  
  131.       /* indexes of the edge vertices */
  132.       j0 = (vert==0) ? vlist[n-1] : vlist[vert-1];
  133.       j1 = vlist[vert];
  134.  
  135.       x0 = VB.Win[j0][0];   y0 = VB.Win[j0][1];
  136.       x1 = VB.Win[j1][0];   y1 = VB.Win[j1][1];
  137.  
  138.       iy0 = (GLint) y0;
  139.       iy1 = (GLint) y1;
  140.  
  141.       if (iy0==iy1) {
  142.      continue;    /* skip horizontal edges */
  143.       }
  144.       else if (iy0<iy1) {
  145.          leftflag = CC.PlaneC < 0.0f;
  146.      dxdy = (x1-x0) / (y1-y0);
  147.      b = x0 - dxdy * y0;         /* b = X intercept */
  148.      len = iy1 - iy0;
  149. #ifdef INTERP_COLOR
  150.      r0 = VB.Color[j0][0];
  151.      g0 = VB.Color[j0][1];
  152.      b0 = VB.Color[j0][2];
  153. #  ifdef INTERP_ALPHA
  154.      a0 = VB.Color[j0][3];
  155. #  endif
  156.          if (len>1) {
  157.             dr = (VB.Color[j1][0] - r0) / len;
  158.             dg = (VB.Color[j1][1] - g0) / len;
  159.             db = (VB.Color[j1][2] - b0) / len;
  160. #  ifdef INTERP_ALPHA
  161.             da = (VB.Color[j1][3] - a0) / len;
  162. #  endif
  163.          }
  164. #endif
  165. #ifdef INTERP_INDEX
  166.          i0 = IntToFixed( VB.Index[j0] );
  167.          if (len>0) {
  168.             i1 = IntToFixed( VB.Index[j1] );
  169.             di = (i1 - i0) / len;
  170.          }
  171. #endif
  172.       }
  173.       else {
  174.      /* y0 > y1 */
  175.          GLint tmp;
  176.          tmp = iy0;  iy0 = iy1;  iy1 = tmp;  /* Swap Y coords */
  177.          leftflag = CC.PlaneC >= 0.0f;
  178.      dxdy = (x0-x1) / (y0-y1);
  179.      b = x1 - dxdy * y1;         /* b = X intercept */
  180.      len = iy1 - iy0;
  181. #ifdef INTERP_COLOR
  182.      r0 = VB.Color[j1][0];
  183.      g0 = VB.Color[j1][1];
  184.      b0 = VB.Color[j1][2];
  185. #  ifdef INTERP_ALPHA
  186.      a0 = VB.Color[j1][3];
  187. #  endif
  188.          if (len>1) {
  189.             dr = (VB.Color[j0][0] - r0) / len;
  190.             dg = (VB.Color[j0][1] - g0) / len;
  191.             db = (VB.Color[j0][2] - b0) / len;
  192. #  ifdef INTERP_ALPHA
  193.             da = (VB.Color[j0][3] - a0) / len;
  194. #  endif
  195.          }
  196. #endif
  197. #ifdef INTERP_INDEX
  198.          i0 = IntToFixed( VB.Index[j1] );
  199.          if (len>0) {
  200.             i1 = IntToFixed( VB.Index[j0] );
  201.             di = (i1 - i0) / len;
  202.          }
  203. #endif
  204.       }
  205.  
  206.       iy0++;
  207.       iy1++;
  208.  
  209.       /* compute span bounds */
  210.       fx = FloatToFixed( iy0 * dxdy + b + 1.0F );
  211.       if (len>1) {
  212.          /* don't compute if <=1 to prevent float->int overflow error */
  213.          fdxdy = FloatToFixed( dxdy );
  214.       }
  215.       else {
  216.          fdxdy = 0;
  217.       }
  218.  
  219.       if (leftflag) {
  220.          /* update left boundary values */
  221.          for (y=iy0; y<iy1; y++) {
  222.             int ix = FixedToInt( fx );
  223.             fx += fdxdy;
  224. #ifdef CLIP_Y
  225.             /* make sure y isn't ouside of array */
  226.             if (y>=0 && y<CC.BufferHeight) {
  227. #endif
  228.             lx[y] = ix;
  229. #ifdef INTERP_COLOR
  230.             lr[y] = r0;   r0 += dr;
  231.             lg[y] = g0;   g0 += dg;
  232.             lb[y] = b0;   b0 += db;
  233. #  ifdef INTERP_ALPHA
  234.         la[y] = a0;   a0 += da;
  235. #  endif
  236. #endif
  237. #ifdef INTERP_INDEX
  238.             li[y] = i0;   i0 += di;
  239. #endif
  240. #ifdef CLIP_Y
  241.             }
  242. #endif
  243.          }
  244.       }
  245.       else {
  246.          /* update right boundary values */
  247.          for (y=iy0; y<iy1; y++) {
  248.             int ix = FixedToInt( fx );
  249.             fx += fdxdy;
  250. #ifdef CLIP_Y
  251.             /* make sure y isn't ouside of array */
  252.             if (y>=0 && y<CC.BufferHeight) {
  253. #endif
  254.             rx[y] = ix;
  255. #ifdef INTERP_COLOR
  256.             rr[y] = r0;   r0 += dr;
  257.             rg[y] = g0;   g0 += dg;
  258.             rb[y] = b0;   b0 += db;
  259. #  ifdef INTERP_ALPHA
  260.         ra[y] = a0;   a0 += da;
  261. #  endif
  262. #endif
  263. #ifdef INTERP_INDEX
  264.             ri[y] = i0;   i0 += di;
  265. #endif
  266. #ifdef CLIP_Y
  267.             }
  268. #endif
  269.          }
  270.       }
  271.  
  272.       /* find min and max y */
  273.       if (iy0 < ymin)  ymin = iy0;
  274.       if (iy0 > ymax)  ymax = iy0;
  275.       if (iy1 < ymin)  ymin = iy1;
  276.       if (iy1 > ymax)  ymax = iy1;
  277.    }
  278.  
  279. #ifdef CLIP_Y
  280.    if (ymin<0) {
  281.       ymin = 0;
  282.    }
  283.    else if (ymax>CC.BufferHeight) {
  284.       ymax = CC.BufferHeight;
  285.    }
  286. #endif
  287.  
  288.    /*** PART 2:  scan convert ***/
  289.    yf = (GLfloat) ymin;
  290.    zrow = Z_ADDRESS( 0, ymin );
  291.    for (y=ymin;y<ymax;y++,yf+=1.0F) {
  292.       GLint xmin = lx[y];
  293.       GLint xmax = rx[y];
  294.       GLint len = xmax-xmin;
  295.  
  296.       /* reset left and right bounds for next polygon */
  297.       lx[y] = MAX_WIDTH;
  298.       rx[y] = -1;
  299.  
  300.       /* render the span w/ optional color interp, depth interp */
  301.       if (len>0) {
  302.          GLint iz0;
  303.          GLfloat z;
  304.          GLfixed fz;
  305.          GLdepth *zptr;
  306.      GLfixed fr, fdrdx, fg, fdgdx, fb, fdbdx, fa, fdadx;
  307.          GLfixed fi, fdidx;
  308.  
  309. #ifdef INTERP_Z
  310.          z = (planed - planea*xmin - planeb*yf) * planec;
  311.          if (z<0.0F) {
  312.             fz = IntToFixed( 0 );
  313.          }
  314.          else if (z>1.0F) {
  315.             fz = IntToFixed( MAX_DEPTH );
  316.          }
  317.          else {
  318.             fz = IntToFixed( (GLint) (z * DEPTH_SCALE) );
  319.          }
  320.  
  321.          zptr = zrow + xmin;
  322. #endif
  323.  
  324. #ifdef INTERP_COLOR
  325.      fr = lr[y];
  326.      fg = lg[y];
  327.      fb = lb[y];
  328. #  ifdef INTERP_ALPHA
  329.      fa = la[y];
  330. #  endif
  331.      if (len>1) {
  332.         fdrdx = (rr[y]-fr) / (len-1);
  333.         fdgdx = (rg[y]-fg) / (len-1);
  334.         fdbdx = (rb[y]-fb) / (len-1);
  335. #  ifdef INTERP_ALPHA
  336.         fdadx = (ra[y]-fa) / (len-1);
  337. #  endif
  338.          }
  339. #endif
  340. #ifdef INTERP_INDEX
  341.          fi = li[y];
  342.          if (len>1) {
  343.             fdidx = (ri[y]-fi) / (len-1);
  344.          }
  345. #endif
  346.  
  347.          {
  348.             INNER_CODE
  349.          }
  350.  
  351.       } /* if len>0 */
  352.  
  353. #ifdef INTERP_Z
  354.       zrow += zrowinc;
  355. #endif
  356.  
  357.    } /* for y */
  358.  
  359. }
  360.  
  361.  
  362.  
  363. #undef INTERP_COLOR
  364. #undef INTERP_ALPHA
  365. #undef INTERP_Z
  366. #undef INTERP_INDEX
  367. #undef SETUP_CODE
  368. #undef INNER_CODE
  369. #undef CLIP_Y
  370.  
  371.