Home | History | Annotate | Download | only in swrast_setup
      1 /*
      2  * Mesa 3-D graphics library
      3  * Version:  7.1
      4  *
      5  * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
      6  *
      7  * Permission is hereby granted, free of charge, to any person obtaining a
      8  * copy of this software and associated documentation files (the "Software"),
      9  * to deal in the Software without restriction, including without limitation
     10  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     11  * and/or sell copies of the Software, and to permit persons to whom the
     12  * Software is furnished to do so, subject to the following conditions:
     13  *
     14  * The above copyright notice and this permission notice shall be included
     15  * in all copies or substantial portions of the Software.
     16  *
     17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     20  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
     21  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     23  *
     24  * Authors:
     25  *    Keith Whitwell <keith (at) tungstengraphics.com>
     26  */
     27 
     28 #include "main/glheader.h"
     29 #include "main/colormac.h"
     30 #include "main/macros.h"
     31 #include "main/mtypes.h"
     32 
     33 #include "tnl/t_context.h"
     34 
     35 #include "ss_triangle.h"
     36 #include "ss_context.h"
     37 
     38 #define SS_OFFSET_BIT	    0x1
     39 #define SS_TWOSIDE_BIT	    0x2
     40 #define SS_UNFILLED_BIT	    0x4
     41 #define SS_MAX_TRIFUNC      0x8
     42 
     43 static tnl_triangle_func tri_tab[SS_MAX_TRIFUNC];
     44 static tnl_quad_func     quad_tab[SS_MAX_TRIFUNC];
     45 
     46 
     47 /*
     48  * Render a triangle respecting edge flags.
     49  */
     50 typedef void (* swsetup_edge_render_prim_tri)(struct gl_context *ctx,
     51                                               const GLubyte *ef,
     52                                               GLuint e0,
     53                                               GLuint e1,
     54                                               GLuint e2,
     55                                               const SWvertex *v0,
     56                                               const SWvertex *v1,
     57                                               const SWvertex *v2);
     58 
     59 /*
     60  * Render a triangle using lines and respecting edge flags.
     61  */
     62 static void
     63 _swsetup_edge_render_line_tri(struct gl_context *ctx,
     64                               const GLubyte *ef,
     65                               GLuint e0,
     66                               GLuint e1,
     67                               GLuint e2,
     68                               const SWvertex *v0,
     69                               const SWvertex *v1,
     70                               const SWvertex *v2)
     71 {
     72    SScontext *swsetup = SWSETUP_CONTEXT(ctx);
     73 
     74    if (swsetup->render_prim == GL_POLYGON) {
     75       if (ef[e2]) _swrast_Line( ctx, v2, v0 );
     76       if (ef[e0]) _swrast_Line( ctx, v0, v1 );
     77       if (ef[e1]) _swrast_Line( ctx, v1, v2 );
     78    } else {
     79       if (ef[e0]) _swrast_Line( ctx, v0, v1 );
     80       if (ef[e1]) _swrast_Line( ctx, v1, v2 );
     81       if (ef[e2]) _swrast_Line( ctx, v2, v0 );
     82    }
     83 }
     84 
     85 /*
     86  * Render a triangle using points and respecting edge flags.
     87  */
     88 static void
     89 _swsetup_edge_render_point_tri(struct gl_context *ctx,
     90                                const GLubyte *ef,
     91                                GLuint e0,
     92                                GLuint e1,
     93                                GLuint e2,
     94                                const SWvertex *v0,
     95                                const SWvertex *v1,
     96                                const SWvertex *v2)
     97 {
     98    if (ef[e0]) _swrast_Point( ctx, v0 );
     99    if (ef[e1]) _swrast_Point( ctx, v1 );
    100    if (ef[e2]) _swrast_Point( ctx, v2 );
    101 
    102    _swrast_flush(ctx);
    103 }
    104 
    105 /*
    106  * Render a triangle respecting cull and shade model.
    107  */
    108 static void _swsetup_render_tri(struct gl_context *ctx,
    109                                 GLuint e0,
    110                                 GLuint e1,
    111                                 GLuint e2,
    112                                 GLuint facing,
    113                                 swsetup_edge_render_prim_tri render)
    114 {
    115    SScontext *swsetup = SWSETUP_CONTEXT(ctx);
    116    struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
    117    GLubyte *ef = VB->EdgeFlag;
    118    SWvertex *verts = swsetup->verts;
    119    SWvertex *v0 = &verts[e0];
    120    SWvertex *v1 = &verts[e1];
    121    SWvertex *v2 = &verts[e2];
    122 
    123    /* cull testing */
    124    if (ctx->Polygon.CullFlag) {
    125       if (facing == 1 && ctx->Polygon.CullFaceMode != GL_FRONT)
    126          return;
    127       if (facing == 0 && ctx->Polygon.CullFaceMode != GL_BACK)
    128          return;
    129    }
    130 
    131    _swrast_SetFacing(ctx, facing);
    132 
    133    if (ctx->Light.ShadeModel == GL_FLAT) {
    134       GLchan c[2][4];
    135       GLfloat s[2][4];
    136 
    137       /* save colors/indexes for v0, v1 vertices */
    138       COPY_CHAN4(c[0], v0->color);
    139       COPY_CHAN4(c[1], v1->color);
    140       COPY_4V(s[0], v0->attrib[FRAG_ATTRIB_COL1]);
    141       COPY_4V(s[1], v1->attrib[FRAG_ATTRIB_COL1]);
    142 
    143       /* copy v2 color/indexes to v0, v1 indexes */
    144       COPY_CHAN4(v0->color, v2->color);
    145       COPY_CHAN4(v1->color, v2->color);
    146       COPY_4V(v0->attrib[FRAG_ATTRIB_COL1], v2->attrib[FRAG_ATTRIB_COL1]);
    147       COPY_4V(v1->attrib[FRAG_ATTRIB_COL1], v2->attrib[FRAG_ATTRIB_COL1]);
    148 
    149       render(ctx, ef, e0, e1, e2, v0, v1, v2);
    150 
    151       COPY_CHAN4(v0->color, c[0]);
    152       COPY_CHAN4(v1->color, c[1]);
    153       COPY_4V(v0->attrib[FRAG_ATTRIB_COL1], s[0]);
    154       COPY_4V(v1->attrib[FRAG_ATTRIB_COL1], s[1]);
    155    }
    156    else {
    157       render(ctx, ef, e0, e1, e2, v0, v1, v2);
    158    }
    159 }
    160 
    161 #define SS_COLOR(a,b) UNCLAMPED_FLOAT_TO_RGBA_CHAN(a,b)
    162 #define SS_SPEC(a,b) COPY_4V(a,b)
    163 #define SS_IND(a,b) (a = b)
    164 
    165 #define IND (0)
    166 #define TAG(x) x##_rgba
    167 #include "ss_tritmp.h"
    168 
    169 #define IND (SS_OFFSET_BIT)
    170 #define TAG(x) x##_offset_rgba
    171 #include "ss_tritmp.h"
    172 
    173 #define IND (SS_TWOSIDE_BIT)
    174 #define TAG(x) x##_twoside_rgba
    175 #include "ss_tritmp.h"
    176 
    177 #define IND (SS_OFFSET_BIT|SS_TWOSIDE_BIT)
    178 #define TAG(x) x##_offset_twoside_rgba
    179 #include "ss_tritmp.h"
    180 
    181 #define IND (SS_UNFILLED_BIT)
    182 #define TAG(x) x##_unfilled_rgba
    183 #include "ss_tritmp.h"
    184 
    185 #define IND (SS_OFFSET_BIT|SS_UNFILLED_BIT)
    186 #define TAG(x) x##_offset_unfilled_rgba
    187 #include "ss_tritmp.h"
    188 
    189 #define IND (SS_TWOSIDE_BIT|SS_UNFILLED_BIT)
    190 #define TAG(x) x##_twoside_unfilled_rgba
    191 #include "ss_tritmp.h"
    192 
    193 #define IND (SS_OFFSET_BIT|SS_TWOSIDE_BIT|SS_UNFILLED_BIT)
    194 #define TAG(x) x##_offset_twoside_unfilled_rgba
    195 #include "ss_tritmp.h"
    196 
    197 
    198 void _swsetup_trifuncs_init( struct gl_context *ctx )
    199 {
    200    (void) ctx;
    201 
    202    init_rgba();
    203    init_offset_rgba();
    204    init_twoside_rgba();
    205    init_offset_twoside_rgba();
    206    init_unfilled_rgba();
    207    init_offset_unfilled_rgba();
    208    init_twoside_unfilled_rgba();
    209    init_offset_twoside_unfilled_rgba();
    210 }
    211 
    212 
    213 static void swsetup_points( struct gl_context *ctx, GLuint first, GLuint last )
    214 {
    215    struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
    216    SWvertex *verts = SWSETUP_CONTEXT(ctx)->verts;
    217    GLuint i;
    218 
    219    if (VB->Elts) {
    220       for (i = first; i < last; i++)
    221 	 if (VB->ClipMask[VB->Elts[i]] == 0)
    222 	    _swrast_Point( ctx, &verts[VB->Elts[i]] );
    223    }
    224    else {
    225       for (i = first; i < last; i++)
    226 	 if (VB->ClipMask[i] == 0)
    227 	    _swrast_Point( ctx, &verts[i] );
    228    }
    229 }
    230 
    231 static void swsetup_line( struct gl_context *ctx, GLuint v0, GLuint v1 )
    232 {
    233    SWvertex *verts = SWSETUP_CONTEXT(ctx)->verts;
    234    _swrast_Line( ctx, &verts[v0], &verts[v1] );
    235 }
    236 
    237 
    238 
    239 void _swsetup_choose_trifuncs( struct gl_context *ctx )
    240 {
    241    TNLcontext *tnl = TNL_CONTEXT(ctx);
    242    GLuint ind = 0;
    243 
    244    if (ctx->Polygon.OffsetPoint ||
    245        ctx->Polygon.OffsetLine ||
    246        ctx->Polygon.OffsetFill)
    247       ind |= SS_OFFSET_BIT;
    248 
    249    if ((ctx->Light.Enabled && ctx->Light.Model.TwoSide) ||
    250        (ctx->VertexProgram._Current && ctx->VertexProgram.TwoSideEnabled))
    251       ind |= SS_TWOSIDE_BIT;
    252 
    253    /* We piggyback the two-sided stencil front/back determination on the
    254     * unfilled triangle path.
    255     */
    256    if (ctx->Polygon.FrontMode != GL_FILL ||
    257        ctx->Polygon.BackMode != GL_FILL ||
    258        (ctx->Stencil.Enabled && ctx->Stencil._TestTwoSide))
    259       ind |= SS_UNFILLED_BIT;
    260 
    261    tnl->Driver.Render.Triangle = tri_tab[ind];
    262    tnl->Driver.Render.Quad = quad_tab[ind];
    263    tnl->Driver.Render.Line = swsetup_line;
    264    tnl->Driver.Render.Points = swsetup_points;
    265 }
    266