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

  1. /* $Id: points.c,v 1.14 1997/10/29 01:29:09 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  2.5
  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: points.c,v $
  26.  * Revision 1.14  1997/10/29 01:29:09  brianp
  27.  * added GL_EXT_point_parameters extension from Daniel Barrero
  28.  *
  29.  * Revision 1.13  1997/07/24 01:23:44  brianp
  30.  * changed precompiled header symbol from PCH to PC_HEADER
  31.  *
  32.  * Revision 1.12  1997/06/20 02:50:39  brianp
  33.  * changed color components from GLfixed to GLubyte
  34.  *
  35.  * Revision 1.11  1997/05/28 03:26:02  brianp
  36.  * added precompiled header (PCH) support
  37.  *
  38.  * Revision 1.10  1997/05/03 00:51:02  brianp
  39.  * removed calls to gl_texturing_enabled()
  40.  *
  41.  * Revision 1.9  1997/04/14 02:00:39  brianp
  42.  * #include "texstate.h" instead of "texture.h"
  43.  *
  44.  * Revision 1.8  1997/04/12 12:24:43  brianp
  45.  * replaced ctx->PointsFunc with ctx->Driver.PointsFunc
  46.  *
  47.  * Revision 1.7  1997/04/02 03:11:38  brianp
  48.  * replaced VB->Unclipped with VB->ClipMask
  49.  *
  50.  * Revision 1.6  1997/03/08 02:04:27  brianp
  51.  * better implementation of feedback function
  52.  *
  53.  * Revision 1.5  1997/02/09 18:43:52  brianp
  54.  * added GL_EXT_texture3D support
  55.  *
  56.  * Revision 1.4  1997/01/09 19:48:00  brianp
  57.  * now call gl_texturing_enabled()
  58.  *
  59.  * Revision 1.3  1996/11/08 02:21:21  brianp
  60.  * added null drawing function for GL_NO_RASTER
  61.  *
  62.  * Revision 1.2  1996/09/15 14:18:37  brianp
  63.  * now use GLframebuffer and GLvisual
  64.  *
  65.  * Revision 1.1  1996/09/13 01:38:16  brianp
  66.  * Initial revision
  67.  *
  68.  */
  69.  
  70.  
  71. #ifdef PC_HEADER
  72. #include "all.h"
  73. #else
  74. #include "context.h"
  75. #include "feedback.h"
  76. #include "dlist.h"
  77. #include "macros.h"
  78. #include "pb.h"
  79. #include "span.h"
  80. #include "texstate.h"
  81. #include "types.h"
  82. #include "vb.h"
  83. #include "mmath.h"
  84. #endif
  85.  
  86. #define BOOL_TO_FLOAT(X)        ( (GLfloat)(GLint) (X) )
  87. #define BOOL_TO_DOUBLE(X)        ( (GLdouble)(GLint) (X) )
  88.  
  89.  
  90. void gl_PointSize( GLcontext *ctx, GLfloat size )
  91. {
  92.    if (size<=0.0) {
  93.       gl_error( ctx, GL_INVALID_VALUE, "glPointSize" );
  94.       return;
  95.    }
  96.    if (INSIDE_BEGIN_END(ctx)) {
  97.       gl_error( ctx, GL_INVALID_OPERATION, "glPointSize" );
  98.       return;
  99.    }
  100.    ctx->NewState |= NEW_RASTER_OPS;
  101.    ctx->Point.Size = size;
  102. }
  103.  
  104.  
  105.  
  106. void gl_PointParameterfvEXT( GLcontext *ctx, GLenum pname,
  107.                     const GLfloat *params)
  108. {
  109.    if (INSIDE_BEGIN_END(ctx)) {
  110.       gl_error( ctx, GL_INVALID_OPERATION, "glPointParameterfvEXT" );
  111.       return;
  112.    }
  113.    if(pname==GL_DISTANCE_ATTENUATION_EXT) {
  114.      COPY_3V(ctx->Point.Params,params);
  115.    } else {
  116.     if (*params<0.0 ) {
  117.         gl_error( ctx, GL_INVALID_VALUE, "glPointParameterfvEXT" );
  118.         return;
  119.     }
  120.     switch (pname) {
  121.         case GL_POINT_SIZE_MIN_EXT:
  122.         ctx->Point.MinSize=*params;
  123.         break;
  124.         case GL_POINT_SIZE_MAX_EXT:
  125.         ctx->Point.MaxSize=*params;
  126.         break;
  127.         case GL_POINT_FADE_THRESHOLD_SIZE_EXT:
  128.         ctx->Point.Threshold=*params;
  129.         break;
  130.         default:
  131.         gl_error( ctx, GL_INVALID_ENUM, "glPointParameterfvEXT" );
  132.         return;
  133.     }
  134.    }
  135.    {
  136.     int a = ctx->NewState | NEW_RASTER_OPS;
  137.     ctx->NewState = a;
  138.    }
  139. }
  140.  
  141.  
  142. /**********************************************************************/
  143. /*****                    Rasterization                           *****/
  144. /**********************************************************************/
  145.  
  146.  
  147. /*
  148.  * There are 3 pairs (RGBA, CI) of point rendering functions:
  149.  *   1. simple:  size=1 and no special rasterization functions (fastest)
  150.  *   2. size1:  size=1 and any rasterization functions
  151.  *   3. general:  any size and rasterization functions (slowest)
  152.  *
  153.  * All point rendering functions take the same two arguments: first and
  154.  * last which specify that the points specified by VB[first] through
  155.  * VB[last] are to be rendered.
  156.  */
  157.  
  158.  
  159.  
  160. /*
  161.  * Put points in feedback buffer.
  162.  */
  163. static void feedback_points( GLcontext *ctx, GLuint first, GLuint last )
  164. {
  165.    struct vertex_buffer *VB = ctx->VB;
  166.    GLuint i;
  167.    GLfloat invRedScale   = ctx->Visual->InvRedScale;
  168.    GLfloat invGreenScale = ctx->Visual->InvGreenScale;
  169.    GLfloat invBlueScale  = ctx->Visual->InvBlueScale;
  170.    GLfloat invAlphaScale = ctx->Visual->InvAlphaScale;
  171.  
  172.    for (i=first;i<=last;i++) {
  173.       if (VB->ClipMask[i]==0) {
  174.      GLfloat x, y, z, w, invq;
  175.      GLfloat color[4], texcoord[4];
  176.  
  177.      x = VB->Win[i][0];
  178.      y = VB->Win[i][1];
  179.      z = VB->Win[i][2] / DEPTH_SCALE;
  180.      w = VB->Clip[i][3];
  181.  
  182.      /* convert color from integer back to a float in [0,1] */
  183.      if (ctx->Light.ShadeModel==GL_SMOOTH) {
  184.         /* smooth shading - colors are in fixed point */
  185.         color[0] = FixedToFloat(VB->Color[i][0]) * invRedScale;
  186.         color[1] = FixedToFloat(VB->Color[i][1]) * invGreenScale;
  187.         color[2] = FixedToFloat(VB->Color[i][2]) * invBlueScale;
  188.         color[3] = FixedToFloat(VB->Color[i][3]) * invAlphaScale;
  189.      }
  190.      else {
  191.         /* flat shading - colors are integers */
  192.         color[0] = VB->Color[i][0] * invRedScale;
  193.         color[1] = VB->Color[i][1] * invGreenScale;
  194.         color[2] = VB->Color[i][2] * invBlueScale;
  195.         color[3] = VB->Color[i][3] * invAlphaScale;
  196.      }
  197.      invq = 1.0F / VB->TexCoord[i][3];
  198.      texcoord[0] = VB->TexCoord[i][0] * invq;
  199.      texcoord[1] = VB->TexCoord[i][1] * invq;
  200.      texcoord[2] = VB->TexCoord[i][2] * invq;
  201.      texcoord[3] = VB->TexCoord[i][3];
  202.  
  203.      FEEDBACK_TOKEN( ctx, BOOL_TO_FLOAT(GL_POINT_TOKEN) );
  204.      gl_feedback_vertex( ctx, x, y, z, w, color,
  205.                  (GLfloat) VB->Index[i], texcoord );
  206.       }
  207.    }
  208. }
  209.  
  210.  
  211.  
  212. /*
  213.  * Put points in selection buffer.
  214.  */
  215. static void select_points( GLcontext *ctx, GLuint first, GLuint last )
  216. {
  217.    struct vertex_buffer *VB = ctx->VB;
  218.    GLuint i;
  219.  
  220.    for (i=first;i<=last;i++) {
  221.       if (VB->ClipMask[i]==0) {
  222.      gl_update_hitflag( ctx, VB->Win[i][2] / DEPTH_SCALE );
  223.       }
  224.    }
  225. }
  226.  
  227.  
  228. /*
  229.  * CI points with size == 1.0
  230.  */
  231. void size1_ci_points( GLcontext *ctx, GLuint first, GLuint last )
  232. {
  233.    struct vertex_buffer *VB = ctx->VB;
  234.    struct pixel_buffer *PB = ctx->PB;
  235.    GLfloat *win;
  236.    GLint *pbx = PB->x, *pby = PB->y;
  237.    GLdepth *pbz = PB->z;
  238.    GLuint *pbi = PB->i;
  239.    GLuint pbcount = PB->count;
  240.    GLuint i;
  241.  
  242.    win = &VB->Win[first][0];
  243.    for (i=first;i<=last;i++) {
  244.       if (VB->ClipMask[i]==0) {
  245.      pbx[pbcount] = (GLint)  win[0];
  246.      pby[pbcount] = (GLint)  win[1];
  247.      pbz[pbcount] = (GLint) (win[2] + ctx->PointZoffset);
  248.      pbi[pbcount] = VB->Index[i];
  249.      pbcount++;
  250.       }
  251.       win += 3;
  252.    }
  253.    PB->count = pbcount;
  254.    PB_CHECK_FLUSH(ctx, PB)
  255. }
  256.  
  257.  
  258.  
  259. /*
  260.  * RGBA points with size == 1.0
  261.  */
  262. static void size1_rgba_points( GLcontext *ctx, GLuint first, GLuint last )
  263. {
  264.    struct vertex_buffer *VB = ctx->VB;
  265.    struct pixel_buffer *PB = ctx->PB;
  266.    GLuint i;
  267.  
  268.    for (i=first;i<=last;i++) {
  269.       if (VB->ClipMask[i]==0) {
  270.      GLint x, y, z;
  271.      GLint red, green, blue, alpha;
  272.  
  273.      x = (GLint)  VB->Win[i][0];
  274.      y = (GLint)  VB->Win[i][1];
  275.      z = (GLint) (VB->Win[i][2] + ctx->PointZoffset);
  276.  
  277.      red   = VB->Color[i][0];
  278.      green = VB->Color[i][1];
  279.      blue  = VB->Color[i][2];
  280.      alpha = VB->Color[i][3];
  281.  
  282.      PB_WRITE_RGBA_PIXEL( PB, x, y, z, red, green, blue, alpha );
  283.       }
  284.    }
  285.    PB_CHECK_FLUSH(ctx,PB)
  286. }
  287.  
  288.  
  289.  
  290. /*
  291.  * General CI points.
  292.  */
  293. static void general_ci_points( GLcontext *ctx, GLuint first, GLuint last )
  294. {
  295.    struct vertex_buffer *VB = ctx->VB;
  296.    struct pixel_buffer *PB = ctx->PB;
  297.    GLuint i;
  298.    GLint isize;
  299.  
  300.    isize = (GLint) (CLAMP(ctx->Point.Size,MIN_POINT_SIZE,MAX_POINT_SIZE) + 0.5F);
  301.  
  302.    for (i=first;i<=last;i++) {
  303.       if (VB->ClipMask[i]==0) {
  304.      GLint x, y, z;
  305.      GLint x0, x1, y0, y1;
  306.      GLint ix, iy;
  307.  
  308.      x = (GLint)  VB->Win[i][0];
  309.      y = (GLint)  VB->Win[i][1];
  310.      z = (GLint) (VB->Win[i][2] + ctx->PointZoffset);
  311.  
  312.      if (isize&1) {
  313.         /* odd size */
  314.         x0 = x - isize/2;
  315.         x1 = x + isize/2;
  316.         y0 = y - isize/2;
  317.         y1 = y + isize/2;
  318.      }
  319.      else {
  320.         /* even size */
  321.         x0 = (GLint) (x + 0.5F) - isize/2;
  322.         x1 = x0 + isize-1;
  323.         y0 = (GLint) (y + 0.5F) - isize/2;
  324.         y1 = y0 + isize-1;
  325.      }
  326.  
  327.      PB_SET_INDEX( ctx, PB, VB->Index[i] );
  328.  
  329.      for (iy=y0;iy<=y1;iy++) {
  330.         for (ix=x0;ix<=x1;ix++) {
  331.            PB_WRITE_PIXEL( PB, ix, iy, z );
  332.         }
  333.      }
  334.      PB_CHECK_FLUSH(ctx,PB)
  335.       }
  336.    }
  337. }
  338.  
  339.  
  340. /*
  341.  * General RGBA points.
  342.  */
  343. static void general_rgba_points( GLcontext *ctx, GLuint first, GLuint last )
  344. {
  345.    struct vertex_buffer *VB = ctx->VB;
  346.    struct pixel_buffer *PB = ctx->PB;
  347.    GLuint i;
  348.    GLint isize;
  349.  
  350.    isize = (GLint) (CLAMP(ctx->Point.Size,MIN_POINT_SIZE,MAX_POINT_SIZE) + 0.5F);
  351.  
  352.    for (i=first;i<=last;i++) {
  353.       if (VB->ClipMask[i]==0) {
  354.      GLint x, y, z;
  355.      GLint x0, x1, y0, y1;
  356.      GLint ix, iy;
  357.  
  358.      x = (GLint)  VB->Win[i][0];
  359.      y = (GLint)  VB->Win[i][1];
  360.      z = (GLint) (VB->Win[i][2] + ctx->PointZoffset);
  361.  
  362.      if (isize&1) {
  363.         /* odd size */
  364.         x0 = x - isize/2;
  365.         x1 = x + isize/2;
  366.         y0 = y - isize/2;
  367.         y1 = y + isize/2;
  368.      }
  369.      else {
  370.         /* even size */
  371.         x0 = (GLint) (x + 0.5F) - isize/2;
  372.         x1 = x0 + isize-1;
  373.         y0 = (GLint) (y + 0.5F) - isize/2;
  374.         y1 = y0 + isize-1;
  375.      }
  376.  
  377.      PB_SET_COLOR( ctx, PB,
  378.                VB->Color[i][0],
  379.                VB->Color[i][1],
  380.                VB->Color[i][2],
  381.                VB->Color[i][3] );
  382.  
  383.      for (iy=y0;iy<=y1;iy++) {
  384.         for (ix=x0;ix<=x1;ix++) {
  385.            PB_WRITE_PIXEL( PB, ix, iy, z );
  386.         }
  387.      }
  388.      PB_CHECK_FLUSH(ctx,PB)
  389.       }
  390.    }
  391. }
  392.  
  393.  
  394.  
  395.  
  396. /*
  397.  * Textured RGBA points.
  398.  */
  399. static void textured_rgba_points( GLcontext *ctx, GLuint first, GLuint last )
  400. {
  401.    struct vertex_buffer *VB = ctx->VB;
  402.    struct pixel_buffer *PB = ctx->PB;
  403.    GLuint i;
  404.  
  405.    for (i=first;i<=last;i++) {
  406.       if (VB->ClipMask[i]==0) {
  407.      GLint x, y, z;
  408.      GLint x0, x1, y0, y1;
  409.      GLint ix, iy;
  410.      GLint isize;
  411.      GLint red, green, blue, alpha;
  412.      GLfloat s, t, u;
  413.  
  414.      x = (GLint)  VB->Win[i][0];
  415.      y = (GLint)  VB->Win[i][1];
  416.      z = (GLint) (VB->Win[i][2] + ctx->PointZoffset);
  417.  
  418.      isize = (GLint)
  419.            (CLAMP(ctx->Point.Size,MIN_POINT_SIZE,MAX_POINT_SIZE) + 0.5F);
  420.      if (isize<1) {
  421.         isize = 1;
  422.      }
  423.  
  424.      if (isize&1) {
  425.         /* odd size */
  426.         x0 = x - isize/2;
  427.         x1 = x + isize/2;
  428.         y0 = y - isize/2;
  429.         y1 = y + isize/2;
  430.      }
  431.      else {
  432.         /* even size */
  433.         x0 = (GLint) (x + 0.5F) - isize/2;
  434.         x1 = x0 + isize-1;
  435.         y0 = (GLint) (y + 0.5F) - isize/2;
  436.         y1 = y0 + isize-1;
  437.      }
  438.  
  439.      red   = VB->Color[i][0];
  440.      green = VB->Color[i][1];
  441.      blue  = VB->Color[i][2];
  442.      alpha = VB->Color[i][3];
  443.      s = VB->TexCoord[i][0] / VB->TexCoord[i][3];
  444.      t = VB->TexCoord[i][1] / VB->TexCoord[i][3];
  445.      u = VB->TexCoord[i][2] / VB->TexCoord[i][3];
  446.  
  447. /*    don't think this is needed
  448.      PB_SET_COLOR( red, green, blue, alpha );
  449. */
  450.  
  451.      for (iy=y0;iy<=y1;iy++) {
  452.         for (ix=x0;ix<=x1;ix++) {
  453.            PB_WRITE_TEX_PIXEL( PB, ix, iy, z, red, green, blue, alpha, s, t, u );
  454.         }
  455.      }
  456.      PB_CHECK_FLUSH(ctx,PB)
  457.       }
  458.    }
  459. }
  460.  
  461.  
  462.  
  463. /*
  464.  * Antialiased points with or without texture mapping.
  465.  */
  466. static void antialiased_rgba_points( GLcontext *ctx,
  467.                      GLuint first, GLuint last )
  468. {
  469.    struct vertex_buffer *VB = ctx->VB;
  470.    struct pixel_buffer *PB = ctx->PB;
  471.    GLuint i;
  472.    GLfloat radius, rmin, rmax, rmin2, rmax2, cscale;
  473.  
  474.    radius = CLAMP( ctx->Point.Size, MIN_POINT_SIZE, MAX_POINT_SIZE ) * 0.5F;
  475.    rmin = radius - 0.7071F;  /* 0.7071 = sqrt(2)/2 */
  476.    rmax = radius + 0.7071F;
  477.    rmin2 = rmin*rmin;
  478.    rmax2 = rmax*rmax;
  479.    cscale = 256.0F / (rmax2-rmin2);
  480.  
  481.    if (ctx->Texture.Enabled) {
  482.       for (i=first;i<=last;i++) {
  483.      if (VB->ClipMask[i]==0) {
  484.         GLint xmin, ymin, xmax, ymax;
  485.         GLint x, y, z;
  486.         GLint red, green, blue, alpha;
  487.         GLfloat s, t, u;
  488.  
  489.         xmin = (GLint) (VB->Win[i][0] - radius);
  490.         xmax = (GLint) (VB->Win[i][0] + radius);
  491.         ymin = (GLint) (VB->Win[i][1] - radius);
  492.         ymax = (GLint) (VB->Win[i][1] + radius);
  493.         z = (GLint) (VB->Win[i][2] + ctx->PointZoffset);
  494.  
  495.         red   = VB->Color[i][0];
  496.         green = VB->Color[i][1];
  497.         blue  = VB->Color[i][2];
  498.         s = VB->TexCoord[i][0] / VB->TexCoord[i][3];
  499.         t = VB->TexCoord[i][1] / VB->TexCoord[i][3];
  500.         u = VB->TexCoord[i][2] / VB->TexCoord[i][3];
  501.  
  502.         for (y=ymin;y<=ymax;y++) {
  503.            for (x=xmin;x<=xmax;x++) {
  504.           GLfloat dx = x/*+0.5F*/ - VB->Win[i][0];
  505.           GLfloat dy = y/*+0.5F*/ - VB->Win[i][1];
  506.           GLfloat dist2 = dx*dx + dy*dy;
  507.           if (dist2<rmax2) {
  508.              alpha = VB->Color[i][3];
  509.              if (dist2>=rmin2) {
  510.             GLint coverage = (GLint) (256.0F-(dist2-rmin2)*cscale);
  511.             /* coverage is in [0,256] */
  512.             alpha = (alpha * coverage) >> 8;
  513.              }
  514.              PB_WRITE_TEX_PIXEL( PB, x,y,z, red, green, blue, alpha, s, t, u );
  515.           }
  516.            }
  517.         }
  518.         PB_CHECK_FLUSH(ctx,PB)
  519.      }
  520.       }
  521.    }
  522.    else {
  523.       /* Not texture mapped */
  524.       for (i=first;i<=last;i++) {
  525.      if (VB->ClipMask[i]==0) {
  526.         GLint xmin, ymin, xmax, ymax;
  527.         GLint x, y, z;
  528.         GLint red, green, blue, alpha;
  529.  
  530.         xmin = (GLint) (VB->Win[i][0] - radius);
  531.         xmax = (GLint) (VB->Win[i][0] + radius);
  532.         ymin = (GLint) (VB->Win[i][1] - radius);
  533.         ymax = (GLint) (VB->Win[i][1] + radius);
  534.         z = (GLint) (VB->Win[i][2] + ctx->PointZoffset);
  535.  
  536.         red   = VB->Color[i][0];
  537.         green = VB->Color[i][1];
  538.         blue  = VB->Color[i][2];
  539.  
  540.         for (y=ymin;y<=ymax;y++) {
  541.            for (x=xmin;x<=xmax;x++) {
  542.           GLfloat dx = x/*+0.5F*/ - VB->Win[i][0];
  543.           GLfloat dy = y/*+0.5F*/ - VB->Win[i][1];
  544.           GLfloat dist2 = dx*dx + dy*dy;
  545.           if (dist2<rmax2) {
  546.              alpha = VB->Color[i][3];
  547.              if (dist2>=rmin2) {
  548.             GLint coverage = (GLint) (256.0F-(dist2-rmin2)*cscale);
  549.             /* coverage is in [0,256] */
  550.             alpha = (alpha * coverage) >> 8;
  551.              }
  552.              PB_WRITE_RGBA_PIXEL( PB, x, y, z, red, green, blue, alpha );
  553.           }
  554.            }
  555.         }
  556.         PB_CHECK_FLUSH(ctx,PB)
  557.      }
  558.       }
  559.    }
  560. }
  561.  
  562.  
  563.  
  564. /*
  565.  * Null rasterizer for measuring transformation speed.
  566.  */
  567. static void null_points( GLcontext *ctx, GLuint first, GLuint last )
  568. {
  569. }
  570.  
  571. /* Definition of the functions for GL_EXT_point_parameters */
  572.  
  573. /*
  574.  * Calculates the distance attenuation formula of a point in eye space
  575.  * coordinates
  576.  */
  577. static GLfloat dist_attenuation(GLcontext *ctx, const GLfloat p[3])
  578. {
  579.  GLfloat dist;
  580.  dist=GL_SQRT(p[0]*p[0]+p[1]*p[1]+p[2]*p[2]);
  581.  return (1/(ctx->Point.Params[0]+ ctx->Point.Params[1]*dist +
  582.          ctx->Point.Params[2]*dist*dist));
  583. }
  584.  
  585. /*
  586.  * Distance Attenuated General CI points.
  587.  */
  588. static void dist_atten_general_ci_points( GLcontext *ctx, GLuint first, 
  589.                     GLuint last )
  590. {
  591.    struct vertex_buffer *VB = ctx->VB;
  592.    struct pixel_buffer *PB = ctx->PB;
  593.    GLuint i;
  594.    GLint isize;
  595.    GLfloat psize,dsize;
  596.    psize=CLAMP(ctx->Point.Size,MIN_POINT_SIZE,MAX_POINT_SIZE);
  597.  
  598.    for (i=first;i<=last;i++) {
  599.       if (VB->ClipMask[i]==0) {
  600.      GLint x, y, z;
  601.      GLint x0, x1, y0, y1;
  602.      GLint ix, iy;
  603.  
  604.      x = (GLint)  VB->Win[i][0];
  605.      y = (GLint)  VB->Win[i][1];
  606.      z = (GLint) (VB->Win[i][2] + ctx->PointZoffset);
  607.  
  608.      dsize=psize*dist_attenuation(ctx,VB->Eye[i]);
  609.      if(dsize>=ctx->Point.Threshold) {
  610.         isize=(GLint) (MIN2(dsize,ctx->Point.MaxSize)+0.5F);
  611.      } else {
  612.         isize=(GLint) (MAX2(ctx->Point.Threshold,ctx->Point.MinSize)+0.5F);
  613.      }
  614.  
  615.      if (isize&1) {
  616.         /* odd size */
  617.         x0 = x - isize/2;
  618.         x1 = x + isize/2;
  619.         y0 = y - isize/2;
  620.         y1 = y + isize/2;
  621.      }
  622.      else {
  623.         /* even size */
  624.         x0 = (GLint) (x + 0.5F) - isize/2;
  625.         x1 = x0 + isize-1;
  626.         y0 = (GLint) (y + 0.5F) - isize/2;
  627.         y1 = y0 + isize-1;
  628.      }
  629.  
  630.      PB_SET_INDEX( ctx, PB, VB->Index[i] );
  631.  
  632.      for (iy=y0;iy<=y1;iy++) {
  633.         for (ix=x0;ix<=x1;ix++) {
  634.            PB_WRITE_PIXEL( PB, ix, iy, z );
  635.         }
  636.      }
  637.      PB_CHECK_FLUSH(ctx,PB)
  638.       }
  639.    }
  640. }
  641.  
  642. /*
  643.  * Distance Attenuated General RGBA points.
  644.  */
  645. static void dist_atten_general_rgba_points( GLcontext *ctx, GLuint first, 
  646.                 GLuint last )
  647. {
  648.    struct vertex_buffer *VB = ctx->VB;
  649.    struct pixel_buffer *PB = ctx->PB;
  650.    GLuint i;
  651.    GLubyte alpha;
  652.    GLint isize;
  653.    GLfloat psize,dsize;
  654.    psize=CLAMP(ctx->Point.Size,MIN_POINT_SIZE,MAX_POINT_SIZE);
  655.  
  656.    for (i=first;i<=last;i++) {
  657.       if (VB->ClipMask[i]==0) {
  658.      GLint x, y, z;
  659.      GLint x0, x1, y0, y1;
  660.      GLint ix, iy;
  661.  
  662.      x = (GLint)  VB->Win[i][0];
  663.      y = (GLint)  VB->Win[i][1];
  664.      z = (GLint) (VB->Win[i][2] + ctx->PointZoffset);
  665.      dsize=psize*dist_attenuation(ctx,VB->Eye[i]);
  666.      if(dsize>=ctx->Point.Threshold) {
  667.         isize=(GLint) (MIN2(dsize,ctx->Point.MaxSize)+0.5F);
  668.         alpha=VB->Color[i][3];
  669.      } else {
  670.         isize=(GLint) (MAX2(ctx->Point.Threshold,ctx->Point.MinSize)+0.5F);
  671.         dsize/=ctx->Point.Threshold;
  672.         alpha=VB->Color[i][3]* (dsize*dsize);
  673.      }
  674.      if (isize&1) {
  675.         /* odd size */
  676.         x0 = x - isize/2;
  677.         x1 = x + isize/2;
  678.         y0 = y - isize/2;
  679.         y1 = y + isize/2;
  680.      }
  681.      else {
  682.         /* even size */
  683.         x0 = (GLint) (x + 0.5F) - isize/2;
  684.         x1 = x0 + isize-1;
  685.         y0 = (GLint) (y + 0.5F) - isize/2;
  686.         y1 = y0 + isize-1;
  687.      }
  688.      PB_SET_COLOR( ctx, PB,
  689.                VB->Color[i][0],
  690.                VB->Color[i][1],
  691.                VB->Color[i][2],
  692.                alpha );
  693.  
  694.      for (iy=y0;iy<=y1;iy++) {
  695.         for (ix=x0;ix<=x1;ix++) {
  696.            PB_WRITE_PIXEL( PB, ix, iy, z );
  697.         }
  698.      }
  699.      PB_CHECK_FLUSH(ctx,PB)
  700.       }
  701.    }
  702. }
  703.  
  704. /*
  705.  *  Distance Attenuated Textured RGBA points.
  706.  */
  707. static void dist_atten_textured_rgba_points( GLcontext *ctx, GLuint first, 
  708.                     GLuint last )
  709. {
  710.    struct vertex_buffer *VB = ctx->VB;
  711.    struct pixel_buffer *PB = ctx->PB;
  712.    GLuint i;
  713.    GLfloat psize,dsize;
  714.    psize=CLAMP(ctx->Point.Size,MIN_POINT_SIZE,MAX_POINT_SIZE);
  715.  
  716.    for (i=first;i<=last;i++) {
  717.       if (VB->ClipMask[i]==0) {
  718.      GLint x, y, z;
  719.      GLint x0, x1, y0, y1;
  720.      GLint ix, iy;
  721.      GLint isize;
  722.      GLint red, green, blue, alpha;
  723.      GLfloat s, t, u;
  724.  
  725.      x = (GLint)  VB->Win[i][0];
  726.      y = (GLint)  VB->Win[i][1];
  727.      z = (GLint) (VB->Win[i][2] + ctx->PointZoffset);
  728.  
  729.      dsize=psize*dist_attenuation(ctx,VB->Eye[i]);
  730.      if(dsize>=ctx->Point.Threshold) {
  731.         isize=(GLint) (MIN2(dsize,ctx->Point.MaxSize)+0.5F);
  732.         alpha=VB->Color[i][3];
  733.      } else {
  734.         isize=(GLint) (MAX2(ctx->Point.Threshold,ctx->Point.MinSize)+0.5F);
  735.         dsize/=ctx->Point.Threshold;
  736.         alpha=VB->Color[i][3]* (dsize*dsize);
  737.      }
  738.  
  739.      if (isize<1) {
  740.         isize = 1;
  741.      }
  742.  
  743.      if (isize&1) {
  744.         /* odd size */
  745.         x0 = x - isize/2;
  746.         x1 = x + isize/2;
  747.         y0 = y - isize/2;
  748.         y1 = y + isize/2;
  749.      }
  750.      else {
  751.         /* even size */
  752.         x0 = (GLint) (x + 0.5F) - isize/2;
  753.         x1 = x0 + isize-1;
  754.         y0 = (GLint) (y + 0.5F) - isize/2;
  755.         y1 = y0 + isize-1;
  756.      }
  757.  
  758.      red   = VB->Color[i][0];
  759.      green = VB->Color[i][1];
  760.      blue  = VB->Color[i][2];
  761.      s = VB->TexCoord[i][0] / VB->TexCoord[i][3];
  762.      t = VB->TexCoord[i][1] / VB->TexCoord[i][3];
  763.      u = VB->TexCoord[i][2] / VB->TexCoord[i][3];
  764.  
  765. /*    don't think this is needed
  766.      PB_SET_COLOR( red, green, blue, alpha );
  767. */
  768.   
  769.      for (iy=y0;iy<=y1;iy++) {
  770.         for (ix=x0;ix<=x1;ix++) {
  771.            PB_WRITE_TEX_PIXEL( PB, ix, iy, z, red, green, blue, alpha, s, t,
  772.  u );
  773.         }
  774.      }
  775.      PB_CHECK_FLUSH(ctx,PB)
  776.       }
  777.    }
  778. }
  779.  
  780. /*
  781.  * Distance Attenuated Antialiased points with or without texture mapping.
  782.  */
  783. static void dist_atten_antialiased_rgba_points( GLcontext *ctx,
  784.                      GLuint first, GLuint last )
  785. {
  786.    struct vertex_buffer *VB = ctx->VB;
  787.    struct pixel_buffer *PB = ctx->PB;
  788.    GLuint i;
  789.    GLfloat radius, rmin, rmax, rmin2, rmax2, cscale;
  790.    GLfloat psize,dsize,alphaf;
  791.    psize=CLAMP(ctx->Point.Size,MIN_POINT_SIZE,MAX_POINT_SIZE);
  792.  
  793.    if (ctx->Texture.Enabled) {
  794.       for (i=first;i<=last;i++) {
  795.      if (VB->ClipMask[i]==0) {
  796.         GLint xmin, ymin, xmax, ymax;
  797.         GLint x, y, z;
  798.         GLint red, green, blue, alpha;
  799.         GLfloat s, t, u;
  800.  
  801.  
  802.         dsize=psize*dist_attenuation(ctx,VB->Eye[i]);
  803.         if(dsize>=ctx->Point.Threshold) {
  804.            radius=(MIN2(dsize,ctx->Point.MaxSize)*0.5F);
  805.            alphaf=1.0;
  806.         } else {
  807.            radius=(MAX2(ctx->Point.Threshold,ctx->Point.MinSize)*0.5F);
  808.            dsize/=ctx->Point.Threshold;
  809.            alphaf=(dsize*dsize);
  810.         }
  811.         rmin = radius - 0.7071F;  /* 0.7071 = sqrt(2)/2 */
  812.         rmax = radius + 0.7071F;
  813.         rmin2 = rmin*rmin;
  814.         rmax2 = rmax*rmax;
  815.         cscale = 256.0F / (rmax2-rmin2);
  816.  
  817.         xmin = (GLint) (VB->Win[i][0] - radius);
  818.         xmax = (GLint) (VB->Win[i][0] + radius);
  819.         ymin = (GLint) (VB->Win[i][1] - radius);
  820.         ymax = (GLint) (VB->Win[i][1] + radius);
  821.         z = (GLint) (VB->Win[i][2] + ctx->PointZoffset);
  822.  
  823.         red   = VB->Color[i][0];
  824.         green = VB->Color[i][1];
  825.         blue  = VB->Color[i][2];
  826.         s = VB->TexCoord[i][0] / VB->TexCoord[i][3];
  827.         t = VB->TexCoord[i][1] / VB->TexCoord[i][3];
  828.         u = VB->TexCoord[i][2] / VB->TexCoord[i][3];
  829.  
  830.         for (y=ymin;y<=ymax;y++) {
  831.            for (x=xmin;x<=xmax;x++) {
  832.           GLfloat dx = x/*+0.5F*/ - VB->Win[i][0];
  833.           GLfloat dy = y/*+0.5F*/ - VB->Win[i][1];
  834.           GLfloat dist2 = dx*dx + dy*dy;
  835.           if (dist2<rmax2) {
  836.              alpha = VB->Color[i][3];
  837.              if (dist2>=rmin2) {
  838.             GLint coverage = (GLint) (256.0F-(dist2-rmin2)*cscale);
  839.             /* coverage is in [0,256] */
  840.             alpha = (alpha * coverage) >> 8;
  841.              }
  842.              alpha*=alphaf;
  843.              PB_WRITE_TEX_PIXEL( PB, x,y,z, red, green, blue, alpha, s,
  844. t, u );
  845.           }
  846.            }
  847.         }
  848.         PB_CHECK_FLUSH(ctx,PB)
  849.      }
  850.       }
  851.    }
  852.    else {
  853.       /* Not texture mapped */
  854.       for (i=first;i<=last;i++) {
  855.      if (VB->ClipMask[i]==0) {
  856.         GLint xmin, ymin, xmax, ymax;
  857.         GLint x, y, z;
  858.         GLint red, green, blue, alpha;
  859.  
  860.         dsize=psize*dist_attenuation(ctx,VB->Eye[i]);
  861.         if(dsize>=ctx->Point.Threshold) {
  862.            radius=(MIN2(dsize,ctx->Point.MaxSize)*0.5F);
  863.            alphaf=1.0;
  864.         } else {
  865.            radius=(MAX2(ctx->Point.Threshold,ctx->Point.MinSize)*0.5F);
  866.            dsize/=ctx->Point.Threshold;
  867.            alphaf=(dsize*dsize);
  868.         }
  869.         rmin = radius - 0.7071F;  /* 0.7071 = sqrt(2)/2 */
  870.         rmax = radius + 0.7071F;
  871.         rmin2 = rmin*rmin;
  872.         rmax2 = rmax*rmax;
  873.         cscale = 256.0F / (rmax2-rmin2);
  874.  
  875.         xmin = (GLint) (VB->Win[i][0] - radius);
  876.         xmax = (GLint) (VB->Win[i][0] + radius);
  877.         ymin = (GLint) (VB->Win[i][1] - radius);
  878.         ymax = (GLint) (VB->Win[i][1] + radius);
  879.         z = (GLint) (VB->Win[i][2] + ctx->PointZoffset);
  880.  
  881.         red   = VB->Color[i][0];
  882.         green = VB->Color[i][1];
  883.         blue  = VB->Color[i][2];
  884.  
  885.         for (y=ymin;y<=ymax;y++) {
  886.            for (x=xmin;x<=xmax;x++) {
  887.           GLfloat dx = x/*+0.5F*/ - VB->Win[i][0];
  888.           GLfloat dy = y/*+0.5F*/ - VB->Win[i][1];
  889.           GLfloat dist2 = dx*dx + dy*dy;
  890.           if (dist2<rmax2) {
  891.               alpha = VB->Color[i][3];
  892.              if (dist2>=rmin2) {
  893.             GLint coverage = (GLint) (256.0F-(dist2-rmin2)*cscale);
  894.             /* coverage is in [0,256] */
  895.             alpha = (alpha * coverage) >> 8;
  896.              }
  897.              alpha*=alphaf;
  898.              PB_WRITE_RGBA_PIXEL( PB, x, y, z, red, green, blue, alpha )
  899. ;
  900.           }
  901.            }
  902.         }
  903.         PB_CHECK_FLUSH(ctx,PB)
  904.      }
  905.       }
  906.    }
  907. }
  908.  
  909.  
  910. /*
  911.  * Examine the current context to determine which point drawing function
  912.  * should be used.
  913.  */
  914. void gl_set_point_function( GLcontext *ctx )
  915. {
  916.    GLboolean rgbmode = ctx->Visual->RGBAflag;
  917.  
  918.    if (ctx->RenderMode==GL_RENDER) {
  919.       if (ctx->NoRaster) {
  920.      ctx->Driver.PointsFunc = null_points;
  921.      return;
  922.       }
  923.       if (ctx->Driver.PointsFunc) {
  924.      /* Device driver will draw points. */
  925.      ctx->Driver.PointsFunc = ctx->Driver.PointsFunc;
  926.       }
  927.       else if (ctx->Point.Params[0]==1.0 && ctx->Point.Params[1]==0.0 && 
  928.            ctx->Point.Params[2]==0.0) { 
  929.      if (ctx->Point.SmoothFlag && rgbmode) {
  930.         ctx->Driver.PointsFunc = antialiased_rgba_points;
  931.      }
  932.      else if (ctx->Texture.Enabled) {
  933.         ctx->Driver.PointsFunc = textured_rgba_points;
  934.      }
  935.      else if (ctx->Point.Size==1.0) {
  936.         /* size=1, any raster ops */
  937.         ctx->Driver.PointsFunc = rgbmode ? (points_func)size1_rgba_points
  938.                          : (points_func)size1_ci_points;
  939.      }
  940.      else {
  941.         /* every other kind of point rendering */
  942.         ctx->Driver.PointsFunc = rgbmode ? (points_func)general_rgba_points
  943.                          : (points_func)general_ci_points;
  944.      }
  945.       } 
  946.       else if(ctx->Point.SmoothFlag && rgbmode) {
  947.      ctx->Driver.PointsFunc = dist_atten_antialiased_rgba_points;
  948.       }
  949.       else if (ctx->Texture.Enabled) {
  950.      ctx->Driver.PointsFunc = dist_atten_textured_rgba_points;
  951.       } 
  952.       else {
  953.      /* every other kind of point rendering */
  954.      ctx->Driver.PointsFunc = rgbmode ? (points_func)dist_atten_general_rgba_points
  955.                       : (points_func)dist_atten_general_ci_points;
  956.      }
  957.    }
  958.    else if (ctx->RenderMode==GL_FEEDBACK) {
  959.       ctx->Driver.PointsFunc = feedback_points;
  960.    }
  961.    else {
  962.       /* GL_SELECT mode */
  963.       ctx->Driver.PointsFunc = select_points;
  964.    }
  965.  
  966. }
  967.  
  968.