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