home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga 5 / MA_Cover_5.iso / ppc / mesa / src / linetemp.h < prev    next >
Encoding:
C/C++ Source or Header  |  1998-01-31  |  12.1 KB  |  513 lines

  1. /* $Id: linetemp.h,v 1.3 1997/06/20 02:49:53 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  2.3
  6.  * Copyright (C) 1995-1997  Brian Paul
  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: linetemp.h,v $
  26.  * Revision 1.3  1997/06/20 02:49:53  brianp
  27.  * changed color components from GLfixed to GLubyte
  28.  *
  29.  * Revision 1.2  1997/05/16 01:54:54  brianp
  30.  * zPtrYstep calculation was negated!
  31.  *
  32.  * Revision 1.1  1997/03/16 02:07:56  brianp
  33.  * Initial revision
  34.  *
  35.  */
  36.  
  37.  
  38. /*
  39.  * Line Rasterizer Template
  40.  *
  41.  * This file is #include'd to generate custom line rasterizers.
  42.  *
  43.  * The following macros may be defined to indicate what auxillary information
  44.  * must be interplated along the line:
  45.  *    INTERP_Z      - if defined, interpolate Z values
  46.  *    INTERP_RGB    - if defined, interpolate RGB values
  47.  *    INTERP_ALPHA  - if defined, interpolate Alpha values
  48.  *    INTERP_INDEX  - if defined, interpolate color index values
  49.  *    INTERP_ST     - if defined, interpolate integer ST texcoords
  50.  *                         (fast, simple 2-D texture mapping)
  51.  *    INTERP_STW    - if defined, interpolate float ST texcoords and W
  52.  *                         (2-D texture maps with perspective correction)
  53.  *    INTERP_UV     - if defined, interpolate float UV texcoords too
  54.  *                         (for 3-D, 4-D? texture maps)
  55.  *
  56.  * When one can directly address pixels in the color buffer the following
  57.  * macros can be defined and used to directly compute pixel addresses during
  58.  * rasterization (see pixelPtr):
  59.  *    PIXEL_TYPE          - the datatype of a pixel (GLubyte, GLushort, GLuint)
  60.  *    BYTES_PER_ROW       - number of bytes per row in the color buffer
  61.  *    PIXEL_ADDRESS(X,Y)  - returns the address of pixel at (X,Y) where
  62.  *                          Y==0 at bottom of screen and increases upward.
  63.  *
  64.  * Optionally, one may provide one-time setup code
  65.  *    SETUP_CODE    - code which is to be executed once per line
  66.  *
  67.  * To enable line stippling define STIPPLE = 1
  68.  * To enable wide lines define WIDE = 1
  69.  * 
  70.  * To actually "plot" each pixel either the PLOT macro or
  71.  * (XMAJOR_PLOT and YMAJOR_PLOT macros) must be defined...
  72.  *    PLOT(X,Y) - code to plot a pixel.  Example:
  73.  *                if (Z < *zPtr) {
  74.  *                   *zPtr = Z;
  75.  *                   color = pack_rgb( FixedToInt(r0), FixedToInt(g0),
  76.  *                                     FixedToInt(b0) );
  77.  *                   put_pixel( X, Y, color );
  78.  *                }
  79.  *
  80.  * This code was designed for the origin to be in the lower-left corner.
  81.  *
  82.  */
  83.  
  84.  
  85. /*void line( GLcontext *ctx, GLuint vert0, GLuint vert1, GLuint pvert )*/
  86. {
  87.    struct vertex_buffer *VB = ctx->VB;
  88. /*
  89.    GLint x0 = (GLint) VB->Win[vert0][0], dx = (GLint) VB->Win[vert1][0] - x0;
  90.    GLint y0 = (GLint) VB->Win[vert0][1], dy = (GLint) VB->Win[vert1][1] - y0;
  91. */
  92.    GLint x0 = (GLint) VB->Win[vert0][0], x1 = (GLint) VB->Win[vert1][0];
  93.    GLint y0 = (GLint) VB->Win[vert0][1], y1 = (GLint) VB->Win[vert1][1];
  94.    GLint dx, dy;
  95. #if INTERP_XY
  96.    GLint xstep, ystep;
  97. #endif
  98. #if INTERP_Z
  99.    GLint z0, z1, dz, zPtrXstep, zPtrYstep;
  100.    GLdepth *zPtr;
  101. #endif
  102. #if INTERP_RGB
  103.    GLfixed r0 = IntToFixed(VB->Color[vert0][0]);
  104.    GLfixed dr = IntToFixed(VB->Color[vert1][0]) - r0;
  105.    GLfixed g0 = IntToFixed(VB->Color[vert0][1]);
  106.    GLfixed dg = IntToFixed(VB->Color[vert1][1]) - g0;
  107.    GLfixed b0 = IntToFixed(VB->Color[vert0][2]);
  108.    GLfixed db = IntToFixed(VB->Color[vert1][2]) - b0;
  109. #endif
  110. #if INTERP_ALPHA
  111.    GLfixed a0 = IntToFixed(VB->Color[vert0][3]);
  112.    GLfixed da = IntToFixed(VB->Color[vert1][3]) - a0;
  113. #endif
  114. #if INTERP_INDEX
  115.    GLint i0 = VB->Index[vert0] << 8,  di = (GLint) (VB->Index[vert1] << 8)-i0;
  116. #endif
  117. #if INTERP_ST
  118.    GLfixed s0 = FloatToFixed(VB->TexCoord[vert0][0] * S_SCALE);
  119.    GLfixed ds = FloatToFixed(VB->TexCoord[vert1][0] * S_SCALE) - s0;
  120.    GLfixed t0 = FloatToFixed(VB->TexCoord[vert0][1] * T_SCALE);
  121.    GLfixed dt = FloatToFixed(VB->TexCoord[vert1][1] * T_SCALE) - t0;
  122. #endif
  123. #if INTERP_STW
  124.    GLfloat s0 = VB->TexCoord[vert0][0], ds = VB->TexCoord[vert1][0] - s0;
  125.    GLfloat t0 = VB->TexCoord[vert0][1], dt = VB->TexCoord[vert1][1] - t0;
  126.    GLfloat w0 = 1.0F / VB->Clip[vert0][3], dw = 1.0F / VB->Clip[vert1][3] - w0;
  127. #endif
  128. #if INTERP_UV
  129.    GLfloat u0 = VB->TexCoord[vert0][2], du = VB->TexCoord[vert1][2] - u0;
  130.    GLfloat v0 = VB->TexCoord[vert0][3], dv = VB->TexCoord[vert1][3] - v0;
  131. #endif
  132. #ifdef PIXEL_ADDRESS
  133.    PIXEL_TYPE *pixelPtr;
  134.    GLint pixelXstep, pixelYstep;
  135. #endif
  136.  
  137. #if WIDE
  138.    GLint width, min, max;
  139.    width = (GLint) CLAMP( ctx->Line.Width, MIN_LINE_WIDTH, MAX_LINE_WIDTH );
  140.    min = -width / 2;
  141.    max = min + width - 1;
  142. #endif
  143.  
  144. /*
  145.  * Despite being clipped to the view volume, the line's window coordinates
  146.  * may just lie outside the window bounds.  That is, if the legal window
  147.  * coordinates are [0,W-1][0,H-1], it's possible for x==W and/or y==H.
  148.  * This quick and dirty code nudges the endpoints inside the window if
  149.  * necessary.
  150.  */
  151. #if CLIP_HACK
  152.    {
  153.       GLint w = ctx->Buffer->Width;
  154.       GLint h = ctx->Buffer->Height;
  155.       if ((x0==w) | (x1==w)) {
  156.          if ((x0==w) & (x1==w))
  157.            return;
  158.          x0 -= x0==w;
  159.          x1 -= x1==w;
  160.       }
  161.       if ((y0==h) | (y1==h)) {
  162.          if ((y0==h) & (y1==h))
  163.            return;
  164.          y0 -= y0==h;
  165.          y1 -= y1==h;
  166.       }
  167.    }
  168. #endif
  169.    dx = x1 - x0;
  170.    dy = y1 - y0;
  171.    if (dx==0 && dy==0) {
  172.       return;
  173.    }
  174.  
  175.    /*
  176.     * Setup
  177.     */
  178. #ifdef SETUP_CODE
  179.    SETUP_CODE
  180. #endif
  181.  
  182. #if INTERP_Z
  183.    zPtr = Z_ADDRESS(ctx,x0,y0);
  184. #  if DEPTH_BITS==16
  185.       z0 = FloatToFixed(VB->Win[vert0][2]);
  186.       z1 = FloatToFixed(VB->Win[vert1][2]);
  187. #  else
  188.       z0 = (int) VB->Win[vert0][2];
  189.       z1 = (int) VB->Win[vert1][2];
  190. #  endif
  191. #endif
  192. #ifdef PIXEL_ADDRESS
  193.    pixelPtr = (PIXEL_TYPE *) PIXEL_ADDRESS(x0,y0);
  194. #endif
  195.  
  196.    if (dx<0) {
  197.       dx = -dx;   /* make positive */
  198. #if INTERP_XY
  199.       xstep = -1;
  200. #endif
  201. #ifdef INTERP_Z
  202.       zPtrXstep = -sizeof(GLdepth);
  203. #endif
  204. #ifdef PIXEL_ADDRESS
  205.       pixelXstep = -sizeof(PIXEL_TYPE);
  206. #endif
  207.    }
  208.    else {
  209. #if INTERP_XY
  210.       xstep = 1;
  211. #endif
  212. #if INTERP_Z
  213.       zPtrXstep = sizeof(GLdepth);
  214. #endif
  215. #ifdef PIXEL_ADDRESS
  216.       pixelXstep = sizeof(PIXEL_TYPE);
  217. #endif
  218.    }
  219.  
  220.    if (dy<0) {
  221.       dy = -dy;   /* make positive */
  222. #if INTERP_XY
  223.       ystep = -1;
  224. #endif
  225. #if INTERP_Z
  226.       zPtrYstep = -ctx->Buffer->Width * sizeof(GLdepth);
  227. #endif
  228. #ifdef PIXEL_ADDRESS
  229.       pixelYstep = BYTES_PER_ROW;
  230. #endif
  231.    }
  232.    else {
  233. #if INTERP_XY
  234.       ystep = 1;
  235. #endif
  236. #if INTERP_Z
  237.       zPtrYstep = ctx->Buffer->Width * sizeof(GLdepth);
  238. #endif
  239. #ifdef PIXEL_ADDRESS
  240.       pixelYstep = -(BYTES_PER_ROW);
  241. #endif
  242.    }
  243.  
  244.    /*
  245.     * Draw
  246.     */
  247.  
  248.    if (dx>dy) {
  249.       /*
  250.        * X-major line
  251.        */
  252.       GLint i;
  253.       GLint errorInc = dy+dy;
  254.       GLint error = errorInc-dx;
  255.       GLint errorDec = error-dx;
  256. #if INTERP_Z
  257.       dz = (z1-z0) / dx;
  258. #endif
  259. #if INTERP_RGB
  260.       dr /= dx;   /* convert from whole line delta to per-pixel delta */
  261.       dg /= dx;
  262.       db /= dx;
  263. #endif
  264. #if INTERP_ALPHA
  265.       da /= dx;
  266. #endif
  267. #if INTERP_INDEX
  268.       di /= dx;
  269. #endif
  270. #if INTERP_ST
  271.       ds /= dx;
  272.       dt /= dx;
  273. #endif
  274. #if INTERP_STW
  275.       {
  276.          GLfloat fdxinv = 1.0F / (GLfloat) dx;
  277.          ds *= fdxinv;
  278.          dt *= fdxinv;
  279.          dw *= fdxinv;
  280. #if INTERP_UV
  281.          du *= fdxinv;
  282.          dv *= fdxinv;
  283. #endif
  284.       }
  285. #endif
  286.       for (i=0;i<dx;i++) {
  287. #if STIPPLE
  288.          GLushort m;
  289.          m = 1 << ((ctx->StippleCounter/ctx->Line.StippleFactor) & 0xf);
  290.          if (ctx->Line.StipplePattern & m) {
  291. #endif
  292. #if INTERP_Z
  293. #  if DEPTH_BITS==16
  294.             GLdepth Z = FixedToInt(z0);
  295. #  else
  296.             GLdepth Z = z0;
  297. #  endif
  298. #endif
  299. #if INTERP_INDEX
  300.             GLint I = i0 >> 8;
  301. #endif
  302. #if WIDE
  303.             GLint yy;
  304.             GLint ymin = y0 + min;
  305.             GLint ymax = y0 + max;
  306.             for (yy=ymin;yy<=ymax;yy++) {
  307.                PLOT( x0, yy );
  308.             }
  309. #else
  310. #  ifdef XMAJOR_PLOT
  311.             XMAJOR_PLOT( x0, y0 );
  312. #  else
  313.             PLOT( x0, y0 );
  314. #  endif
  315. #endif /*WIDE*/
  316. #if STIPPLE
  317.         }
  318.     ctx->StippleCounter++;
  319. #endif
  320. #if INTERP_XY
  321.          x0 += xstep;
  322. #endif
  323. #if INTERP_Z
  324.          zPtr = (GLdepth *) ((GLubyte*) zPtr + zPtrXstep);
  325.          z0 += dz;
  326. #endif
  327. #if INTERP_RGB
  328.          r0 += dr;
  329.          g0 += dg;
  330.          b0 += db;
  331. #endif
  332. #if INTERP_ALPHA
  333.          a0 += da;
  334. #endif
  335. #if INTERP_INDEX
  336.          i0 += di;
  337. #endif
  338. #if INTERP_ST
  339.          s0 += ds;
  340.          t0 += dt;
  341. #endif
  342. #if INTERP_STW
  343.          s0 += ds;
  344.          t0 += dt;
  345.          w0 += dw;
  346. #endif
  347. #if INTERP_UV
  348.          u0 += du;
  349.          v0 += dv;
  350. #endif
  351. #ifdef PIXEL_ADDRESS
  352.          pixelPtr = (PIXEL_TYPE*) ((GLubyte*) pixelPtr + pixelXstep);
  353. #endif
  354.          if (error<0) {
  355.             error += errorInc;
  356.          }
  357.          else {
  358.             error += errorDec;
  359. #if INTERP_XY
  360.             y0 += ystep;
  361. #endif
  362. #if INTERP_Z
  363.             zPtr = (GLdepth *) ((GLubyte*) zPtr + zPtrYstep);
  364. #endif
  365. #ifdef PIXEL_ADDRESS
  366.             pixelPtr = (PIXEL_TYPE*) ((GLubyte*) pixelPtr + pixelYstep);
  367. #endif
  368.          }
  369.       }
  370.    }
  371.    else {
  372.       /*
  373.        * Y-major line
  374.        */
  375.       GLint i;
  376.       GLint errorInc = dx+dx;
  377.       GLint error = errorInc-dy;
  378.       GLint errorDec = error-dy;
  379. #if INTERP_Z
  380.       dz = (z1-z0) / dy;
  381. #endif
  382. #if INTERP_RGB
  383.       dr /= dy;   /* convert from whole line delta to per-pixel delta */
  384.       dg /= dy;
  385.       db /= dy;
  386. #endif
  387. #if INTERP_ALPHA
  388.       da /= dy;
  389. #endif
  390. #if INTERP_INDEX
  391.       di /= dy;
  392. #endif
  393. #if INTERP_ST
  394.       ds /= dy;
  395.       dt /= dy;
  396. #endif
  397. #if INTERP_STW
  398.       {
  399.          GLfloat fdyinv = 1.0F / (GLfloat) dy;
  400.          ds *= fdyinv;
  401.          dt *= fdyinv;
  402.          dw *= fdyinv;
  403. #if INTERP_UV
  404.          du *= fdyinv;
  405.          dv *= fdyinv;
  406. #endif
  407.       }
  408. #endif
  409.       for (i=0;i<dy;i++) {
  410. #if STIPPLE
  411.          GLushort m;
  412.          m = 1 << ((ctx->StippleCounter/ctx->Line.StippleFactor) & 0xf);
  413.          if (ctx->Line.StipplePattern & m) {
  414. #endif
  415. #if INTERP_Z
  416. #  if DEPTH_BITS==16
  417.             GLdepth Z = FixedToInt(z0);
  418. #  else
  419.             GLdepth Z = z0;
  420. #  endif
  421. #endif
  422. #if INTERP_INDEX
  423.             GLint I = i0 >> 8;
  424. #endif
  425. #if WIDE
  426.             GLint xx;
  427.             GLint xmin = x0 + min;
  428.             GLint xmax = x0 + max;
  429.             for (xx=xmin;xx<=xmax;xx++) {
  430.                PLOT( xx, y0 );
  431.             }
  432. #else
  433. #  ifdef YMAJOR_PLOT
  434.             YMAJOR_PLOT( x0, y0 );
  435. #  else
  436.             PLOT( x0, y0 );
  437. #  endif
  438. #endif /*WIDE*/
  439. #if STIPPLE
  440.         }
  441.     ctx->StippleCounter++;
  442. #endif
  443. #if INTERP_XY
  444.          y0 += ystep;
  445. #endif
  446. #if INTERP_Z
  447.          zPtr = (GLdepth *) ((GLubyte*) zPtr + zPtrYstep);
  448.          z0 += dz;
  449. #endif
  450. #if INTERP_RGB
  451.          r0 += dr;
  452.          g0 += dg;
  453.          b0 += db;
  454. #endif
  455. #if INTERP_ALPHA
  456.          a0 += da;
  457. #endif
  458. #if INTERP_INDEX
  459.          i0 += di;
  460. #endif
  461. #if INTERP_ST
  462.          s0 += ds;
  463.          t0 += dt;
  464. #endif
  465. #if INTERP_STW
  466.          s0 += ds;
  467.          t0 += dt;
  468.          w0 += dw;
  469. #endif
  470. #if INTERP_UV
  471.          u0 += du;
  472.          v0 += dv;
  473. #endif
  474. #ifdef PIXEL_ADDRESS
  475.          pixelPtr = (PIXEL_TYPE*) ((GLubyte*) pixelPtr + pixelYstep);
  476. #endif
  477.          if (error<0) {
  478.             error += errorInc;
  479.          }
  480.          else {
  481.             error += errorDec;
  482. #if INTERP_XY
  483.             x0 += xstep;
  484. #endif
  485. #if INTERP_Z
  486.             zPtr = (GLdepth *) ((GLubyte*) zPtr + zPtrXstep);
  487. #endif
  488. #ifdef PIXEL_ADDRESS
  489.             pixelPtr = (PIXEL_TYPE*) ((GLubyte*) pixelPtr + pixelXstep);
  490. #endif
  491.          }
  492.       }
  493.    }
  494.  
  495. }
  496.  
  497.  
  498. #undef INTERP_XY
  499. #undef INTERP_Z
  500. #undef INTERP_RGB
  501. #undef INTERP_ALPHA
  502. #undef INTERP_INDEX
  503. #undef PIXEL_ADDRESS
  504. #undef PIXEL_TYPE
  505. #undef BYTES_PER_ROW
  506. #undef SETUP_CODE
  507. #undef PLOT
  508. #undef XMAJOR_PLOT
  509. #undef YMAJOR_PLOT
  510. #undef CLIP_HACK
  511. #undef STIPPLE
  512. #undef WIDE
  513.