home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mesa5.zip / mesa5src.zip / swrast / s_linetemp.h < prev    next >
Text File  |  2002-11-15  |  14KB  |  448 lines

  1. /* $Id: s_linetemp.h,v 1.16 2002/11/15 15:05:04 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  5.1
  6.  *
  7.  * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
  8.  *
  9.  * Permission is hereby granted, free of charge, to any person obtaining a
  10.  * copy of this software and associated documentation files (the "Software"),
  11.  * to deal in the Software without restriction, including without limitation
  12.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  13.  * and/or sell copies of the Software, and to permit persons to whom the
  14.  * Software is furnished to do so, subject to the following conditions:
  15.  *
  16.  * The above copyright notice and this permission notice shall be included
  17.  * in all copies or substantial portions of the Software.
  18.  *
  19.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  20.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  22.  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  23.  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  24.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  */
  26.  
  27.  
  28. /*
  29.  * Line Rasterizer Template
  30.  *
  31.  * This file is #include'd to generate custom line rasterizers.
  32.  *
  33.  * The following macros may be defined to indicate what auxillary information
  34.  * must be interplated along the line:
  35.  *    INTERP_Z        - if defined, interpolate Z values
  36.  *    INTERP_FOG      - if defined, interpolate FOG values
  37.  *    INTERP_RGBA     - if defined, interpolate RGBA values
  38.  *    INTERP_SPEC     - if defined, interpolate specular RGB values
  39.  *    INTERP_INDEX    - if defined, interpolate color index values
  40.  *    INTERP_TEX      - if defined, interpolate unit 0 texcoords
  41.  *    INTERP_MULTITEX - if defined, interpolate multi-texcoords
  42.  *
  43.  * When one can directly address pixels in the color buffer the following
  44.  * macros can be defined and used to directly compute pixel addresses during
  45.  * rasterization (see pixelPtr):
  46.  *    PIXEL_TYPE          - the datatype of a pixel (GLubyte, GLushort, GLuint)
  47.  *    BYTES_PER_ROW       - number of bytes per row in the color buffer
  48.  *    PIXEL_ADDRESS(X,Y)  - returns the address of pixel at (X,Y) where
  49.  *                          Y==0 at bottom of screen and increases upward.
  50.  *
  51.  * Similarly, for direct depth buffer access, this type is used for depth
  52.  * buffer addressing:
  53.  *    DEPTH_TYPE          - either GLushort or GLuint
  54.  *
  55.  * Optionally, one may provide one-time setup code
  56.  *    SETUP_CODE    - code which is to be executed once per line
  57.  *
  58.  * To actually "plot" each pixel the PLOT macro must be defined...
  59.  *    PLOT(X,Y) - code to plot a pixel.  Example:
  60.  *                if (Z < *zPtr) {
  61.  *                   *zPtr = Z;
  62.  *                   color = pack_rgb( FixedToInt(r0), FixedToInt(g0),
  63.  *                                     FixedToInt(b0) );
  64.  *                   put_pixel( X, Y, color );
  65.  *                }
  66.  *
  67.  * This code was designed for the origin to be in the lower-left corner.
  68.  *
  69.  */
  70.  
  71.  
  72. static void
  73. NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 )
  74. {
  75.    struct sw_span span;
  76.    GLuint interpFlags = 0;
  77.    GLint x0 = (GLint) vert0->win[0];
  78.    GLint x1 = (GLint) vert1->win[0];
  79.    GLint y0 = (GLint) vert0->win[1];
  80.    GLint y1 = (GLint) vert1->win[1];
  81.    GLint dx, dy;
  82.    GLint numPixels;
  83.    GLint xstep, ystep;
  84. #if defined(DEPTH_TYPE)
  85.    const GLint depthBits = ctx->Visual.depthBits;
  86.    const GLint fixedToDepthShift = depthBits <= 16 ? FIXED_SHIFT : 0;
  87. #define FixedToDepth(F)  ((F) >> fixedToDepthShift)
  88.    GLint zPtrXstep, zPtrYstep;
  89.    DEPTH_TYPE *zPtr;
  90. #elif defined(INTERP_Z)
  91.    const GLint depthBits = ctx->Visual.depthBits;
  92. #endif
  93. #ifdef PIXEL_ADDRESS
  94.    PIXEL_TYPE *pixelPtr;
  95.    GLint pixelXstep, pixelYstep;
  96. #endif
  97.  
  98. #ifdef SETUP_CODE
  99.    SETUP_CODE
  100. #endif
  101.  
  102.    /* Cull primitives with malformed coordinates.
  103.     */
  104.    {
  105.       GLfloat tmp = vert0->win[0] + vert0->win[1]
  106.                   + vert1->win[0] + vert1->win[1];
  107.       if (IS_INF_OR_NAN(tmp))
  108.      return;
  109.    }
  110.  
  111.    /*
  112.    printf("%s():\n", __FUNCTION__);
  113.    printf(" (%f, %f, %f) -> (%f, %f, %f)\n",
  114.           vert0->win[0], vert0->win[1], vert0->win[2],
  115.           vert1->win[0], vert1->win[1], vert1->win[2]);
  116.    printf(" (%d, %d, %d) -> (%d, %d, %d)\n",
  117.           vert0->color[0], vert0->color[1], vert0->color[2], 
  118.           vert1->color[0], vert1->color[1], vert1->color[2]);
  119.    printf(" (%d, %d, %d) -> (%d, %d, %d)\n",
  120.           vert0->specular[0], vert0->specular[1], vert0->specular[2], 
  121.           vert1->specular[0], vert1->specular[1], vert1->specular[2]);
  122.    */
  123.  
  124. /*
  125.  * Despite being clipped to the view volume, the line's window coordinates
  126.  * may just lie outside the window bounds.  That is, if the legal window
  127.  * coordinates are [0,W-1][0,H-1], it's possible for x==W and/or y==H.
  128.  * This quick and dirty code nudges the endpoints inside the window if
  129.  * necessary.
  130.  */
  131. #ifdef CLIP_HACK
  132.    {
  133.       GLint w = ctx->DrawBuffer->Width;
  134.       GLint h = ctx->DrawBuffer->Height;
  135.       if ((x0==w) | (x1==w)) {
  136.          if ((x0==w) & (x1==w))
  137.            return;
  138.          x0 -= x0==w;
  139.          x1 -= x1==w;
  140.       }
  141.       if ((y0==h) | (y1==h)) {
  142.          if ((y0==h) & (y1==h))
  143.            return;
  144.          y0 -= y0==h;
  145.          y1 -= y1==h;
  146.       }
  147.    }
  148. #endif
  149.  
  150.    dx = x1 - x0;
  151.    dy = y1 - y0;
  152.    if (dx == 0 && dy == 0)
  153.       return;
  154.  
  155. #ifdef DEPTH_TYPE
  156.    zPtr = (DEPTH_TYPE *) _mesa_zbuffer_address(ctx, x0, y0);
  157. #endif
  158. #ifdef PIXEL_ADDRESS
  159.    pixelPtr = (PIXEL_TYPE *) PIXEL_ADDRESS(x0,y0);
  160. #endif
  161.  
  162.    if (dx<0) {
  163.       dx = -dx;   /* make positive */
  164.       xstep = -1;
  165. #ifdef DEPTH_TYPE
  166.       zPtrXstep = -((GLint)sizeof(DEPTH_TYPE));
  167. #endif
  168. #ifdef PIXEL_ADDRESS
  169.       pixelXstep = -((GLint)sizeof(PIXEL_TYPE));
  170. #endif
  171.    }
  172.    else {
  173.       xstep = 1;
  174. #ifdef DEPTH_TYPE
  175.       zPtrXstep = ((GLint)sizeof(DEPTH_TYPE));
  176. #endif
  177. #ifdef PIXEL_ADDRESS
  178.       pixelXstep = ((GLint)sizeof(PIXEL_TYPE));
  179. #endif
  180.    }
  181.  
  182.    if (dy<0) {
  183.       dy = -dy;   /* make positive */
  184.       ystep = -1;
  185. #ifdef DEPTH_TYPE
  186.       zPtrYstep = -((GLint) (ctx->DrawBuffer->Width * sizeof(DEPTH_TYPE)));
  187. #endif
  188. #ifdef PIXEL_ADDRESS
  189.       pixelYstep = BYTES_PER_ROW;
  190. #endif
  191.    }
  192.    else {
  193.       ystep = 1;
  194. #ifdef DEPTH_TYPE
  195.       zPtrYstep = (GLint) (ctx->DrawBuffer->Width * sizeof(DEPTH_TYPE));
  196. #endif
  197. #ifdef PIXEL_ADDRESS
  198.       pixelYstep = -(BYTES_PER_ROW);
  199. #endif
  200.    }
  201.  
  202.    ASSERT(dx >= 0);
  203.    ASSERT(dy >= 0);
  204.  
  205.    numPixels = MAX2(dx, dy);
  206.  
  207.    /*
  208.     * Span setup: compute start and step values for all interpolated values.
  209.     */
  210. #ifdef INTERP_RGBA
  211.    interpFlags |= SPAN_RGBA;
  212.    if (ctx->Light.ShadeModel == GL_SMOOTH) {
  213.       span.red   = ChanToFixed(vert0->color[0]);
  214.       span.green = ChanToFixed(vert0->color[1]);
  215.       span.blue  = ChanToFixed(vert0->color[2]);
  216.       span.alpha = ChanToFixed(vert0->color[3]);
  217.       span.redStep   = (ChanToFixed(vert1->color[0]) - span.red  ) / numPixels;
  218.       span.greenStep = (ChanToFixed(vert1->color[1]) - span.green) / numPixels;
  219.       span.blueStep  = (ChanToFixed(vert1->color[2]) - span.blue ) / numPixels;
  220.       span.alphaStep = (ChanToFixed(vert1->color[3]) - span.alpha) / numPixels;
  221.    }
  222.    else {
  223.       span.red   = ChanToFixed(vert1->color[0]);
  224.       span.green = ChanToFixed(vert1->color[1]);
  225.       span.blue  = ChanToFixed(vert1->color[2]);
  226.       span.alpha = ChanToFixed(vert1->color[3]);
  227.       span.redStep   = 0;
  228.       span.greenStep = 0;
  229.       span.blueStep  = 0;
  230.       span.alphaStep = 0;
  231.    }
  232. #endif
  233. #ifdef INTERP_SPEC
  234.    interpFlags |= SPAN_SPEC;
  235.    if (ctx->Light.ShadeModel == GL_SMOOTH) {
  236.       span.specRed       = ChanToFixed(vert0->specular[0]);
  237.       span.specGreen     = ChanToFixed(vert0->specular[1]);
  238.       span.specBlue      = ChanToFixed(vert0->specular[2]);
  239.       span.specRedStep   = (ChanToFixed(vert1->specular[0]) - span.specRed) / numPixels;
  240.       span.specGreenStep = (ChanToFixed(vert1->specular[1]) - span.specBlue) / numPixels;
  241.       span.specBlueStep  = (ChanToFixed(vert1->specular[2]) - span.specGreen) / numPixels;
  242.    }
  243.    else {
  244.       span.specRed       = ChanToFixed(vert1->specular[0]);
  245.       span.specGreen     = ChanToFixed(vert1->specular[1]);
  246.       span.specBlue      = ChanToFixed(vert1->specular[2]);
  247.       span.specRedStep   = 0;
  248.       span.specGreenStep = 0;
  249.       span.specBlueStep  = 0;
  250.    }
  251. #endif
  252. #ifdef INTERP_INDEX
  253.    interpFlags |= SPAN_INDEX;
  254.    if (ctx->Light.ShadeModel == GL_SMOOTH) {
  255.       span.index = IntToFixed(vert0->index);
  256.       span.indexStep = IntToFixed(vert1->index - vert0->index) / numPixels;
  257.    }
  258.    else {
  259.       span.index = IntToFixed(vert1->index);
  260.       span.indexStep = 0;
  261.    }
  262. #endif
  263. #if defined(INTERP_Z) || defined(DEPTH_TYPE)
  264.    interpFlags |= SPAN_Z;
  265.    {
  266.       if (depthBits <= 16) {
  267.          span.z = FloatToFixed(vert0->win[2]) + FIXED_HALF;
  268.          span.zStep = FloatToFixed(vert1->win[2] - vert0->win[2]) / numPixels;
  269.       }
  270.       else {
  271.          span.z = vert0->win[2];
  272.          span.zStep = (vert1->win[2] - vert0->win[2]) / numPixels;
  273.       }
  274.    }
  275. #endif
  276. #ifdef INTERP_FOG
  277.    interpFlags |= SPAN_FOG;
  278.    span.fog = vert0->fog;
  279.    span.fogStep = (vert1->fog - vert0->fog) / numPixels;
  280. #endif
  281. #ifdef INTERP_TEX
  282.    interpFlags |= SPAN_TEXTURE;
  283.    {
  284.       const GLfloat invw0 = vert0->win[3];
  285.       const GLfloat invw1 = vert1->win[3];
  286.       const GLfloat invLen = 1.0F / numPixels;
  287.       GLfloat ds, dt, dr, dq;
  288.       span.tex[0][0] = invw0 * vert0->texcoord[0][0];
  289.       span.tex[0][1] = invw0 * vert0->texcoord[0][1];
  290.       span.tex[0][2] = invw0 * vert0->texcoord[0][2];
  291.       span.tex[0][3] = invw0 * vert0->texcoord[0][3];
  292.       ds = (invw1 * vert1->texcoord[0][0]) - span.tex[0][0];
  293.       dt = (invw1 * vert1->texcoord[0][1]) - span.tex[0][1];
  294.       dr = (invw1 * vert1->texcoord[0][2]) - span.tex[0][2];
  295.       dq = (invw1 * vert1->texcoord[0][3]) - span.tex[0][3];
  296.       span.texStepX[0][0] = ds * invLen;
  297.       span.texStepX[0][1] = dt * invLen;
  298.       span.texStepX[0][2] = dr * invLen;
  299.       span.texStepX[0][3] = dq * invLen;
  300.       span.texStepY[0][0] = 0.0F;
  301.       span.texStepY[0][1] = 0.0F;
  302.       span.texStepY[0][2] = 0.0F;
  303.       span.texStepY[0][3] = 0.0F;
  304.    }
  305. #endif
  306. #ifdef INTERP_MULTITEX
  307.    interpFlags |= SPAN_TEXTURE;
  308.    {
  309.       const GLfloat invLen = 1.0F / numPixels;
  310.       GLuint u;
  311.       for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
  312.          if (ctx->Texture.Unit[u]._ReallyEnabled) {
  313.             const GLfloat invw0 = vert0->win[3];
  314.             const GLfloat invw1 = vert1->win[3];
  315.             GLfloat ds, dt, dr, dq;
  316.             span.tex[u][0] = invw0 * vert0->texcoord[u][0];
  317.             span.tex[u][1] = invw0 * vert0->texcoord[u][1];
  318.             span.tex[u][2] = invw0 * vert0->texcoord[u][2];
  319.             span.tex[u][3] = invw0 * vert0->texcoord[u][3];
  320.             ds = (invw1 * vert1->texcoord[u][0]) - span.tex[u][0];
  321.             dt = (invw1 * vert1->texcoord[u][1]) - span.tex[u][1];
  322.             dr = (invw1 * vert1->texcoord[u][2]) - span.tex[u][2];
  323.             dq = (invw1 * vert1->texcoord[u][3]) - span.tex[u][3];
  324.             span.texStepX[u][0] = ds * invLen;
  325.             span.texStepX[u][1] = dt * invLen;
  326.             span.texStepX[u][2] = dr * invLen;
  327.             span.texStepX[u][3] = dq * invLen;
  328.             span.texStepY[u][0] = 0.0F;
  329.             span.texStepY[u][1] = 0.0F;
  330.             span.texStepY[u][2] = 0.0F;
  331.             span.texStepY[u][3] = 0.0F;
  332.      }
  333.       }
  334.    }
  335. #endif
  336.  
  337.    INIT_SPAN(span, GL_LINE, numPixels, interpFlags, SPAN_XY);
  338.  
  339.    /*
  340.     * Draw
  341.     */
  342.  
  343.    if (dx > dy) {
  344.       /*** X-major line ***/
  345.       GLint i;
  346.       GLint errorInc = dy+dy;
  347.       GLint error = errorInc-dx;
  348.       GLint errorDec = error-dx;
  349.  
  350.       for (i = 0; i < dx; i++) {
  351. #ifdef DEPTH_TYPE
  352.          GLdepth Z = FixedToDepth(span.z);
  353. #endif
  354. #ifdef PLOT
  355.          PLOT( x0, y0 );
  356. #else
  357.          span.array->x[i] = x0;
  358.          span.array->y[i] = y0;
  359. #endif
  360.          x0 += xstep;
  361. #ifdef DEPTH_TYPE
  362.          zPtr = (DEPTH_TYPE *) ((GLubyte*) zPtr + zPtrXstep);
  363.          span.z += span.zStep;
  364. #endif
  365. #ifdef PIXEL_ADDRESS
  366.          pixelPtr = (PIXEL_TYPE*) ((GLubyte*) pixelPtr + pixelXstep);
  367. #endif
  368.          if (error<0) {
  369.             error += errorInc;
  370.          }
  371.          else {
  372.             error += errorDec;
  373.             y0 += ystep;
  374. #ifdef DEPTH_TYPE
  375.             zPtr = (DEPTH_TYPE *) ((GLubyte*) zPtr + zPtrYstep);
  376. #endif
  377. #ifdef PIXEL_ADDRESS
  378.             pixelPtr = (PIXEL_TYPE*) ((GLubyte*) pixelPtr + pixelYstep);
  379. #endif
  380.          }
  381.       }
  382.    }
  383.    else {
  384.       /*** Y-major line ***/
  385.       GLint i;
  386.       GLint errorInc = dx+dx;
  387.       GLint error = errorInc-dy;
  388.       GLint errorDec = error-dy;
  389.  
  390.       for (i=0;i<dy;i++) {
  391. #ifdef DEPTH_TYPE
  392.          GLdepth Z = FixedToDepth(span.z);
  393. #endif
  394. #ifdef PLOT
  395.          PLOT( x0, y0 );
  396. #else
  397.          span.array->x[i] = x0;
  398.          span.array->y[i] = y0;
  399. #endif
  400.          y0 += ystep;
  401. #ifdef DEPTH_TYPE
  402.          zPtr = (DEPTH_TYPE *) ((GLubyte*) zPtr + zPtrYstep);
  403.          span.z += span.zStep;
  404. #endif
  405. #ifdef PIXEL_ADDRESS
  406.          pixelPtr = (PIXEL_TYPE*) ((GLubyte*) pixelPtr + pixelYstep);
  407. #endif
  408.          if (error<0) {
  409.             error += errorInc;
  410.          }
  411.          else {
  412.             error += errorDec;
  413.             x0 += xstep;
  414. #ifdef DEPTH_TYPE
  415.             zPtr = (DEPTH_TYPE *) ((GLubyte*) zPtr + zPtrXstep);
  416. #endif
  417. #ifdef PIXEL_ADDRESS
  418.             pixelPtr = (PIXEL_TYPE*) ((GLubyte*) pixelPtr + pixelXstep);
  419. #endif
  420.          }
  421.       }
  422.    }
  423.  
  424. #ifdef RENDER_SPAN
  425.    RENDER_SPAN( span );
  426. #endif
  427.  
  428. }
  429.  
  430.  
  431. #undef NAME
  432. #undef INTERP_Z
  433. #undef INTERP_FOG
  434. #undef INTERP_RGBA
  435. #undef INTERP_SPEC
  436. #undef INTERP_TEX
  437. #undef INTERP_MULTITEX
  438. #undef INTERP_INDEX
  439. #undef PIXEL_ADDRESS
  440. #undef PIXEL_TYPE
  441. #undef DEPTH_TYPE
  442. #undef BYTES_PER_ROW
  443. #undef SETUP_CODE
  444. #undef PLOT
  445. #undef CLIP_HACK
  446. #undef FixedToDepth
  447. #undef RENDER_SPAN
  448.