Fix a number of point size attenuation problems.
authorBrian Paul <brian.paul@tungstengraphics.com>
Fri, 7 Oct 2005 03:56:29 +0000 (03:56 +0000)
committerBrian Paul <brian.paul@tungstengraphics.com>
Fri, 7 Oct 2005 03:56:29 +0000 (03:56 +0000)
Move size clamping into the rasterization function.

src/mesa/main/points.c
src/mesa/main/points.h
src/mesa/main/state.c
src/mesa/swrast/s_pointtemp.h
src/mesa/tnl/t_vb_points.c

index 2ffb1a421253f133192c8d72854739cc2839e90c..aa36fb62877700d3e49f837fd9da2a28a5d20838 100644 (file)
@@ -5,9 +5,9 @@
 
 /*
  * Mesa 3-D graphics library
- * Version:  6.2
+ * Version:  6.5
  *
- * Copyright (C) 1999-2004  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2005  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
 
 
 /**
- * Set the point size.
- *
- * \param size pointer diameter.
- *
+ * Set current point size.
+ * \param size  point diameter in pixels
  * \sa glPointSize().
- *
- * Verifies the parameter and updates gl_point_attrib::Size. On a change,
- * flushes the vertices, updates the clamped point size and marks the
- * DD_POINT_SIZE flag in __GLcontextRec::_TriangleCaps for the drivers if the
- * size is different from one. Notifies the driver via
- * the dd_function_table::PointSize callback.
  */
 void GLAPIENTRY
 _mesa_PointSize( GLfloat size )
@@ -65,17 +57,9 @@ _mesa_PointSize( GLfloat size )
 
    FLUSH_VERTICES(ctx, _NEW_POINT);
    ctx->Point.Size = size;
-   ctx->Point._Size = CLAMP(size,
-                           ctx->Const.MinPointSize,
-                           ctx->Const.MaxPointSize);
-
-   if (ctx->Point._Size == 1.0F)
-      ctx->_TriangleCaps &= ~DD_POINT_SIZE;
-   else
-      ctx->_TriangleCaps |= DD_POINT_SIZE;
 
    if (ctx->Driver.PointSize)
-      (*ctx->Driver.PointSize)(ctx, size);
+      ctx->Driver.PointSize(ctx, size);
 }
 
 
@@ -127,24 +111,10 @@ _mesa_PointParameterfvEXT( GLenum pname, const GLfloat *params)
    switch (pname) {
       case GL_DISTANCE_ATTENUATION_EXT:
          if (ctx->Extensions.EXT_point_parameters) {
-            const GLboolean tmp = ctx->Point._Attenuated;
             if (TEST_EQ_3V(ctx->Point.Params, params))
               return;
-
            FLUSH_VERTICES(ctx, _NEW_POINT);
             COPY_3V(ctx->Point.Params, params);
-
-           /* Update several derived values now.  This likely to be
-            * more efficient than trying to catch this statechange in
-            * state.c.
-            */
-            ctx->Point._Attenuated = (params[0] != 1.0 ||
-                                     params[1] != 0.0 ||
-                                     params[2] != 0.0);
-
-            if (tmp != ctx->Point._Attenuated) {
-               ctx->_TriangleCaps ^= DD_POINT_ATTEN;
-            }
          }
          else {
             _mesa_error(ctx, GL_INVALID_ENUM,
@@ -260,6 +230,37 @@ _mesa_PointParameterfvEXT( GLenum pname, const GLfloat *params)
 #endif
 
 
+
+/**
+ * Update derived point-related state.
+ */
+void
+_mesa_update_point(GLcontext *ctx)
+{
+   /* clamp to user-specified limits now, clamp to ctx->Const.Min/Max
+    * limits during rasterization.
+    */
+   ctx->Point._Size = CLAMP(ctx->Point.Size,
+                           ctx->Point.MinSize,
+                           ctx->Point.MaxSize);
+
+   if (ctx->Point._Size == 1.0F)
+      ctx->_TriangleCaps &= ~DD_POINT_SIZE;
+   else
+      ctx->_TriangleCaps |= DD_POINT_SIZE;
+
+   ctx->Point._Attenuated = (ctx->Point.Params[0] != 1.0 ||
+                             ctx->Point.Params[1] != 0.0 ||
+                             ctx->Point.Params[2] != 0.0);
+
+   if (ctx->Point._Attenuated)
+      ctx->_TriangleCaps |= DD_POINT_ATTEN;
+   else
+      ctx->_TriangleCaps &= ~DD_POINT_ATTEN;
+}
+
+
+
 /**
  * Initialize the context point state.
  *
@@ -268,11 +269,11 @@ _mesa_PointParameterfvEXT( GLenum pname, const GLfloat *params)
  * Initializes __GLcontextRec::Point and point related constants in
  * __GLcontextRec::Const.
  */
-void _mesa_init_point( GLcontext * ctx )
+void
+_mesa_init_point(GLcontext *ctx)
 {
-   int i;
-   
-   /* Point group */
+   GLuint i;
+
    ctx->Point.SmoothFlag = GL_FALSE;
    ctx->Point.Size = 1.0;
    ctx->Point._Size = 1.0;
@@ -281,12 +282,13 @@ void _mesa_init_point( GLcontext * ctx )
    ctx->Point.Params[2] = 0.0;
    ctx->Point._Attenuated = GL_FALSE;
    ctx->Point.MinSize = 0.0;
-   ctx->Point.MaxSize = ctx->Const.MaxPointSize;
+   ctx->Point.MaxSize
+      = MAX2(ctx->Const.MaxPointSize, ctx->Const.MaxPointSizeAA);
    ctx->Point.Threshold = 1.0;
-   ctx->Point.PointSprite = GL_FALSE; /* GL_ARB_point_sprite / GL_NV_point_sprite */
+   ctx->Point.PointSprite = GL_FALSE; /* GL_ARB/NV_point_sprite */
    ctx->Point.SpriteRMode = GL_ZERO; /* GL_NV_point_sprite (only!) */
    ctx->Point.SpriteOrigin = GL_UPPER_LEFT; /* GL_ARB_point_sprite */
    for (i = 0; i < MAX_TEXTURE_UNITS; i++) {
-      ctx->Point.CoordReplace[i] = GL_FALSE; /* GL_ARB_point_sprite / GL_NV_point_sprite */
+      ctx->Point.CoordReplace[i] = GL_FALSE; /* GL_ARB/NV_point_sprite */
    }
 }
index 16513c3ec673c6d6ac62360b393909af617d51fd..56acd9ee57445822545c030669ee8059532f1c7d 100644 (file)
@@ -5,9 +5,9 @@
 
 /*
  * Mesa 3-D graphics library
- * Version:  4.1
+ * Version:  6.5
  *
- * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2005  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -50,6 +50,9 @@ _mesa_PointParameterfEXT( GLenum pname, GLfloat param );
 extern void GLAPIENTRY
 _mesa_PointParameterfvEXT( GLenum pname, const GLfloat *params );
 
+extern void
+_mesa_update_point(GLcontext *ctx);
+
 extern void 
 _mesa_init_point( GLcontext * ctx );
 
index 509ee42a023b6040f0b6eb5a7ce090f3c32cc8b2..244cb485c6c4f21f06c0fe9f94f6ce2f26957c82 100644 (file)
@@ -987,6 +987,9 @@ _mesa_update_state( GLcontext *ctx )
    if (new_state & (_NEW_SCISSOR|_NEW_BUFFERS))
       _mesa_update_draw_buffer_bounds( ctx );
 
+   if (new_state & _NEW_POINT)
+      _mesa_update_point( ctx );
+
    if (new_state & _NEW_POLYGON)
       _mesa_update_polygon( ctx );
 
index b0c110f30074bbbbc10544a39c48edfdaeee5049..4ce261009c0e99d07e3f78d5b466df56ac4f058a 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.3
+ * Version:  6.5
  *
- * Copyright (C) 1999-2004  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2005  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -153,28 +153,44 @@ NAME ( GLcontext *ctx, const SWvertex *vert )
    span->arrayMask |= SPAN_TEXTURE;
 #endif
 
+   /* Compute point size if not known to be one */
 #if FLAGS & ATTENUATE
-   if (vert->pointSize >= ctx->Point.Threshold) {
-      size = MIN2(vert->pointSize, ctx->Point.MaxSize);
+   /* first, clamp attenuated size to the user-specifed range */
+   size = CLAMP(vert->pointSize, ctx->Point.MinSize, ctx->Point.MaxSize);
 #if (FLAGS & RGBA) && (FLAGS & SMOOTH)
-      alphaAtten = 1.0F;
-#endif
+   /* only if multisampling, compute the fade factor */
+   if (ctx->Multisample.Enabled) {
+      if (vert->pointSize >= ctx->Point.Threshold) {
+         alphaAtten = 1.0F;
+      }
+      else {
+         GLfloat dsize = vert->pointSize / ctx->Point.Threshold;
+         alphaAtten = dsize * dsize;
+      }
    }
    else {
-#if (FLAGS & RGBA) && (FLAGS & SMOOTH)
-      GLfloat dsize = vert->pointSize / ctx->Point.Threshold;
-      alphaAtten = dsize * dsize;
-#endif
-      size = MAX2(ctx->Point.Threshold, ctx->Point.MinSize);
+      alphaAtten = 1.0;
    }
+#endif
 #elif FLAGS & (LARGE | SMOOTH | SPRITE)
-   size = ctx->Point._Size;
+   /* constant, non-attenuated size */
+   size = ctx->Point._Size; /* this is already clamped */
 #endif
 
+
 #if FLAGS & (ATTENUATE | LARGE | SMOOTH | SPRITE)
-   /*
-    * Multi-pixel points
-    */
+   /***
+    *** Multi-pixel points
+    ***/
+
+   /* do final clamping now */
+   if (ctx->Point.SmoothFlag) {
+      size = CLAMP(size, ctx->Const.MinPointSizeAA, ctx->Const.MaxPointSizeAA);
+   }
+   else {
+      size = CLAMP(size, ctx->Const.MinPointSize, ctx->Const.MaxPointSize);
+   }
+
    {{
       GLint x, y;
       const GLfloat radius = 0.5F * size;
@@ -312,20 +328,21 @@ NAME ( GLcontext *ctx, const SWvertex *vert )
                if (ctx->Texture.Unit[u]._ReallyEnabled) {
                   if (ctx->Point.CoordReplace[u]) {
                      GLfloat s = 0.5F + (x + 0.5F - vert->win[0]) / size;
-                     GLfloat t;
+                     GLfloat t, r;
                      if (ctx->Point.SpriteOrigin == GL_LOWER_LEFT)
                         t = 0.5F + (y + 0.5F - vert->win[1]) / size;
                      else /* GL_UPPER_LEFT */
                         t = 0.5F - (y + 0.5F - vert->win[1]) / size;
-                     span->array->texcoords[u][count][0] = s;
-                     span->array->texcoords[u][count][1] = t;
-                     span->array->texcoords[u][count][3] = 1.0F;
                      if (ctx->Point.SpriteRMode == GL_ZERO)
-                        span->array->texcoords[u][count][2] = 0.0F;
+                        r = 0.0F;
                      else if (ctx->Point.SpriteRMode == GL_S)
-                        span->array->texcoords[u][count][2] = vert->texcoord[u][0];
+                        r = vert->texcoord[u][0];
                      else /* GL_R */
-                        span->array->texcoords[u][count][2] = vert->texcoord[u][2];
+                        r = vert->texcoord[u][2];
+                     span->array->texcoords[u][count][0] = s;
+                     span->array->texcoords[u][count][1] = t;
+                     span->array->texcoords[u][count][2] = r;
+                     span->array->texcoords[u][count][3] = 1.0F;
                   }
                   else {
                      COPY_4V(span->array->texcoords[u][count], vert->texcoord[u]);
@@ -345,9 +362,9 @@ NAME ( GLcontext *ctx, const SWvertex *vert )
 
 #else /* LARGE | ATTENUATE | SMOOTH | SPRITE */
 
-   /*
-    * Single-pixel points
-    */
+   /***
+    *** Single-pixel points
+    ***/
    {{
       GLuint count;
 
index ccceba3262d9b94a6269ea2c842f8e5c99f55526..47c37930d570a72a50a690e5290c78e2eb3dda5f 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.1
+ * Version:  6.5
  *
- * Copyright (C) 1999-2004  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2005  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -38,11 +38,14 @@ struct point_stage_data {
 #define POINT_STAGE_DATA(stage) ((struct point_stage_data *)stage->privatePtr)
 
 
-/*
- * Compute attenuated point sizes
+/**
+ * Compute point size for each vertex from the vertex eye-space Z
+ * coordinate and the point size attenuation factors.
+ * Only done when point size attenuation is enabled and vertex program is
+ * disabled.
  */
-static GLboolean run_point_stage( GLcontext *ctx,
-                                 struct tnl_pipeline_stage *stage )
+static GLboolean
+run_point_stage(GLcontext *ctx, struct tnl_pipeline_stage *stage)
 {
    if (ctx->Point._Attenuated && !ctx->VertexProgram._Enabled) {
       struct point_stage_data *store = POINT_STAGE_DATA(stage);
@@ -51,14 +54,15 @@ static GLboolean run_point_stage( GLcontext *ctx,
       const GLfloat p0 = ctx->Point.Params[0];
       const GLfloat p1 = ctx->Point.Params[1];
       const GLfloat p2 = ctx->Point.Params[2];
-      const GLfloat pointSize = ctx->Point._Size;
+      const GLfloat pointSize = ctx->Point.Size;
       GLfloat (*size)[4] = store->PointSize.data;
       GLuint i;
 
       for (i = 0; i < VB->Count; i++) {
-        const GLfloat dist = -eye[i][2];
-        /* GLfloat dist = SQRTF(pos[0]*pos[0]+pos[1]*pos[1]+pos[2]*pos[2]);*/
-        size[i][0] = pointSize / (p0 + dist * (p1 + dist * p2));
+         const GLfloat dist = FABSF(eye[i][2]);
+         const GLfloat q = p0 + dist * (p1 + dist * p2);
+         const GLfloat atten = (q != 0.0) ? SQRTF(1.0 / q) : 1.0;
+         size[i][0] = pointSize * atten; /* clamping done in rasterization */
       }
 
       VB->PointSizePtr = &store->PointSize;
@@ -69,13 +73,12 @@ static GLboolean run_point_stage( GLcontext *ctx,
 }
 
 
-
-static GLboolean alloc_point_data( GLcontext *ctx,
-                                  struct tnl_pipeline_stage *stage )
+static GLboolean
+alloc_point_data(GLcontext *ctx, struct tnl_pipeline_stage *stage)
 {
    struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
    struct point_stage_data *store;
-   stage->privatePtr = MALLOC(sizeof(*store));
+   stage->privatePtr = _mesa_malloc(sizeof(*store));
    store = POINT_STAGE_DATA(stage);
    if (!store)
       return GL_FALSE;
@@ -85,16 +88,18 @@ static GLboolean alloc_point_data( GLcontext *ctx,
 }
 
 
-static void free_point_data( struct tnl_pipeline_stage *stage )
+static void
+free_point_data(struct tnl_pipeline_stage *stage)
 {
    struct point_stage_data *store = POINT_STAGE_DATA(stage);
    if (store) {
       _mesa_vector4f_free( &store->PointSize );
-      FREE( store );
+      _mesa_free( store );
       stage->privatePtr = NULL;
    }
 }
 
+
 const struct tnl_pipeline_stage _tnl_point_attenuation_stage =
 {
    "point size attenuation",   /* name */