ss_triangle.c revision 641b2307ec77e70a5b1db75934438d2fbb75613c
1/* $Id: ss_triangle.c,v 1.16 2002/10/02 21:44:08 brianp Exp $ */ 2 3/* 4 * Mesa 3-D graphics library 5 * Version: 3.5 6 * 7 * Copyright (C) 1999-2001 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 * Authors: 27 * Keith Whitwell <keithw@valinux.com> 28 */ 29 30#include "glheader.h" 31#include "colormac.h" 32#include "macros.h" 33#include "mtypes.h" 34 35#include "tnl/t_context.h" 36 37#include "ss_triangle.h" 38#include "ss_context.h" 39 40#define SS_RGBA_BIT 0x1 41#define SS_OFFSET_BIT 0x2 42#define SS_TWOSIDE_BIT 0x4 43#define SS_UNFILLED_BIT 0x8 44#define SS_MAX_TRIFUNC 0x10 45 46static triangle_func tri_tab[SS_MAX_TRIFUNC]; 47static quad_func quad_tab[SS_MAX_TRIFUNC]; 48 49 50static void _swsetup_render_line_tri( GLcontext *ctx, 51 GLuint e0, GLuint e1, GLuint e2 ) 52{ 53 SScontext *swsetup = SWSETUP_CONTEXT(ctx); 54 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; 55 GLubyte *ef = VB->EdgeFlag; 56 SWvertex *verts = swsetup->verts; 57 SWvertex *v0 = &verts[e0]; 58 SWvertex *v1 = &verts[e1]; 59 SWvertex *v2 = &verts[e2]; 60 GLchan c[2][4]; 61 GLchan s[2][4]; 62 GLuint i[2]; 63 64 if (ctx->_TriangleCaps & DD_FLATSHADE) { 65 COPY_CHAN4(c[0], v0->color); 66 COPY_CHAN4(c[1], v1->color); 67 COPY_CHAN4(s[0], v0->specular); 68 COPY_CHAN4(s[1], v1->specular); 69 i[0] = v0->index; 70 i[1] = v1->index; 71 72 COPY_CHAN4(v0->color, v2->color); 73 COPY_CHAN4(v1->color, v2->color); 74 COPY_CHAN4(v0->specular, v2->specular); 75 COPY_CHAN4(v1->specular, v2->specular); 76 v0->index = v2->index; 77 v1->index = v2->index; 78 } 79 80 if (swsetup->render_prim == GL_POLYGON) { 81 if (ef[e2]) _swrast_Line( ctx, v2, v0 ); 82 if (ef[e0]) _swrast_Line( ctx, v0, v1 ); 83 if (ef[e1]) _swrast_Line( ctx, v1, v2 ); 84 } else { 85 if (ef[e0]) _swrast_Line( ctx, v0, v1 ); 86 if (ef[e1]) _swrast_Line( ctx, v1, v2 ); 87 if (ef[e2]) _swrast_Line( ctx, v2, v0 ); 88 } 89 90 if (ctx->_TriangleCaps & DD_FLATSHADE) { 91 COPY_CHAN4(v0->color, c[0]); 92 COPY_CHAN4(v1->color, c[1]); 93 COPY_CHAN4(v0->specular, s[0]); 94 COPY_CHAN4(v1->specular, s[1]); 95 v0->index = i[0]; 96 v1->index = i[1]; 97 } 98} 99 100static void _swsetup_render_point_tri( GLcontext *ctx, 101 GLuint e0, GLuint e1, GLuint e2 ) 102{ 103 SScontext *swsetup = SWSETUP_CONTEXT(ctx); 104 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; 105 GLubyte *ef = VB->EdgeFlag; 106 SWvertex *verts = swsetup->verts; 107 SWvertex *v0 = &verts[e0]; 108 SWvertex *v1 = &verts[e1]; 109 SWvertex *v2 = &verts[e2]; 110 GLchan c[2][4]; 111 GLchan s[2][4]; 112 GLuint i[2]; 113 114 if (ctx->_TriangleCaps & DD_FLATSHADE) { 115 COPY_CHAN4(c[0], v0->color); 116 COPY_CHAN4(c[1], v1->color); 117 COPY_CHAN4(s[0], v0->specular); 118 COPY_CHAN4(s[1], v1->specular); 119 i[0] = v0->index; 120 i[1] = v1->index; 121 122 COPY_CHAN4(v0->color, v2->color); 123 COPY_CHAN4(v1->color, v2->color); 124 COPY_CHAN4(v0->specular, v2->specular); 125 COPY_CHAN4(v1->specular, v2->specular); 126 v0->index = v2->index; 127 v1->index = v2->index; 128 } 129 130 if (ef[e0]) _swrast_Point( ctx, v0 ); 131 if (ef[e1]) _swrast_Point( ctx, v1 ); 132 if (ef[e2]) _swrast_Point( ctx, v2 ); 133 134 if (ctx->_TriangleCaps & DD_FLATSHADE) { 135 COPY_CHAN4(v0->color, c[0]); 136 COPY_CHAN4(v1->color, c[1]); 137 COPY_CHAN4(v0->specular, s[0]); 138 COPY_CHAN4(v1->specular, s[1]); 139 v0->index = i[0]; 140 v1->index = i[1]; 141 } 142} 143 144#define SS_COLOR(a,b) COPY_CHAN4(a,b) 145#define SS_SPEC(a,b) COPY_3V(a,b) 146#define SS_IND(a,b) (a = b) 147 148#define IND (0) 149#define TAG(x) x 150#include "ss_tritmp.h" 151 152#define IND (SS_OFFSET_BIT) 153#define TAG(x) x##_offset 154#include "ss_tritmp.h" 155 156#define IND (SS_TWOSIDE_BIT) 157#define TAG(x) x##_twoside 158#include "ss_tritmp.h" 159 160#define IND (SS_OFFSET_BIT|SS_TWOSIDE_BIT) 161#define TAG(x) x##_offset_twoside 162#include "ss_tritmp.h" 163 164#define IND (SS_UNFILLED_BIT) 165#define TAG(x) x##_unfilled 166#include "ss_tritmp.h" 167 168#define IND (SS_OFFSET_BIT|SS_UNFILLED_BIT) 169#define TAG(x) x##_offset_unfilled 170#include "ss_tritmp.h" 171 172#define IND (SS_TWOSIDE_BIT|SS_UNFILLED_BIT) 173#define TAG(x) x##_twoside_unfilled 174#include "ss_tritmp.h" 175 176#define IND (SS_OFFSET_BIT|SS_TWOSIDE_BIT|SS_UNFILLED_BIT) 177#define TAG(x) x##_offset_twoside_unfilled 178#include "ss_tritmp.h" 179 180#define IND (0|SS_RGBA_BIT) 181#define TAG(x) x##_rgba 182#include "ss_tritmp.h" 183 184#define IND (SS_OFFSET_BIT|SS_RGBA_BIT) 185#define TAG(x) x##_offset_rgba 186#include "ss_tritmp.h" 187 188#define IND (SS_TWOSIDE_BIT|SS_RGBA_BIT) 189#define TAG(x) x##_twoside_rgba 190#include "ss_tritmp.h" 191 192#define IND (SS_OFFSET_BIT|SS_TWOSIDE_BIT|SS_RGBA_BIT) 193#define TAG(x) x##_offset_twoside_rgba 194#include "ss_tritmp.h" 195 196#define IND (SS_UNFILLED_BIT|SS_RGBA_BIT) 197#define TAG(x) x##_unfilled_rgba 198#include "ss_tritmp.h" 199 200#define IND (SS_OFFSET_BIT|SS_UNFILLED_BIT|SS_RGBA_BIT) 201#define TAG(x) x##_offset_unfilled_rgba 202#include "ss_tritmp.h" 203 204#define IND (SS_TWOSIDE_BIT|SS_UNFILLED_BIT|SS_RGBA_BIT) 205#define TAG(x) x##_twoside_unfilled_rgba 206#include "ss_tritmp.h" 207 208#define IND (SS_OFFSET_BIT|SS_TWOSIDE_BIT|SS_UNFILLED_BIT|SS_RGBA_BIT) 209#define TAG(x) x##_offset_twoside_unfilled_rgba 210#include "ss_tritmp.h" 211 212 213void _swsetup_trifuncs_init( GLcontext *ctx ) 214{ 215 (void) ctx; 216 217 init(); 218 init_offset(); 219 init_twoside(); 220 init_offset_twoside(); 221 init_unfilled(); 222 init_offset_unfilled(); 223 init_twoside_unfilled(); 224 init_offset_twoside_unfilled(); 225 226 init_rgba(); 227 init_offset_rgba(); 228 init_twoside_rgba(); 229 init_offset_twoside_rgba(); 230 init_unfilled_rgba(); 231 init_offset_unfilled_rgba(); 232 init_twoside_unfilled_rgba(); 233 init_offset_twoside_unfilled_rgba(); 234} 235 236 237static void swsetup_points( GLcontext *ctx, GLuint first, GLuint last ) 238{ 239 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; 240 SWvertex *verts = SWSETUP_CONTEXT(ctx)->verts; 241 GLuint i; 242 243 if (VB->Elts) { 244 for (i = first; i < last; i++) 245 if (VB->ClipMask[VB->Elts[i]] == 0) 246 _swrast_Point( ctx, &verts[VB->Elts[i]] ); 247 } 248 else { 249 for (i = first; i < last; i++) 250 if (VB->ClipMask[i] == 0) 251 _swrast_Point( ctx, &verts[i] ); 252 } 253} 254 255static void swsetup_line( GLcontext *ctx, GLuint v0, GLuint v1 ) 256{ 257 SWvertex *verts = SWSETUP_CONTEXT(ctx)->verts; 258 _swrast_Line( ctx, &verts[v0], &verts[v1] ); 259} 260 261 262 263void _swsetup_choose_trifuncs( GLcontext *ctx ) 264{ 265 TNLcontext *tnl = TNL_CONTEXT(ctx); 266 GLuint ind = 0; 267 268 if (ctx->Polygon.OffsetPoint || 269 ctx->Polygon.OffsetLine || 270 ctx->Polygon.OffsetFill) 271 ind |= SS_OFFSET_BIT; 272 273 if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) 274 ind |= SS_TWOSIDE_BIT; 275 276 if (ctx->_TriangleCaps & DD_TRI_UNFILLED) 277 ind |= SS_UNFILLED_BIT; 278 279 if (ctx->Visual.rgbMode) 280 ind |= SS_RGBA_BIT; 281 282 tnl->Driver.Render.Triangle = tri_tab[ind]; 283 tnl->Driver.Render.Quad = quad_tab[ind]; 284 tnl->Driver.Render.Line = swsetup_line; 285 tnl->Driver.Render.Points = swsetup_points; 286} 287