Home | History | Annotate | Download | only in tnl
      1 /*
      2  * Mesa 3-D graphics library
      3  *
      4  * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the "Software"),
      8  * to deal in the Software without restriction, including without limitation
      9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     10  * and/or sell copies of the Software, and to permit persons to whom the
     11  * Software is furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice shall be included
     14  * in all copies or substantial portions of the Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
     20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     22  * OTHER DEALINGS IN THE SOFTWARE.
     23  *
     24  * Authors:
     25  *    Brian Paul
     26  */
     27 
     28 #include "c99_math.h"
     29 #include "main/glheader.h"
     30 #include "main/mtypes.h"
     31 #include "main/dd.h"
     32 #include "main/imports.h"
     33 #include "t_context.h"
     34 #include "t_pipeline.h"
     35 
     36 
     37 struct point_stage_data {
     38    GLvector4f PointSize;
     39 };
     40 
     41 #define POINT_STAGE_DATA(stage) ((struct point_stage_data *)stage->privatePtr)
     42 
     43 
     44 /**
     45  * Compute point size for each vertex from the vertex eye-space Z
     46  * coordinate and the point size attenuation factors.
     47  * Only done when point size attenuation is enabled and vertex program is
     48  * disabled.
     49  */
     50 static GLboolean
     51 run_point_stage(struct gl_context *ctx, struct tnl_pipeline_stage *stage)
     52 {
     53    if (ctx->Point._Attenuated && !ctx->VertexProgram._Current) {
     54       struct point_stage_data *store = POINT_STAGE_DATA(stage);
     55       struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
     56       const GLfloat *eyeCoord = (GLfloat *) VB->EyePtr->data + 2;
     57       const GLint eyeCoordStride = VB->EyePtr->stride / sizeof(GLfloat);
     58       const GLfloat p0 = ctx->Point.Params[0];
     59       const GLfloat p1 = ctx->Point.Params[1];
     60       const GLfloat p2 = ctx->Point.Params[2];
     61       const GLfloat pointSize = ctx->Point.Size;
     62       GLfloat (*size)[4] = store->PointSize.data;
     63       GLuint i;
     64 
     65       for (i = 0; i < VB->Count; i++) {
     66          const GLfloat dist = fabsf(*eyeCoord);
     67          const GLfloat q = p0 + dist * (p1 + dist * p2);
     68          const GLfloat atten = (q != 0.0F) ? (1.0f / sqrtf(q)) : 1.0F;
     69          size[i][0] = pointSize * atten; /* clamping done in rasterization */
     70          eyeCoord += eyeCoordStride;
     71       }
     72 
     73       VB->AttribPtr[_TNL_ATTRIB_POINTSIZE] = &store->PointSize;
     74    }
     75 
     76    return GL_TRUE;
     77 }
     78 
     79 
     80 static GLboolean
     81 alloc_point_data(struct gl_context *ctx, struct tnl_pipeline_stage *stage)
     82 {
     83    struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
     84    struct point_stage_data *store;
     85    stage->privatePtr = malloc(sizeof(*store));
     86    store = POINT_STAGE_DATA(stage);
     87    if (!store)
     88       return GL_FALSE;
     89 
     90    _mesa_vector4f_alloc( &store->PointSize, 0, VB->Size, 32 );
     91    return GL_TRUE;
     92 }
     93 
     94 
     95 static void
     96 free_point_data(struct tnl_pipeline_stage *stage)
     97 {
     98    struct point_stage_data *store = POINT_STAGE_DATA(stage);
     99    if (store) {
    100       _mesa_vector4f_free( &store->PointSize );
    101       free( store );
    102       stage->privatePtr = NULL;
    103    }
    104 }
    105 
    106 
    107 const struct tnl_pipeline_stage _tnl_point_attenuation_stage =
    108 {
    109    "point size attenuation",	/* name */
    110    NULL,			/* stage private data */
    111    alloc_point_data,		/* alloc data */
    112    free_point_data,		/* destructor */
    113    NULL,
    114    run_point_stage		/* run */
    115 };
    116