home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mesa5.zip / mesa5src.zip / swrast / s_pointtemp.h < prev    next >
Text File  |  2002-12-08  |  12KB  |  374 lines

  1. /* $Id: s_pointtemp.h,v 1.21 2002/11/09 21:26:41 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  5.0
  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.  * Point rendering template code.
  30.  *
  31.  * Set FLAGS = bitwise-OR of the following tokens:
  32.  *
  33.  *   RGBA = do rgba instead of color index
  34.  *   SMOOTH = do antialiasing
  35.  *   TEXTURE = do texture coords
  36.  *   SPECULAR = do separate specular color
  37.  *   LARGE = do points with diameter > 1 pixel
  38.  *   ATTENUATE = compute point size attenuation
  39.  *   SPRITE = GL_NV_point_sprite
  40.  *
  41.  * Notes: LARGE and ATTENUATE are exclusive of each other.
  42.  *        TEXTURE requires RGBA
  43.  *        SPECULAR requires TEXTURE
  44.  */
  45.  
  46.  
  47. /*
  48.  * NOTES on antialiased point rasterization:
  49.  *
  50.  * Let d = distance of fragment center from vertex.
  51.  * if d < rmin2 then
  52.  *    fragment has 100% coverage
  53.  * else if d > rmax2 then
  54.  *    fragment has 0% coverage
  55.  * else
  56.  *    fragment has % coverage = (d - rmin2) / (rmax2 - rmin2)
  57.  */
  58.  
  59.  
  60.  
  61. static void
  62. NAME ( GLcontext *ctx, const SWvertex *vert )
  63. {
  64. #if FLAGS & (ATTENUATE | LARGE | SMOOTH | SPRITE)
  65.    GLfloat size;
  66. #endif
  67. #if FLAGS & ATTENUATE
  68.    GLfloat alphaAtten;
  69. #endif
  70. #if FLAGS & RGBA
  71.    const GLchan red   = vert->color[0];
  72.    const GLchan green = vert->color[1];
  73.    const GLchan blue  = vert->color[2];
  74.    const GLchan alpha = vert->color[3];
  75. #endif
  76. #if FLAGS & SPECULAR
  77.    const GLchan specRed   = vert->specular[0];
  78.    const GLchan specGreen = vert->specular[1];
  79.    const GLchan specBlue  = vert->specular[2];
  80. #endif
  81. #if FLAGS & INDEX
  82.    const GLuint colorIndex = vert->index;
  83. #endif
  84. #if FLAGS & TEXTURE
  85.    GLfloat texcoord[MAX_TEXTURE_UNITS][4];
  86.    GLuint u;
  87. #endif
  88.    SWcontext *swrast = SWRAST_CONTEXT(ctx);
  89.    struct sw_span *span = &(swrast->PointSpan);
  90.  
  91.    /* Cull primitives with malformed coordinates.
  92.     */
  93.    {
  94.       float tmp = vert->win[0] + vert->win[1];
  95.       if (IS_INF_OR_NAN(tmp))
  96.         return;
  97.    }
  98.  
  99.    /*
  100.     * Span init
  101.     */
  102.    span->interpMask = SPAN_FOG;
  103.    span->arrayMask = SPAN_XY | SPAN_Z;
  104.    span->fog = vert->fog;
  105.    span->fogStep = 0.0;
  106. #if FLAGS & RGBA
  107.    span->arrayMask |= SPAN_RGBA;
  108. #endif
  109. #if FLAGS & SPECULAR
  110.    span->arrayMask |= SPAN_SPEC;
  111. #endif
  112. #if FLAGS & INDEX
  113.    span->arrayMask |= SPAN_INDEX;
  114. #endif
  115. #if FLAGS & TEXTURE
  116.    span->arrayMask |= SPAN_TEXTURE;
  117.    for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
  118.       if (ctx->Texture.Unit[u]._ReallyEnabled) {
  119.          const GLfloat q = vert->texcoord[u][3];
  120.          const GLfloat invQ = (q == 0.0F || q == 1.0F) ? 1.0F : (1.0F / q);
  121.          texcoord[u][0] = vert->texcoord[u][0] * invQ;
  122.          texcoord[u][1] = vert->texcoord[u][1] * invQ;
  123.          texcoord[u][2] = vert->texcoord[u][2] * invQ;
  124.          texcoord[u][3] = q;
  125.       }
  126.    }
  127. #endif
  128. #if FLAGS & SMOOTH
  129.    span->arrayMask |= SPAN_COVERAGE;
  130. #endif
  131. #if FLAGS & SPRITE
  132.    span->arrayMask |= SPAN_TEXTURE;
  133. #endif
  134.  
  135. #if FLAGS & ATTENUATE
  136.    if (vert->pointSize >= ctx->Point.Threshold) {
  137.       size = MIN2(vert->pointSize, ctx->Point.MaxSize);
  138.       alphaAtten = 1.0F;
  139.    }
  140.    else {
  141.       GLfloat dsize = vert->pointSize / ctx->Point.Threshold;
  142.       size = MAX2(ctx->Point.Threshold, ctx->Point.MinSize);
  143.       alphaAtten = dsize * dsize;
  144.    }
  145. #elif FLAGS & (LARGE | SMOOTH | SPRITE)
  146.    size = ctx->Point._Size;
  147. #endif
  148.  
  149. #if FLAGS & (ATTENUATE | LARGE | SMOOTH | SPRITE)
  150.    /*
  151.     * Multi-pixel points
  152.     */
  153.    {{
  154.       GLint x, y;
  155.       const GLfloat radius = 0.5F * size;
  156.       const GLint z = (GLint) (vert->win[2] + 0.5F);
  157.       GLuint count;
  158. #if FLAGS & SMOOTH
  159.       const GLfloat rmin = radius - 0.7071F;  /* 0.7071 = sqrt(2)/2 */
  160.       const GLfloat rmax = radius + 0.7071F;
  161.       const GLfloat rmin2 = MAX2(0.0F, rmin * rmin);
  162.       const GLfloat rmax2 = rmax * rmax;
  163.       const GLfloat cscale = 1.0F / (rmax2 - rmin2);
  164.       const GLint xmin = (GLint) (vert->win[0] - radius);
  165.       const GLint xmax = (GLint) (vert->win[0] + radius);
  166.       const GLint ymin = (GLint) (vert->win[1] - radius);
  167.       const GLint ymax = (GLint) (vert->win[1] + radius);
  168. #else
  169.       /* non-smooth */
  170.       GLint xmin, xmax, ymin, ymax;
  171.       GLint iSize = (GLint) (size + 0.5F);
  172.       GLint iRadius;
  173.       iSize = MAX2(1, iSize);
  174.       iRadius = iSize / 2;
  175.       if (iSize & 1) {
  176.          /* odd size */
  177.          xmin = (GLint) (vert->win[0] - iRadius);
  178.          xmax = (GLint) (vert->win[0] + iRadius);
  179.          ymin = (GLint) (vert->win[1] - iRadius);
  180.          ymax = (GLint) (vert->win[1] + iRadius);
  181.       }
  182.       else {
  183.          /* even size */
  184.          xmin = (GLint) vert->win[0] - iRadius + 1;
  185.          xmax = xmin + iSize - 1;
  186.          ymin = (GLint) vert->win[1] - iRadius + 1;
  187.          ymax = ymin + iSize - 1;
  188.       }
  189. #endif /*SMOOTH*/
  190.  
  191.       /* check if we need to flush */
  192.       if (span->end + (xmax-xmin+1) * (ymax-ymin+1) >= MAX_WIDTH ||
  193.           (swrast->_RasterMask & (BLEND_BIT | LOGIC_OP_BIT | MASKING_BIT))) {
  194. #if FLAGS & (TEXTURE | SPRITE)
  195.          if (ctx->Texture._EnabledUnits)
  196.             _mesa_write_texture_span(ctx, span);
  197.          else
  198.             _mesa_write_rgba_span(ctx, span);
  199. #elif FLAGS & RGBA
  200.          _mesa_write_rgba_span(ctx, span);
  201. #else
  202.          _mesa_write_index_span(ctx, span);
  203. #endif
  204.          span->end = 0;
  205.       }
  206.  
  207.       /*
  208.        * OK, generate fragments
  209.        */
  210.       count = span->end;
  211. //EK      (void) radius;
  212.       for (y = ymin; y <= ymax; y++) {
  213.          for (x = xmin; x <= xmax; x++) {
  214. #if FLAGS & (SPRITE | TEXTURE)
  215.             GLuint u;
  216. #endif
  217.  
  218. #if FLAGS & RGBA
  219.             span->array->rgba[count][RCOMP] = red;
  220.             span->array->rgba[count][GCOMP] = green;
  221.             span->array->rgba[count][BCOMP] = blue;
  222.             span->array->rgba[count][ACOMP] = alpha;
  223. #endif
  224. #if FLAGS & SPECULAR
  225.             span->array->spec[count][RCOMP] = specRed;
  226.             span->array->spec[count][GCOMP] = specGreen;
  227.             span->array->spec[count][BCOMP] = specBlue;
  228. #endif
  229. #if FLAGS & INDEX
  230.             span->array->index[count] = colorIndex;
  231. #endif
  232. #if FLAGS & TEXTURE
  233.             for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
  234.                if (ctx->Texture.Unit[u]._ReallyEnabled) {
  235.                   COPY_4V(span->array->texcoords[u][count], texcoord[u]);
  236.                }
  237.             }
  238. #endif
  239.  
  240. #if FLAGS & SMOOTH
  241.             /* compute coverage */
  242.             {
  243.                const GLfloat dx = x - vert->win[0] + 0.5F;
  244.                const GLfloat dy = y - vert->win[1] + 0.5F;
  245.                const GLfloat dist2 = dx * dx + dy * dy;
  246.                if (dist2 < rmax2) {
  247.                   if (dist2 >= rmin2) {
  248.                      /* compute partial coverage */
  249.                      span->array->coverage[count] = 1.0F - (dist2 - rmin2) * cscale;
  250. #if FLAGS & INDEX
  251.                      /* coverage in [0,15] */
  252.                      span->array->coverage[count] *= 15.0;
  253. #endif
  254.                   }
  255.                   else {
  256.                      /* full coverage */
  257.                      span->array->coverage[count] = 1.0F;
  258.                   }
  259.  
  260.                   span->array->x[count] = x;
  261.                   span->array->y[count] = y;
  262.                   span->array->z[count] = z;
  263.  
  264. #if (FLAGS & ATTENUATE) && (FLAGS & RGBA)
  265.                   span->array->rgba[count][ACOMP] = (GLchan) (alpha * alphaAtten);
  266. #elif FLAGS & RGBA
  267.                   span->array->rgba[count][ACOMP] = alpha;
  268. #endif /*ATTENUATE*/
  269.                   count++;
  270.                } /*if*/
  271.             }
  272.  
  273. #else /*SMOOTH*/
  274.  
  275.             /* not smooth (square points) */
  276.             span->array->x[count] = x;
  277.             span->array->y[count] = y;
  278.             span->array->z[count] = z;
  279.  
  280. #if FLAGS & SPRITE
  281.             for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
  282.                if (ctx->Texture.Unit[u]._ReallyEnabled) {
  283.                   if (ctx->Point.CoordReplace[u]) {
  284.                      GLfloat s = 0.5F + (x + 0.5F - vert->win[0]) / size;
  285.                      GLfloat t = 0.5F - (y + 0.5F - vert->win[1]) / size;
  286.                      span->array->texcoords[u][count][0] = s;
  287.                      span->array->texcoords[u][count][1] = t;
  288.                      span->array->texcoords[u][count][3] = 1.0F;
  289.                      if (ctx->Point.SpriteRMode == GL_ZERO)
  290.                         span->array->texcoords[u][count][2] = 0.0F;
  291.                      else if (ctx->Point.SpriteRMode == GL_S)
  292.                         span->array->texcoords[u][count][2] = vert->texcoord[u][0];
  293.                      else /* GL_R */
  294.                         span->array->texcoords[u][count][2] = vert->texcoord[u][2];
  295.                   }
  296.                   else {
  297.                      COPY_4V(span->array->texcoords[u][count], vert->texcoord[u]);
  298.                   }
  299.                }
  300.             }
  301. #endif /*SPRITE*/
  302.  
  303.             count++;  /* square point */
  304.  
  305. #endif /*SMOOTH*/
  306.  
  307.         } /*for x*/
  308.       } /*for y*/
  309.       span->end = count;
  310.    }}
  311.  
  312. #else /* LARGE | ATTENUATE | SMOOTH | SPRITE */
  313.  
  314.    /*
  315.     * Single-pixel points
  316.     */
  317.    {{
  318.       GLuint count;
  319.  
  320.       /* check if we need to flush */
  321.       if (span->end >= MAX_WIDTH ||
  322.           (swrast->_RasterMask & (BLEND_BIT | LOGIC_OP_BIT | MASKING_BIT))) {
  323. #if FLAGS & (TEXTURE | SPRITE)
  324.          if (ctx->Texture._EnabledUnits)
  325.             _mesa_write_texture_span(ctx, span);
  326.          else
  327.             _mesa_write_rgba_span(ctx, span);
  328. #elif FLAGS & RGBA
  329.          _mesa_write_rgba_span(ctx, span);
  330. #else
  331.          _mesa_write_index_span(ctx, span);
  332. #endif
  333.          span->end = 0;
  334.       }
  335.  
  336.       count = span->end;
  337.  
  338. #if FLAGS & RGBA
  339.       span->array->rgba[count][RCOMP] = red;
  340.       span->array->rgba[count][GCOMP] = green;
  341.       span->array->rgba[count][BCOMP] = blue;
  342.       span->array->rgba[count][ACOMP] = alpha;
  343. #endif
  344. #if FLAGS & SPECULAR
  345.       span->array->spec[count][RCOMP] = specRed;
  346.       span->array->spec[count][GCOMP] = specGreen;
  347.       span->array->spec[count][BCOMP] = specBlue;
  348. #endif
  349. #if FLAGS & INDEX
  350.       span->array->index[count] = colorIndex;
  351. #endif
  352. #if FLAGS & TEXTURE
  353.       for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
  354.          if (ctx->Texture.Unit[u]._ReallyEnabled) {
  355.             COPY_4V(span->array->texcoords[u][count], texcoord[u]);
  356.          }
  357.       }
  358. #endif
  359.  
  360.       span->array->x[count] = (GLint) vert->win[0];
  361.       span->array->y[count] = (GLint) vert->win[1];
  362.       span->array->z[count] = (GLint) (vert->win[2] + 0.5F);
  363.       span->end = count + 1;
  364.    }}
  365.  
  366. #endif /* LARGE || ATTENUATE || SMOOTH */
  367.  
  368.    ASSERT(span->end <= MAX_WIDTH);
  369. }
  370.  
  371.  
  372. #undef FLAGS
  373. #undef NAME
  374.