1 /* 2 * Mesa 3-D graphics library 3 * 4 * Copyright (C) 1999-2005 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 * Keith Whitwell <keithw (at) vmware.com> 26 */ 27 28 29 /* Template for building functions to plug into the driver interface 30 * of t_vb_render.c: 31 * ctx->Driver.QuadFunc 32 * ctx->Driver.TriangleFunc 33 * ctx->Driver.LineFunc 34 * ctx->Driver.PointsFunc 35 * 36 * DO_TWOSIDE: Plug back-color values from the VB into backfacing triangles, 37 * and restore vertices afterwards. 38 * DO_OFFSET: Calculate offset for triangles and adjust vertices. Restore 39 * vertices after rendering. 40 * DO_FLAT: For hardware without native flatshading, copy provoking colors 41 * into the other vertices. Restore after rendering. 42 * DO_UNFILLED: Decompose triangles to lines and points where appropriate. 43 * DO_TWOSTENCIL:Gross hack for two-sided stencil. 44 * 45 * HAVE_SPEC: Vertices have secondary rgba values. 46 * 47 * VERT_X(v): Alias for vertex x value. 48 * VERT_Y(v): Alias for vertex y value. 49 * VERT_Z(v): Alias for vertex z value. 50 * DEPTH_SCALE: Scale for constant offset. 51 * REVERSE_DEPTH: Viewport depth range reversed. 52 * 53 * VERTEX: Hardware vertex type. 54 * GET_VERTEX(n): Retreive vertex with index n. 55 * AREA_IS_CCW(a): Return true if triangle with signed area a is ccw. 56 * 57 * VERT_SET_RGBA: Assign vertex rgba from VB color. 58 * VERT_COPY_RGBA: Copy vertex rgba another vertex. 59 * VERT_SAVE_RGBA: Save vertex rgba to a local variable. 60 * VERT_RESTORE_RGBA: Restore vertex rgba from a local variable. 61 * --> Similar for SPEC. 62 * 63 * LOCAL_VARS(n): (At least) define local vars for save/restore rgba. 64 * 65 */ 66 67 #if HAVE_BACK_COLORS 68 #define VERT_SET_RGBA( v, c ) 69 #endif 70 71 #if !HAVE_SPEC 72 #define VERT_SET_SPEC( v, c ) (void) c 73 #define VERT_COPY_SPEC( v0, v1 ) 74 #define VERT_SAVE_SPEC( idx ) 75 #define VERT_RESTORE_SPEC( idx ) 76 #if HAVE_BACK_COLORS 77 #define VERT_COPY_SPEC1( v ) 78 #endif 79 #else 80 #if HAVE_BACK_COLORS 81 #define VERT_SET_SPEC( v, c ) 82 #endif 83 #endif 84 85 #if !HAVE_BACK_COLORS 86 #define VERT_COPY_SPEC1( v ) 87 #define VERT_COPY_RGBA1( v ) 88 #endif 89 90 #ifndef INSANE_VERTICES 91 #define VERT_SET_Z(v,val) VERT_Z(v) = val 92 #define VERT_Z_ADD(v,val) VERT_Z(v) += val 93 #endif 94 95 #ifndef REVERSE_DEPTH 96 #define REVERSE_DEPTH 0 97 #endif 98 99 /* disable twostencil for un-aware drivers */ 100 #ifndef HAVE_STENCIL_TWOSIDE 101 #define HAVE_STENCIL_TWOSIDE 0 102 #endif 103 #ifndef DO_TWOSTENCIL 104 #define DO_TWOSTENCIL 0 105 #endif 106 #ifndef SETUP_STENCIL 107 #define SETUP_STENCIL(f) 108 #endif 109 #ifndef UNSET_STENCIL 110 #define UNSET_STENCIL(f) 111 #endif 112 113 #if DO_TRI 114 static void TAG(triangle)( struct gl_context *ctx, GLuint e0, GLuint e1, GLuint e2 ) 115 { 116 struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb; 117 VERTEX *v[3]; 118 GLfloat offset = 0; 119 GLfloat z[3] = { 0 }; 120 GLenum mode = GL_FILL; 121 GLuint facing = 0; 122 LOCAL_VARS(3); 123 124 /* fprintf(stderr, "%s\n", __func__); */ 125 126 v[0] = (VERTEX *)GET_VERTEX(e0); 127 v[1] = (VERTEX *)GET_VERTEX(e1); 128 v[2] = (VERTEX *)GET_VERTEX(e2); 129 130 if (DO_TWOSIDE || DO_OFFSET || DO_UNFILLED || DO_TWOSTENCIL) 131 { 132 GLfloat ex = VERT_X(v[0]) - VERT_X(v[2]); 133 GLfloat ey = VERT_Y(v[0]) - VERT_Y(v[2]); 134 GLfloat fx = VERT_X(v[1]) - VERT_X(v[2]); 135 GLfloat fy = VERT_Y(v[1]) - VERT_Y(v[2]); 136 GLfloat cc = ex*fy - ey*fx; 137 138 if (DO_TWOSIDE || DO_UNFILLED || DO_TWOSTENCIL) 139 { 140 facing = AREA_IS_CCW( cc ) ^ _mesa_polygon_get_front_bit(ctx); 141 142 if (DO_UNFILLED) { 143 if (facing) { 144 mode = ctx->Polygon.BackMode; 145 if (ctx->Polygon.CullFlag && 146 ctx->Polygon.CullFaceMode != GL_FRONT) { 147 return; 148 } 149 } else { 150 mode = ctx->Polygon.FrontMode; 151 if (ctx->Polygon.CullFlag && 152 ctx->Polygon.CullFaceMode != GL_BACK) { 153 return; 154 } 155 } 156 } 157 158 if (DO_TWOSIDE && facing == 1) { 159 if (HAVE_BACK_COLORS) { 160 if (!DO_FLAT) { 161 VERT_SAVE_RGBA( 0 ); 162 VERT_SAVE_RGBA( 1 ); 163 VERT_COPY_RGBA1( v[0] ); 164 VERT_COPY_RGBA1( v[1] ); 165 } 166 VERT_SAVE_RGBA( 2 ); 167 VERT_COPY_RGBA1( v[2] ); 168 if (HAVE_SPEC) { 169 if (!DO_FLAT) { 170 VERT_SAVE_SPEC( 0 ); 171 VERT_SAVE_SPEC( 1 ); 172 VERT_COPY_SPEC1( v[0] ); 173 VERT_COPY_SPEC1( v[1] ); 174 } 175 VERT_SAVE_SPEC( 2 ); 176 VERT_COPY_SPEC1( v[2] ); 177 } 178 } 179 else { 180 GLfloat (*vbcolor)[4] = VB->BackfaceColorPtr->data; 181 (void) vbcolor; 182 183 if (!DO_FLAT) { 184 VERT_SAVE_RGBA( 0 ); 185 VERT_SAVE_RGBA( 1 ); 186 } 187 VERT_SAVE_RGBA( 2 ); 188 189 if (VB->BackfaceColorPtr->stride) { 190 assert(VB->BackfaceColorPtr->stride == 4*sizeof(GLfloat)); 191 192 if (!DO_FLAT) { 193 VERT_SET_RGBA( v[0], vbcolor[e0] ); 194 VERT_SET_RGBA( v[1], vbcolor[e1] ); 195 } 196 VERT_SET_RGBA( v[2], vbcolor[e2] ); 197 } 198 else { 199 if (!DO_FLAT) { 200 VERT_SET_RGBA( v[0], vbcolor[0] ); 201 VERT_SET_RGBA( v[1], vbcolor[0] ); 202 } 203 VERT_SET_RGBA( v[2], vbcolor[0] ); 204 } 205 206 if (HAVE_SPEC && VB->BackfaceSecondaryColorPtr) { 207 GLfloat (*vbspec)[4] = VB->BackfaceSecondaryColorPtr->data; 208 assert(VB->BackfaceSecondaryColorPtr->stride == 4*sizeof(GLfloat)); 209 210 if (!DO_FLAT) { 211 VERT_SAVE_SPEC( 0 ); 212 VERT_SAVE_SPEC( 1 ); 213 VERT_SET_SPEC( v[0], vbspec[e0] ); 214 VERT_SET_SPEC( v[1], vbspec[e1] ); 215 } 216 VERT_SAVE_SPEC( 2 ); 217 VERT_SET_SPEC( v[2], vbspec[e2] ); 218 } 219 } 220 } 221 } 222 223 224 if (DO_OFFSET) 225 { 226 offset = ctx->Polygon.OffsetUnits * DEPTH_SCALE; 227 z[0] = VERT_Z(v[0]); 228 z[1] = VERT_Z(v[1]); 229 z[2] = VERT_Z(v[2]); 230 if (cc * cc > 1e-16) { 231 GLfloat ic = 1.0 / cc; 232 GLfloat ez = z[0] - z[2]; 233 GLfloat fz = z[1] - z[2]; 234 GLfloat a = ey*fz - ez*fy; 235 GLfloat b = ez*fx - ex*fz; 236 GLfloat ac = a * ic; 237 GLfloat bc = b * ic; 238 if ( ac < 0.0f ) ac = -ac; 239 if ( bc < 0.0f ) bc = -bc; 240 offset += MAX2( ac, bc ) * ctx->Polygon.OffsetFactor / ctx->DrawBuffer->_MRD; 241 } 242 offset *= ctx->DrawBuffer->_MRD * (REVERSE_DEPTH ? -1.0 : 1.0); 243 } 244 } 245 246 if (DO_FLAT) { 247 VERT_SAVE_RGBA( 0 ); 248 VERT_SAVE_RGBA( 1 ); 249 VERT_COPY_RGBA( v[0], v[2] ); 250 VERT_COPY_RGBA( v[1], v[2] ); 251 if (HAVE_SPEC && VB->AttribPtr[_TNL_ATTRIB_COLOR1]) { 252 VERT_SAVE_SPEC( 0 ); 253 VERT_SAVE_SPEC( 1 ); 254 VERT_COPY_SPEC( v[0], v[2] ); 255 VERT_COPY_SPEC( v[1], v[2] ); 256 } 257 } 258 259 if (mode == GL_POINT) { 260 if (DO_OFFSET && ctx->Polygon.OffsetPoint) { 261 VERT_Z_ADD(v[0], offset); 262 VERT_Z_ADD(v[1], offset); 263 VERT_Z_ADD(v[2], offset); 264 } 265 if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) { 266 SETUP_STENCIL(facing); 267 UNFILLED_TRI( ctx, GL_POINT, e0, e1, e2 ); 268 UNSET_STENCIL(facing); 269 } else { 270 UNFILLED_TRI( ctx, GL_POINT, e0, e1, e2 ); 271 } 272 } else if (mode == GL_LINE) { 273 if (DO_OFFSET && ctx->Polygon.OffsetLine) { 274 VERT_Z_ADD(v[0], offset); 275 VERT_Z_ADD(v[1], offset); 276 VERT_Z_ADD(v[2], offset); 277 } 278 if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) { 279 SETUP_STENCIL(facing); 280 UNFILLED_TRI( ctx, GL_LINE, e0, e1, e2 ); 281 UNSET_STENCIL(facing); 282 } else { 283 UNFILLED_TRI( ctx, GL_LINE, e0, e1, e2 ); 284 } 285 } else { 286 if (DO_OFFSET && ctx->Polygon.OffsetFill) { 287 VERT_Z_ADD(v[0], offset); 288 VERT_Z_ADD(v[1], offset); 289 VERT_Z_ADD(v[2], offset); 290 } 291 if (DO_UNFILLED) { 292 RASTERIZE( GL_TRIANGLES ); 293 } 294 if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) { 295 SETUP_STENCIL(facing); 296 TRI( v[0], v[1], v[2] ); 297 UNSET_STENCIL(facing); 298 } else { 299 TRI( v[0], v[1], v[2] ); 300 } 301 } 302 303 if (DO_OFFSET) 304 { 305 VERT_SET_Z(v[0], z[0]); 306 VERT_SET_Z(v[1], z[1]); 307 VERT_SET_Z(v[2], z[2]); 308 } 309 310 if (DO_TWOSIDE && facing == 1) { 311 if (!DO_FLAT) { 312 VERT_RESTORE_RGBA( 0 ); 313 VERT_RESTORE_RGBA( 1 ); 314 } 315 VERT_RESTORE_RGBA( 2 ); 316 if (HAVE_SPEC) { 317 if (!DO_FLAT) { 318 VERT_RESTORE_SPEC( 0 ); 319 VERT_RESTORE_SPEC( 1 ); 320 } 321 VERT_RESTORE_SPEC( 2 ); 322 } 323 } 324 325 326 if (DO_FLAT) { 327 VERT_RESTORE_RGBA( 0 ); 328 VERT_RESTORE_RGBA( 1 ); 329 if (HAVE_SPEC && VB->AttribPtr[_TNL_ATTRIB_COLOR1]) { 330 VERT_RESTORE_SPEC( 0 ); 331 VERT_RESTORE_SPEC( 1 ); 332 } 333 } 334 } 335 #endif 336 337 #if DO_QUAD 338 #if DO_FULL_QUAD 339 static void TAG(quadr)( struct gl_context *ctx, 340 GLuint e0, GLuint e1, GLuint e2, GLuint e3 ) 341 { 342 struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb; 343 VERTEX *v[4]; 344 GLfloat offset = 0; 345 GLfloat z[4] = { 0 }; 346 GLenum mode = GL_FILL; 347 GLuint facing = 0; 348 LOCAL_VARS(4); 349 350 v[0] = (VERTEX *)GET_VERTEX(e0); 351 v[1] = (VERTEX *)GET_VERTEX(e1); 352 v[2] = (VERTEX *)GET_VERTEX(e2); 353 v[3] = (VERTEX *)GET_VERTEX(e3); 354 355 if (DO_TWOSIDE || DO_OFFSET || DO_UNFILLED || DO_TWOSTENCIL) 356 { 357 GLfloat ex = VERT_X(v[2]) - VERT_X(v[0]); 358 GLfloat ey = VERT_Y(v[2]) - VERT_Y(v[0]); 359 GLfloat fx = VERT_X(v[3]) - VERT_X(v[1]); 360 GLfloat fy = VERT_Y(v[3]) - VERT_Y(v[1]); 361 GLfloat cc = ex*fy - ey*fx; 362 363 if (DO_TWOSIDE || DO_UNFILLED || DO_TWOSTENCIL) 364 { 365 facing = AREA_IS_CCW( cc ) ^ _mesa_polygon_get_front_bit(ctx); 366 367 if (DO_UNFILLED) { 368 if (facing) { 369 mode = ctx->Polygon.BackMode; 370 if (ctx->Polygon.CullFlag && 371 ctx->Polygon.CullFaceMode != GL_FRONT) { 372 return; 373 } 374 } else { 375 mode = ctx->Polygon.FrontMode; 376 if (ctx->Polygon.CullFlag && 377 ctx->Polygon.CullFaceMode != GL_BACK) { 378 return; 379 } 380 } 381 } 382 383 if (DO_TWOSIDE && facing == 1) { 384 GLfloat (*vbcolor)[4] = VB->BackfaceColorPtr->data; 385 (void)vbcolor; 386 387 if (HAVE_BACK_COLORS) { 388 if (!DO_FLAT) { 389 VERT_SAVE_RGBA( 0 ); 390 VERT_SAVE_RGBA( 1 ); 391 VERT_SAVE_RGBA( 2 ); 392 VERT_COPY_RGBA1( v[0] ); 393 VERT_COPY_RGBA1( v[1] ); 394 VERT_COPY_RGBA1( v[2] ); 395 } 396 VERT_SAVE_RGBA( 3 ); 397 VERT_COPY_RGBA1( v[3] ); 398 if (HAVE_SPEC) { 399 if (!DO_FLAT) { 400 VERT_SAVE_SPEC( 0 ); 401 VERT_SAVE_SPEC( 1 ); 402 VERT_SAVE_SPEC( 2 ); 403 VERT_COPY_SPEC1( v[0] ); 404 VERT_COPY_SPEC1( v[1] ); 405 VERT_COPY_SPEC1( v[2] ); 406 } 407 VERT_SAVE_SPEC( 3 ); 408 VERT_COPY_SPEC1( v[3] ); 409 } 410 } 411 else { 412 if (!DO_FLAT) { 413 VERT_SAVE_RGBA( 0 ); 414 VERT_SAVE_RGBA( 1 ); 415 VERT_SAVE_RGBA( 2 ); 416 } 417 VERT_SAVE_RGBA( 3 ); 418 419 if (VB->BackfaceColorPtr->stride) { 420 if (!DO_FLAT) { 421 VERT_SET_RGBA( v[0], vbcolor[e0] ); 422 VERT_SET_RGBA( v[1], vbcolor[e1] ); 423 VERT_SET_RGBA( v[2], vbcolor[e2] ); 424 } 425 VERT_SET_RGBA( v[3], vbcolor[e3] ); 426 } 427 else { 428 if (!DO_FLAT) { 429 VERT_SET_RGBA( v[0], vbcolor[0] ); 430 VERT_SET_RGBA( v[1], vbcolor[0] ); 431 VERT_SET_RGBA( v[2], vbcolor[0] ); 432 } 433 VERT_SET_RGBA( v[3], vbcolor[0] ); 434 } 435 436 if (HAVE_SPEC && VB->BackfaceSecondaryColorPtr) { 437 GLfloat (*vbspec)[4] = VB->BackfaceSecondaryColorPtr->data; 438 assert(VB->BackfaceSecondaryColorPtr->stride==4*sizeof(GLfloat)); 439 440 if (!DO_FLAT) { 441 VERT_SAVE_SPEC( 0 ); 442 VERT_SAVE_SPEC( 1 ); 443 VERT_SAVE_SPEC( 2 ); 444 VERT_SET_SPEC( v[0], vbspec[e0] ); 445 VERT_SET_SPEC( v[1], vbspec[e1] ); 446 VERT_SET_SPEC( v[2], vbspec[e2] ); 447 } 448 VERT_SAVE_SPEC( 3 ); 449 VERT_SET_SPEC( v[3], vbspec[e3] ); 450 } 451 } 452 } 453 } 454 455 456 if (DO_OFFSET) 457 { 458 offset = ctx->Polygon.OffsetUnits * DEPTH_SCALE; 459 z[0] = VERT_Z(v[0]); 460 z[1] = VERT_Z(v[1]); 461 z[2] = VERT_Z(v[2]); 462 z[3] = VERT_Z(v[3]); 463 if (cc * cc > 1e-16) { 464 GLfloat ez = z[2] - z[0]; 465 GLfloat fz = z[3] - z[1]; 466 GLfloat a = ey*fz - ez*fy; 467 GLfloat b = ez*fx - ex*fz; 468 GLfloat ic = 1.0 / cc; 469 GLfloat ac = a * ic; 470 GLfloat bc = b * ic; 471 if ( ac < 0.0f ) ac = -ac; 472 if ( bc < 0.0f ) bc = -bc; 473 offset += MAX2( ac, bc ) * ctx->Polygon.OffsetFactor / ctx->DrawBuffer->_MRD; 474 } 475 offset *= ctx->DrawBuffer->_MRD * (REVERSE_DEPTH ? -1.0 : 1.0); 476 } 477 } 478 479 if (DO_FLAT) { 480 VERT_SAVE_RGBA( 0 ); 481 VERT_SAVE_RGBA( 1 ); 482 VERT_SAVE_RGBA( 2 ); 483 VERT_COPY_RGBA( v[0], v[3] ); 484 VERT_COPY_RGBA( v[1], v[3] ); 485 VERT_COPY_RGBA( v[2], v[3] ); 486 if (HAVE_SPEC && VB->AttribPtr[_TNL_ATTRIB_COLOR1]) { 487 VERT_SAVE_SPEC( 0 ); 488 VERT_SAVE_SPEC( 1 ); 489 VERT_SAVE_SPEC( 2 ); 490 VERT_COPY_SPEC( v[0], v[3] ); 491 VERT_COPY_SPEC( v[1], v[3] ); 492 VERT_COPY_SPEC( v[2], v[3] ); 493 } 494 } 495 496 if (mode == GL_POINT) { 497 if (( DO_OFFSET) && ctx->Polygon.OffsetPoint) { 498 VERT_Z_ADD(v[0], offset); 499 VERT_Z_ADD(v[1], offset); 500 VERT_Z_ADD(v[2], offset); 501 VERT_Z_ADD(v[3], offset); 502 } 503 if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) { 504 SETUP_STENCIL(facing); 505 UNFILLED_QUAD( ctx, GL_POINT, e0, e1, e2, e3 ); 506 UNSET_STENCIL(facing); 507 } else { 508 UNFILLED_QUAD( ctx, GL_POINT, e0, e1, e2, e3 ); 509 } 510 } else if (mode == GL_LINE) { 511 if (DO_OFFSET && ctx->Polygon.OffsetLine) { 512 VERT_Z_ADD(v[0], offset); 513 VERT_Z_ADD(v[1], offset); 514 VERT_Z_ADD(v[2], offset); 515 VERT_Z_ADD(v[3], offset); 516 } 517 if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) { 518 SETUP_STENCIL(facing); 519 UNFILLED_QUAD( ctx, GL_LINE, e0, e1, e2, e3 ); 520 UNSET_STENCIL(facing); 521 } else { 522 UNFILLED_QUAD( ctx, GL_LINE, e0, e1, e2, e3 ); 523 } 524 } else { 525 if (DO_OFFSET && ctx->Polygon.OffsetFill) { 526 VERT_Z_ADD(v[0], offset); 527 VERT_Z_ADD(v[1], offset); 528 VERT_Z_ADD(v[2], offset); 529 VERT_Z_ADD(v[3], offset); 530 } 531 RASTERIZE( GL_QUADS ); 532 if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) { 533 SETUP_STENCIL(facing); 534 QUAD( (v[0]), (v[1]), (v[2]), (v[3]) ); 535 UNSET_STENCIL(facing); 536 } else { 537 QUAD( (v[0]), (v[1]), (v[2]), (v[3]) ); 538 } 539 } 540 541 if (DO_OFFSET) 542 { 543 VERT_SET_Z(v[0], z[0]); 544 VERT_SET_Z(v[1], z[1]); 545 VERT_SET_Z(v[2], z[2]); 546 VERT_SET_Z(v[3], z[3]); 547 } 548 549 if (DO_TWOSIDE && facing == 1) { 550 if (!DO_FLAT) { 551 VERT_RESTORE_RGBA( 0 ); 552 VERT_RESTORE_RGBA( 1 ); 553 VERT_RESTORE_RGBA( 2 ); 554 } 555 VERT_RESTORE_RGBA( 3 ); 556 if (HAVE_SPEC) { 557 if (!DO_FLAT) { 558 VERT_RESTORE_SPEC( 0 ); 559 VERT_RESTORE_SPEC( 1 ); 560 VERT_RESTORE_SPEC( 2 ); 561 } 562 VERT_RESTORE_SPEC( 3 ); 563 } 564 } 565 566 567 if (DO_FLAT) { 568 VERT_RESTORE_RGBA( 0 ); 569 VERT_RESTORE_RGBA( 1 ); 570 VERT_RESTORE_RGBA( 2 ); 571 if (HAVE_SPEC && VB->AttribPtr[_TNL_ATTRIB_COLOR1]) { 572 VERT_RESTORE_SPEC( 0 ); 573 VERT_RESTORE_SPEC( 1 ); 574 VERT_RESTORE_SPEC( 2 ); 575 } 576 } 577 } 578 #else 579 static void TAG(quadr)( struct gl_context *ctx, GLuint e0, 580 GLuint e1, GLuint e2, GLuint e3 ) 581 { 582 if (DO_UNFILLED) { 583 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; 584 GLubyte ef1 = VB->EdgeFlag[e1]; 585 GLubyte ef3 = VB->EdgeFlag[e3]; 586 VB->EdgeFlag[e1] = 0; 587 TAG(triangle)( ctx, e0, e1, e3 ); 588 VB->EdgeFlag[e1] = ef1; 589 VB->EdgeFlag[e3] = 0; 590 TAG(triangle)( ctx, e1, e2, e3 ); 591 VB->EdgeFlag[e3] = ef3; 592 } else { 593 TAG(triangle)( ctx, e0, e1, e3 ); 594 TAG(triangle)( ctx, e1, e2, e3 ); 595 } 596 } 597 #endif 598 #endif 599 600 #if DO_LINE 601 static void TAG(line)( struct gl_context *ctx, GLuint e0, GLuint e1 ) 602 { 603 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; 604 VERTEX *v[2]; 605 LOCAL_VARS(2); 606 607 v[0] = (VERTEX *)GET_VERTEX(e0); 608 v[1] = (VERTEX *)GET_VERTEX(e1); 609 610 if (DO_FLAT) { 611 VERT_SAVE_RGBA( 0 ); 612 VERT_COPY_RGBA( v[0], v[1] ); 613 if (HAVE_SPEC && VB->AttribPtr[_TNL_ATTRIB_COLOR1]) { 614 VERT_SAVE_SPEC( 0 ); 615 VERT_COPY_SPEC( v[0], v[1] ); 616 } 617 } 618 619 LINE( v[0], v[1] ); 620 621 if (DO_FLAT) { 622 VERT_RESTORE_RGBA( 0 ); 623 624 if (HAVE_SPEC && VB->AttribPtr[_TNL_ATTRIB_COLOR1]) { 625 VERT_RESTORE_SPEC( 0 ); 626 } 627 } 628 } 629 #endif 630 631 #if DO_POINTS 632 static void TAG(points)( struct gl_context *ctx, GLuint first, GLuint last ) 633 { 634 struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb; 635 GLuint i; 636 LOCAL_VARS(1); 637 638 if (VB->Elts == 0) { 639 for ( i = first ; i < last ; i++ ) { 640 if ( VB->ClipMask[i] == 0 ) { 641 VERTEX *v = (VERTEX *)GET_VERTEX(i); 642 POINT( v ); 643 } 644 } 645 } else { 646 for ( i = first ; i < last ; i++ ) { 647 GLuint e = VB->Elts[i]; 648 if ( VB->ClipMask[e] == 0 ) { 649 VERTEX *v = (VERTEX *)GET_VERTEX(e); 650 POINT( v ); 651 } 652 } 653 } 654 } 655 #endif 656 657 static void TAG(init)( void ) 658 { 659 #if DO_QUAD 660 TAB[IND].quad = TAG(quadr); 661 #endif 662 #if DO_TRI 663 TAB[IND].triangle = TAG(triangle); 664 #endif 665 #if DO_LINE 666 TAB[IND].line = TAG(line); 667 #endif 668 #if DO_POINTS 669 TAB[IND].points = TAG(points); 670 #endif 671 } 672 673 #undef IND 674 #undef TAG 675 676 #if HAVE_BACK_COLORS 677 #undef VERT_SET_RGBA 678 #endif 679 680 #if !HAVE_SPEC 681 #undef VERT_SET_SPEC 682 #undef VERT_COPY_SPEC 683 #undef VERT_SAVE_SPEC 684 #undef VERT_RESTORE_SPEC 685 #if HAVE_BACK_COLORS 686 #undef VERT_COPY_SPEC1 687 #endif 688 #else 689 #if HAVE_BACK_COLORS 690 #undef VERT_SET_SPEC 691 #endif 692 #endif 693 694 #if !HAVE_BACK_COLORS 695 #undef VERT_COPY_SPEC1 696 #undef VERT_COPY_RGBA1 697 #endif 698 699 #ifndef INSANE_VERTICES 700 #undef VERT_SET_Z 701 #undef VERT_Z_ADD 702 #endif 703