lines.c revision fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5
1/* $Id: lines.c,v 1.6 1999/11/11 01:22:27 brianp Exp $ */ 2 3/* 4 * Mesa 3-D graphics library 5 * Version: 3.3 6 * 7 * Copyright (C) 1999 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 27 28#ifdef PC_HEADER 29#include "all.h" 30#else 31#include "glheader.h" 32#include "context.h" 33#include "depth.h" 34#include "feedback.h" 35#include "lines.h" 36#include "macros.h" 37#include "mmath.h" 38#include "pb.h" 39#include "texstate.h" 40#include "types.h" 41#include "vb.h" 42#endif 43 44 45 46void 47_mesa_LineWidth( GLfloat width ) 48{ 49 GET_CURRENT_CONTEXT(ctx); 50 if (width<=0.0) { 51 gl_error( ctx, GL_INVALID_VALUE, "glLineWidth" ); 52 return; 53 } 54 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glLineWidth"); 55 56 if (ctx->Line.Width != width) { 57 ctx->Line.Width = width; 58 ctx->TriangleCaps &= ~DD_LINE_WIDTH; 59 if (width != 1.0) ctx->TriangleCaps |= DD_LINE_WIDTH; 60 ctx->NewState |= NEW_RASTER_OPS; 61 } 62} 63 64 65 66void 67_mesa_LineStipple( GLint factor, GLushort pattern ) 68{ 69 GET_CURRENT_CONTEXT(ctx); 70 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glLineStipple"); 71 ctx->Line.StippleFactor = CLAMP( factor, 1, 256 ); 72 ctx->Line.StipplePattern = pattern; 73 ctx->NewState |= NEW_RASTER_OPS; 74} 75 76 77 78/**********************************************************************/ 79/***** Rasterization *****/ 80/**********************************************************************/ 81 82 83/* 84 * There are 4 pairs (RGBA, CI) of line drawing functions: 85 * 1. simple: width=1 and no special rasterization functions (fastest) 86 * 2. flat: width=1, non-stippled, flat-shaded, any raster operations 87 * 3. smooth: width=1, non-stippled, smooth-shaded, any raster operations 88 * 4. general: any other kind of line (slowest) 89 */ 90 91 92/* 93 * All line drawing functions have the same arguments: 94 * v1, v2 - indexes of first and second endpoints into vertex buffer arrays 95 * pv - provoking vertex: which vertex color/index to use for flat shading. 96 */ 97 98 99 100 101 102 103#if MAX_WIDTH > MAX_HEIGHT 104# define MAXPOINTS MAX_WIDTH 105#else 106# define MAXPOINTS MAX_HEIGHT 107#endif 108 109 110/* Flat, color index line */ 111static void flat_ci_line( GLcontext *ctx, 112 GLuint vert0, GLuint vert1, GLuint pvert ) 113{ 114 GLint count; 115 GLint *pbx = ctx->PB->x; 116 GLint *pby = ctx->PB->y; 117 PB_SET_INDEX( ctx, ctx->PB, ctx->VB->IndexPtr->data[pvert] ); 118 count = ctx->PB->count; 119 120#define INTERP_XY 1 121 122#define PLOT(X,Y) \ 123 pbx[count] = X; \ 124 pby[count] = Y; \ 125 count++; 126 127#include "linetemp.h" 128 129 ctx->PB->count = count; 130 gl_flush_pb(ctx); 131} 132 133 134 135/* Flat, color index line with Z interpolation/testing */ 136static void flat_ci_z_line( GLcontext *ctx, 137 GLuint vert0, GLuint vert1, GLuint pvert ) 138{ 139 GLint count; 140 GLint *pbx = ctx->PB->x; 141 GLint *pby = ctx->PB->y; 142 GLdepth *pbz = ctx->PB->z; 143 PB_SET_INDEX( ctx, ctx->PB, ctx->VB->IndexPtr->data[pvert] ); 144 count = ctx->PB->count; 145 146#define INTERP_XY 1 147#define INTERP_Z 1 148 149#define PLOT(X,Y) \ 150 pbx[count] = X; \ 151 pby[count] = Y; \ 152 pbz[count] = Z; \ 153 count++; 154 155#include "linetemp.h" 156 157 ctx->PB->count = count; 158 gl_flush_pb(ctx); 159} 160 161 162 163/* Flat-shaded, RGBA line */ 164static void flat_rgba_line( GLcontext *ctx, 165 GLuint vert0, GLuint vert1, GLuint pvert ) 166{ 167 GLint count; 168 GLint *pbx = ctx->PB->x; 169 GLint *pby = ctx->PB->y; 170 GLubyte *color = ctx->VB->ColorPtr->data[pvert]; 171 PB_SET_COLOR( ctx, ctx->PB, color[0], color[1], color[2], color[3] ); 172 count = ctx->PB->count; 173 174#define INTERP_XY 1 175 176#define PLOT(X,Y) \ 177 pbx[count] = X; \ 178 pby[count] = Y; \ 179 count++; 180 181#include "linetemp.h" 182 183 ctx->PB->count = count; 184 gl_flush_pb(ctx); 185} 186 187 188 189/* Flat-shaded, RGBA line with Z interpolation/testing */ 190static void flat_rgba_z_line( GLcontext *ctx, 191 GLuint vert0, GLuint vert1, GLuint pvert ) 192{ 193 GLint count; 194 GLint *pbx = ctx->PB->x; 195 GLint *pby = ctx->PB->y; 196 GLdepth *pbz = ctx->PB->z; 197 GLubyte *color = ctx->VB->ColorPtr->data[pvert]; 198 PB_SET_COLOR( ctx, ctx->PB, color[0], color[1], color[2], color[3] ); 199 count = ctx->PB->count; 200 201#define INTERP_XY 1 202#define INTERP_Z 1 203 204#define PLOT(X,Y) \ 205 pbx[count] = X; \ 206 pby[count] = Y; \ 207 pbz[count] = Z; \ 208 count++; 209 210#include "linetemp.h" 211 212 ctx->PB->count = count; 213 gl_flush_pb(ctx); 214} 215 216 217 218/* Smooth shaded, color index line */ 219static void smooth_ci_line( GLcontext *ctx, 220 GLuint vert0, GLuint vert1, GLuint pvert ) 221{ 222 GLint count = ctx->PB->count; 223 GLint *pbx = ctx->PB->x; 224 GLint *pby = ctx->PB->y; 225 GLuint *pbi = ctx->PB->i; 226 (void) pvert; 227 228#define INTERP_XY 1 229#define INTERP_INDEX 1 230 231#define PLOT(X,Y) \ 232 pbx[count] = X; \ 233 pby[count] = Y; \ 234 pbi[count] = I; \ 235 count++; 236 237#include "linetemp.h" 238 239 ctx->PB->count = count; 240 gl_flush_pb(ctx); 241} 242 243 244 245/* Smooth shaded, color index line with Z interpolation/testing */ 246static void smooth_ci_z_line( GLcontext *ctx, 247 GLuint vert0, GLuint vert1, GLuint pvert ) 248{ 249 GLint count = ctx->PB->count; 250 GLint *pbx = ctx->PB->x; 251 GLint *pby = ctx->PB->y; 252 GLdepth *pbz = ctx->PB->z; 253 GLuint *pbi = ctx->PB->i; 254 (void) pvert; 255 256#define INTERP_XY 1 257#define INTERP_Z 1 258#define INTERP_INDEX 1 259 260#define PLOT(X,Y) \ 261 pbx[count] = X; \ 262 pby[count] = Y; \ 263 pbz[count] = Z; \ 264 pbi[count] = I; \ 265 count++; 266 267#include "linetemp.h" 268 269 ctx->PB->count = count; 270 gl_flush_pb(ctx); 271} 272 273 274 275/* Smooth-shaded, RGBA line */ 276static void smooth_rgba_line( GLcontext *ctx, 277 GLuint vert0, GLuint vert1, GLuint pvert ) 278{ 279 GLint count = ctx->PB->count; 280 GLint *pbx = ctx->PB->x; 281 GLint *pby = ctx->PB->y; 282 GLubyte (*pbrgba)[4] = ctx->PB->rgba; 283 (void) pvert; 284 285#define INTERP_XY 1 286#define INTERP_RGB 1 287#define INTERP_ALPHA 1 288 289#define PLOT(X,Y) \ 290 pbx[count] = X; \ 291 pby[count] = Y; \ 292 pbrgba[count][RCOMP] = FixedToInt(r0); \ 293 pbrgba[count][GCOMP] = FixedToInt(g0); \ 294 pbrgba[count][BCOMP] = FixedToInt(b0); \ 295 pbrgba[count][ACOMP] = FixedToInt(a0); \ 296 count++; 297 298#include "linetemp.h" 299 300 ctx->PB->count = count; 301 gl_flush_pb(ctx); 302} 303 304 305 306/* Smooth-shaded, RGBA line with Z interpolation/testing */ 307static void smooth_rgba_z_line( GLcontext *ctx, 308 GLuint vert0, GLuint vert1, GLuint pvert ) 309{ 310 GLint count = ctx->PB->count; 311 GLint *pbx = ctx->PB->x; 312 GLint *pby = ctx->PB->y; 313 GLdepth *pbz = ctx->PB->z; 314 GLubyte (*pbrgba)[4] = ctx->PB->rgba; 315 (void) pvert; 316 317#define INTERP_XY 1 318#define INTERP_Z 1 319#define INTERP_RGB 1 320#define INTERP_ALPHA 1 321 322#define PLOT(X,Y) \ 323 pbx[count] = X; \ 324 pby[count] = Y; \ 325 pbz[count] = Z; \ 326 pbrgba[count][RCOMP] = FixedToInt(r0); \ 327 pbrgba[count][GCOMP] = FixedToInt(g0); \ 328 pbrgba[count][BCOMP] = FixedToInt(b0); \ 329 pbrgba[count][ACOMP] = FixedToInt(a0); \ 330 count++; 331 332#include "linetemp.h" 333 334 ctx->PB->count = count; 335 gl_flush_pb(ctx); 336} 337 338 339#define CHECK_FULL(count) \ 340 if (count >= PB_SIZE-MAX_WIDTH) { \ 341 ctx->PB->count = count; \ 342 gl_flush_pb(ctx); \ 343 count = ctx->PB->count; \ 344 } 345 346 347 348/* Smooth shaded, color index, any width, maybe stippled */ 349static void general_smooth_ci_line( GLcontext *ctx, 350 GLuint vert0, GLuint vert1, GLuint pvert ) 351{ 352 GLint count = ctx->PB->count; 353 GLint *pbx = ctx->PB->x; 354 GLint *pby = ctx->PB->y; 355 GLdepth *pbz = ctx->PB->z; 356 GLuint *pbi = ctx->PB->i; 357 (void) pvert; 358 359 if (ctx->Line.StippleFlag) { 360 /* stippled */ 361#define INTERP_XY 1 362#define INTERP_Z 1 363#define INTERP_INDEX 1 364#define WIDE 1 365#define STIPPLE 1 366#define PLOT(X,Y) \ 367 pbx[count] = X; \ 368 pby[count] = Y; \ 369 pbz[count] = Z; \ 370 pbi[count] = I; \ 371 count++; \ 372 CHECK_FULL(count); 373#include "linetemp.h" 374 } 375 else { 376 /* unstippled */ 377 if (ctx->Line.Width==2.0F) { 378 /* special case: unstippled and width=2 */ 379#define INTERP_XY 1 380#define INTERP_Z 1 381#define INTERP_INDEX 1 382#define XMAJOR_PLOT(X,Y) \ 383 pbx[count] = X; pbx[count+1] = X; \ 384 pby[count] = Y; pby[count+1] = Y+1; \ 385 pbz[count] = Z; pbz[count+1] = Z; \ 386 pbi[count] = I; pbi[count+1] = I; \ 387 count += 2; \ 388 CHECK_FULL(count); 389#define YMAJOR_PLOT(X,Y) \ 390 pbx[count] = X; pbx[count+1] = X+1; \ 391 pby[count] = Y; pby[count+1] = Y; \ 392 pbz[count] = Z; pbz[count+1] = Z; \ 393 pbi[count] = I; pbi[count+1] = I; \ 394 count += 2; \ 395 CHECK_FULL(count); 396#include "linetemp.h" 397 } 398 else { 399 /* unstippled, any width */ 400#define INTERP_XY 1 401#define INTERP_Z 1 402#define INTERP_INDEX 1 403#define WIDE 1 404#define PLOT(X,Y) \ 405 pbx[count] = X; \ 406 pby[count] = Y; \ 407 pbz[count] = Z; \ 408 pbi[count] = I; \ 409 count++; \ 410 CHECK_FULL(count); 411#include "linetemp.h" 412 } 413 } 414 415 ctx->PB->count = count; 416 gl_flush_pb(ctx); 417} 418 419 420/* Flat shaded, color index, any width, maybe stippled */ 421static void general_flat_ci_line( GLcontext *ctx, 422 GLuint vert0, GLuint vert1, GLuint pvert ) 423{ 424 GLint count; 425 GLint *pbx = ctx->PB->x; 426 GLint *pby = ctx->PB->y; 427 GLdepth *pbz = ctx->PB->z; 428 PB_SET_INDEX( ctx, ctx->PB, ctx->VB->IndexPtr->data[pvert] ); 429 count = ctx->PB->count; 430 431 if (ctx->Line.StippleFlag) { 432 /* stippled, any width */ 433#define INTERP_XY 1 434#define INTERP_Z 1 435#define WIDE 1 436#define STIPPLE 1 437#define PLOT(X,Y) \ 438 pbx[count] = X; \ 439 pby[count] = Y; \ 440 pbz[count] = Z; \ 441 count++; \ 442 CHECK_FULL(count); 443#include "linetemp.h" 444 } 445 else { 446 /* unstippled */ 447 if (ctx->Line.Width==2.0F) { 448 /* special case: unstippled and width=2 */ 449#define INTERP_XY 1 450#define INTERP_Z 1 451#define XMAJOR_PLOT(X,Y) \ 452 pbx[count] = X; pbx[count+1] = X; \ 453 pby[count] = Y; pby[count+1] = Y+1; \ 454 pbz[count] = Z; pbz[count+1] = Z; \ 455 count += 2; \ 456 CHECK_FULL(count); 457#define YMAJOR_PLOT(X,Y) \ 458 pbx[count] = X; pbx[count+1] = X+1; \ 459 pby[count] = Y; pby[count+1] = Y; \ 460 pbz[count] = Z; pbz[count+1] = Z; \ 461 count += 2; \ 462 CHECK_FULL(count); 463#include "linetemp.h" 464 } 465 else { 466 /* unstippled, any width */ 467#define INTERP_XY 1 468#define INTERP_Z 1 469#define WIDE 1 470#define PLOT(X,Y) \ 471 pbx[count] = X; \ 472 pby[count] = Y; \ 473 pbz[count] = Z; \ 474 count++; \ 475 CHECK_FULL(count); 476#include "linetemp.h" 477 } 478 } 479 480 ctx->PB->count = count; 481 gl_flush_pb(ctx); 482} 483 484 485 486static void general_smooth_rgba_line( GLcontext *ctx, 487 GLuint vert0, GLuint vert1, GLuint pvert) 488{ 489 GLint count = ctx->PB->count; 490 GLint *pbx = ctx->PB->x; 491 GLint *pby = ctx->PB->y; 492 GLdepth *pbz = ctx->PB->z; 493 GLubyte (*pbrgba)[4] = ctx->PB->rgba; 494 (void) pvert; 495 496 if (ctx->Line.StippleFlag) { 497 /* stippled */ 498#define INTERP_XY 1 499#define INTERP_Z 1 500#define INTERP_RGB 1 501#define INTERP_ALPHA 1 502#define WIDE 1 503#define STIPPLE 1 504#define PLOT(X,Y) \ 505 pbx[count] = X; \ 506 pby[count] = Y; \ 507 pbz[count] = Z; \ 508 pbrgba[count][RCOMP] = FixedToInt(r0); \ 509 pbrgba[count][GCOMP] = FixedToInt(g0); \ 510 pbrgba[count][BCOMP] = FixedToInt(b0); \ 511 pbrgba[count][ACOMP] = FixedToInt(a0); \ 512 count++; \ 513 CHECK_FULL(count); 514#include "linetemp.h" 515 } 516 else { 517 /* unstippled */ 518 if (ctx->Line.Width==2.0F) { 519 /* special case: unstippled and width=2 */ 520#define INTERP_XY 1 521#define INTERP_Z 1 522#define INTERP_RGB 1 523#define INTERP_ALPHA 1 524#define XMAJOR_PLOT(X,Y) \ 525 pbx[count] = X; pbx[count+1] = X; \ 526 pby[count] = Y; pby[count+1] = Y+1; \ 527 pbz[count] = Z; pbz[count+1] = Z; \ 528 pbrgba[count][RCOMP] = FixedToInt(r0); \ 529 pbrgba[count][GCOMP] = FixedToInt(g0); \ 530 pbrgba[count][BCOMP] = FixedToInt(b0); \ 531 pbrgba[count][ACOMP] = FixedToInt(a0); \ 532 pbrgba[count+1][RCOMP] = FixedToInt(r0); \ 533 pbrgba[count+1][GCOMP] = FixedToInt(g0); \ 534 pbrgba[count+1][BCOMP] = FixedToInt(b0); \ 535 pbrgba[count+1][ACOMP] = FixedToInt(a0); \ 536 count += 2; \ 537 CHECK_FULL(count); 538#define YMAJOR_PLOT(X,Y) \ 539 pbx[count] = X; pbx[count+1] = X+1; \ 540 pby[count] = Y; pby[count+1] = Y; \ 541 pbz[count] = Z; pbz[count+1] = Z; \ 542 pbrgba[count][RCOMP] = FixedToInt(r0); \ 543 pbrgba[count][GCOMP] = FixedToInt(g0); \ 544 pbrgba[count][BCOMP] = FixedToInt(b0); \ 545 pbrgba[count][ACOMP] = FixedToInt(a0); \ 546 pbrgba[count+1][RCOMP] = FixedToInt(r0); \ 547 pbrgba[count+1][GCOMP] = FixedToInt(g0); \ 548 pbrgba[count+1][BCOMP] = FixedToInt(b0); \ 549 pbrgba[count+1][ACOMP] = FixedToInt(a0); \ 550 count += 2; \ 551 CHECK_FULL(count); 552#include "linetemp.h" 553 } 554 else { 555 /* unstippled, any width */ 556#define INTERP_XY 1 557#define INTERP_Z 1 558#define INTERP_RGB 1 559#define INTERP_ALPHA 1 560#define WIDE 1 561#define PLOT(X,Y) \ 562 pbx[count] = X; \ 563 pby[count] = Y; \ 564 pbz[count] = Z; \ 565 pbrgba[count][RCOMP] = FixedToInt(r0); \ 566 pbrgba[count][GCOMP] = FixedToInt(g0); \ 567 pbrgba[count][BCOMP] = FixedToInt(b0); \ 568 pbrgba[count][ACOMP] = FixedToInt(a0); \ 569 count++; \ 570 CHECK_FULL(count); 571#include "linetemp.h" 572 } 573 } 574 575 ctx->PB->count = count; 576 gl_flush_pb(ctx); 577} 578 579 580static void general_flat_rgba_line( GLcontext *ctx, 581 GLuint vert0, GLuint vert1, GLuint pvert ) 582{ 583 GLint count; 584 GLint *pbx = ctx->PB->x; 585 GLint *pby = ctx->PB->y; 586 GLdepth *pbz = ctx->PB->z; 587 GLubyte *color = ctx->VB->ColorPtr->data[pvert]; 588 PB_SET_COLOR( ctx, ctx->PB, color[0], color[1], color[2], color[3] ); 589 count = ctx->PB->count; 590 591 if (ctx->Line.StippleFlag) { 592 /* stippled */ 593#define INTERP_XY 1 594#define INTERP_Z 1 595#define WIDE 1 596#define STIPPLE 1 597#define PLOT(X,Y) \ 598 pbx[count] = X; \ 599 pby[count] = Y; \ 600 pbz[count] = Z; \ 601 count++; \ 602 CHECK_FULL(count); 603#include "linetemp.h" 604 } 605 else { 606 /* unstippled */ 607 if (ctx->Line.Width==2.0F) { 608 /* special case: unstippled and width=2 */ 609#define INTERP_XY 1 610#define INTERP_Z 1 611#define XMAJOR_PLOT(X,Y) \ 612 pbx[count] = X; pbx[count+1] = X; \ 613 pby[count] = Y; pby[count+1] = Y+1; \ 614 pbz[count] = Z; pbz[count+1] = Z; \ 615 count += 2; \ 616 CHECK_FULL(count); 617#define YMAJOR_PLOT(X,Y) \ 618 pbx[count] = X; pbx[count+1] = X+1; \ 619 pby[count] = Y; pby[count+1] = Y; \ 620 pbz[count] = Z; pbz[count+1] = Z; \ 621 count += 2; \ 622 CHECK_FULL(count); 623#include "linetemp.h" 624 } 625 else { 626 /* unstippled, any width */ 627#define INTERP_XY 1 628#define INTERP_Z 1 629#define WIDE 1 630#define PLOT(X,Y) \ 631 pbx[count] = X; \ 632 pby[count] = Y; \ 633 pbz[count] = Z; \ 634 count++; \ 635 CHECK_FULL(count); 636#include "linetemp.h" 637 } 638 } 639 640 ctx->PB->count = count; 641 gl_flush_pb(ctx); 642} 643 644 645/* Flat-shaded, textured, any width, maybe stippled */ 646static void flat_textured_line( GLcontext *ctx, 647 GLuint vert0, GLuint vert1, GLuint pv ) 648{ 649 GLint count; 650 GLint *pbx = ctx->PB->x; 651 GLint *pby = ctx->PB->y; 652 GLdepth *pbz = ctx->PB->z; 653 GLfloat *pbs = ctx->PB->s[0]; 654 GLfloat *pbt = ctx->PB->t[0]; 655 GLfloat *pbu = ctx->PB->u[0]; 656 GLubyte *color = ctx->VB->ColorPtr->data[pv]; 657 PB_SET_COLOR( ctx, ctx->PB, color[0], color[1], color[2], color[3] ); 658 count = ctx->PB->count; 659 660 if (ctx->Line.StippleFlag) { 661 /* stippled */ 662#define INTERP_XY 1 663#define INTERP_Z 1 664#define INTERP_STUV0 1 665#define WIDE 1 666#define STIPPLE 1 667#define PLOT(X,Y) \ 668 { \ 669 pbx[count] = X; \ 670 pby[count] = Y; \ 671 pbz[count] = Z; \ 672 pbs[count] = s; \ 673 pbt[count] = t; \ 674 pbu[count] = u; \ 675 count++; \ 676 CHECK_FULL(count); \ 677 } 678#include "linetemp.h" 679 } 680 else { 681 /* unstippled */ 682#define INTERP_XY 1 683#define INTERP_Z 1 684#define INTERP_STUV0 1 685#define WIDE 1 686#define PLOT(X,Y) \ 687 { \ 688 pbx[count] = X; \ 689 pby[count] = Y; \ 690 pbz[count] = Z; \ 691 pbs[count] = s; \ 692 pbt[count] = t; \ 693 pbu[count] = u; \ 694 count++; \ 695 CHECK_FULL(count); \ 696 } 697#include "linetemp.h" 698 } 699 700 ctx->PB->count = count; 701 gl_flush_pb(ctx); 702} 703 704 705 706/* Smooth-shaded, textured, any width, maybe stippled */ 707static void smooth_textured_line( GLcontext *ctx, 708 GLuint vert0, GLuint vert1, GLuint pvert ) 709{ 710 GLint count = ctx->PB->count; 711 GLint *pbx = ctx->PB->x; 712 GLint *pby = ctx->PB->y; 713 GLdepth *pbz = ctx->PB->z; 714 GLfloat *pbs = ctx->PB->s[0]; 715 GLfloat *pbt = ctx->PB->t[0]; 716 GLfloat *pbu = ctx->PB->u[0]; 717 GLubyte (*pbrgba)[4] = ctx->PB->rgba; 718 (void) pvert; 719 720 if (ctx->Line.StippleFlag) { 721 /* stippled */ 722#define INTERP_XY 1 723#define INTERP_Z 1 724#define INTERP_RGB 1 725#define INTERP_ALPHA 1 726#define INTERP_STUV0 1 727#define WIDE 1 728#define STIPPLE 1 729#define PLOT(X,Y) \ 730 { \ 731 pbx[count] = X; \ 732 pby[count] = Y; \ 733 pbz[count] = Z; \ 734 pbs[count] = s; \ 735 pbt[count] = t; \ 736 pbu[count] = u; \ 737 pbrgba[count][RCOMP] = FixedToInt(r0); \ 738 pbrgba[count][GCOMP] = FixedToInt(g0); \ 739 pbrgba[count][BCOMP] = FixedToInt(b0); \ 740 pbrgba[count][ACOMP] = FixedToInt(a0); \ 741 count++; \ 742 CHECK_FULL(count); \ 743 } 744#include "linetemp.h" 745 } 746 else { 747 /* unstippled */ 748#define INTERP_XY 1 749#define INTERP_Z 1 750#define INTERP_RGB 1 751#define INTERP_ALPHA 1 752#define INTERP_STUV0 1 753#define WIDE 1 754#define PLOT(X,Y) \ 755 { \ 756 pbx[count] = X; \ 757 pby[count] = Y; \ 758 pbz[count] = Z; \ 759 pbs[count] = s; \ 760 pbt[count] = t; \ 761 pbu[count] = u; \ 762 pbrgba[count][RCOMP] = FixedToInt(r0); \ 763 pbrgba[count][GCOMP] = FixedToInt(g0); \ 764 pbrgba[count][BCOMP] = FixedToInt(b0); \ 765 pbrgba[count][ACOMP] = FixedToInt(a0); \ 766 count++; \ 767 CHECK_FULL(count); \ 768 } 769#include "linetemp.h" 770 } 771 772 ctx->PB->count = count; 773 gl_flush_pb(ctx); 774} 775 776 777/* Smooth-shaded, multitextured, any width, maybe stippled, separate specular 778 * color interpolation. 779 */ 780static void smooth_multitextured_line( GLcontext *ctx, 781 GLuint vert0, GLuint vert1, GLuint pvert ) 782{ 783 GLint count = ctx->PB->count; 784 GLint *pbx = ctx->PB->x; 785 GLint *pby = ctx->PB->y; 786 GLdepth *pbz = ctx->PB->z; 787 GLfloat *pbs = ctx->PB->s[0]; 788 GLfloat *pbt = ctx->PB->t[0]; 789 GLfloat *pbu = ctx->PB->u[0]; 790 GLfloat *pbs1 = ctx->PB->s[1]; 791 GLfloat *pbt1 = ctx->PB->t[1]; 792 GLfloat *pbu1 = ctx->PB->u[1]; 793 GLubyte (*pbrgba)[4] = ctx->PB->rgba; 794 GLubyte (*pbspec)[3] = ctx->PB->spec; 795 (void) pvert; 796 797 if (ctx->Line.StippleFlag) { 798 /* stippled */ 799#define INTERP_XY 1 800#define INTERP_Z 1 801#define INTERP_RGB 1 802#define INTERP_SPEC 1 803#define INTERP_ALPHA 1 804#define INTERP_STUV0 1 805#define INTERP_STUV1 1 806#define WIDE 1 807#define STIPPLE 1 808#define PLOT(X,Y) \ 809 { \ 810 pbx[count] = X; \ 811 pby[count] = Y; \ 812 pbz[count] = Z; \ 813 pbs[count] = s; \ 814 pbt[count] = t; \ 815 pbu[count] = u; \ 816 pbs1[count] = s1; \ 817 pbt1[count] = t1; \ 818 pbu1[count] = u1; \ 819 pbrgba[count][RCOMP] = FixedToInt(r0); \ 820 pbrgba[count][GCOMP] = FixedToInt(g0); \ 821 pbrgba[count][BCOMP] = FixedToInt(b0); \ 822 pbrgba[count][ACOMP] = FixedToInt(a0); \ 823 pbspec[count][RCOMP] = FixedToInt(sr0); \ 824 pbspec[count][GCOMP] = FixedToInt(sg0); \ 825 pbspec[count][BCOMP] = FixedToInt(sb0); \ 826 count++; \ 827 CHECK_FULL(count); \ 828 } 829#include "linetemp.h" 830 } 831 else { 832 /* unstippled */ 833#define INTERP_XY 1 834#define INTERP_Z 1 835#define INTERP_RGB 1 836#define INTERP_SPEC 1 837#define INTERP_ALPHA 1 838#define INTERP_STUV0 1 839#define INTERP_STUV1 1 840#define WIDE 1 841#define PLOT(X,Y) \ 842 { \ 843 pbx[count] = X; \ 844 pby[count] = Y; \ 845 pbz[count] = Z; \ 846 pbs[count] = s; \ 847 pbt[count] = t; \ 848 pbu[count] = u; \ 849 pbs1[count] = s1; \ 850 pbt1[count] = t1; \ 851 pbu1[count] = u1; \ 852 pbrgba[count][RCOMP] = FixedToInt(r0); \ 853 pbrgba[count][GCOMP] = FixedToInt(g0); \ 854 pbrgba[count][BCOMP] = FixedToInt(b0); \ 855 pbrgba[count][ACOMP] = FixedToInt(a0); \ 856 pbspec[count][RCOMP] = FixedToInt(sr0); \ 857 pbspec[count][GCOMP] = FixedToInt(sg0); \ 858 pbspec[count][BCOMP] = FixedToInt(sb0); \ 859 count++; \ 860 CHECK_FULL(count); \ 861 } 862#include "linetemp.h" 863 } 864 865 ctx->PB->count = count; 866 gl_flush_pb(ctx); 867} 868 869 870/* 871 * Antialiased RGBA line 872 * 873 * This AA line function isn't terribly efficient but it's pretty 874 * straight-forward to understand. Also, it doesn't exactly conform 875 * to the specification. 876 */ 877static void aa_rgba_line( GLcontext *ctx, 878 GLuint vert0, GLuint vert1, GLuint pvert ) 879{ 880#define INTERP_RGBA 1 881#define PLOT(x, y) { PB_WRITE_RGBA_PIXEL( pb, (x), (y), z, red, green, blue, coverage ); } 882#include "lnaatemp.h" 883} 884 885/* 886 * Antialiased Textured RGBA line 887 * 888 * This AA line function isn't terribly efficient but it's pretty 889 * straight-forward to understand. Also, it doesn't exactly conform 890 * to the specification. 891 */ 892static void aa_tex_rgba_line( GLcontext *ctx, 893 GLuint vert0, GLuint vert1, GLuint pvert ) 894{ 895#define INTERP_RGBA 1 896#define INTERP_STUV0 1 897#define PLOT(x, y) \ 898 { \ 899 PB_WRITE_TEX_PIXEL( pb, (x), (y), z, red, green, blue, coverage, \ 900 s, t, u ); \ 901 } 902#include "lnaatemp.h" 903} 904 905 906/* 907 * Antialiased Multitextured RGBA line 908 * 909 * This AA line function isn't terribly efficient but it's pretty 910 * straight-forward to understand. Also, it doesn't exactly conform 911 * to the specification. 912 */ 913static void aa_multitex_rgba_line( GLcontext *ctx, 914 GLuint vert0, GLuint vert1, GLuint pvert ) 915{ 916#define INTERP_RGBA 1 917#define INTERP_SPEC 1 918#define INTERP_STUV0 1 919#define INTERP_STUV1 1 920#define PLOT(x, y) \ 921 { \ 922 PB_WRITE_MULTITEX_SPEC_PIXEL( pb, (x), (y), z, \ 923 red, green, blue, coverage, specRed, specGreen, specBlue, \ 924 s, t, u, s1, t1, u1 ); \ 925 } 926#include "lnaatemp.h" 927} 928 929 930/* 931 * Antialiased CI line. Same comments for RGBA antialiased lines apply. 932 */ 933static void aa_ci_line( GLcontext *ctx, 934 GLuint vert0, GLuint vert1, GLuint pvert ) 935{ 936#define INTERP_INDEX 1 937#define PLOT(x, y) \ 938 { \ 939 PB_WRITE_CI_PIXEL( pb, (x), (y), z, index + coverage ); \ 940 } 941#include "lnaatemp.h" 942} 943 944 945/* 946 * Null rasterizer for measuring transformation speed. 947 */ 948static void null_line( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv ) 949{ 950 (void) ctx; 951 (void) v1; 952 (void) v2; 953 (void) pv; 954} 955 956 957/* 958 * Determine which line drawing function to use given the current 959 * rendering context. 960 */ 961void gl_set_line_function( GLcontext *ctx ) 962{ 963 GLboolean rgbmode = ctx->Visual->RGBAflag; 964 /* TODO: antialiased lines */ 965 966 if (ctx->RenderMode==GL_RENDER) { 967 if (ctx->NoRaster) { 968 ctx->Driver.LineFunc = null_line; 969 return; 970 } 971 if (ctx->Driver.LineFunc) { 972 /* Device driver will draw lines. */ 973 return; 974 } 975 976 if (ctx->Line.SmoothFlag) { 977 /* antialiased lines */ 978 if (rgbmode) { 979 if (ctx->Texture.ReallyEnabled) { 980 if (ctx->Texture.ReallyEnabled >= TEXTURE1_1D 981 || ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR) 982 /* Multitextured! */ 983 ctx->Driver.LineFunc = aa_multitex_rgba_line; 984 else 985 ctx->Driver.LineFunc = aa_tex_rgba_line; 986 } else { 987 ctx->Driver.LineFunc = aa_rgba_line; 988 } 989 } 990 else { 991 ctx->Driver.LineFunc = aa_ci_line; 992 } 993 } 994 else if (ctx->Texture.ReallyEnabled) { 995 if (ctx->Texture.ReallyEnabled >= TEXTURE1_1D 996 || ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR) { 997 /* multi-texture and/or separate specular color */ 998 ctx->Driver.LineFunc = smooth_multitextured_line; 999 } 1000 else { 1001 if (ctx->Light.ShadeModel==GL_SMOOTH) { 1002 ctx->Driver.LineFunc = smooth_textured_line; 1003 } 1004 else { 1005 ctx->Driver.LineFunc = flat_textured_line; 1006 } 1007 } 1008 } 1009 else if (ctx->Line.Width!=1.0 || ctx->Line.StippleFlag 1010 || ctx->Line.SmoothFlag) { 1011 if (ctx->Light.ShadeModel==GL_SMOOTH) { 1012 if (rgbmode) 1013 ctx->Driver.LineFunc = general_smooth_rgba_line; 1014 else 1015 ctx->Driver.LineFunc = general_smooth_ci_line; 1016 } 1017 else { 1018 if (rgbmode) 1019 ctx->Driver.LineFunc = general_flat_rgba_line; 1020 else 1021 ctx->Driver.LineFunc = general_flat_ci_line; 1022 } 1023 } 1024 else { 1025 if (ctx->Light.ShadeModel==GL_SMOOTH) { 1026 /* Width==1, non-stippled, smooth-shaded */ 1027 if (ctx->Depth.Test 1028 || (ctx->Fog.Enabled && ctx->Hint.Fog==GL_NICEST)) { 1029 if (rgbmode) 1030 ctx->Driver.LineFunc = smooth_rgba_z_line; 1031 else 1032 ctx->Driver.LineFunc = smooth_ci_z_line; 1033 } 1034 else { 1035 if (rgbmode) 1036 ctx->Driver.LineFunc = smooth_rgba_line; 1037 else 1038 ctx->Driver.LineFunc = smooth_ci_line; 1039 } 1040 } 1041 else { 1042 /* Width==1, non-stippled, flat-shaded */ 1043 if (ctx->Depth.Test 1044 || (ctx->Fog.Enabled && ctx->Hint.Fog==GL_NICEST)) { 1045 if (rgbmode) 1046 ctx->Driver.LineFunc = flat_rgba_z_line; 1047 else 1048 ctx->Driver.LineFunc = flat_ci_z_line; 1049 } 1050 else { 1051 if (rgbmode) 1052 ctx->Driver.LineFunc = flat_rgba_line; 1053 else 1054 ctx->Driver.LineFunc = flat_ci_line; 1055 } 1056 } 1057 } 1058 } 1059 else if (ctx->RenderMode==GL_FEEDBACK) { 1060 ctx->Driver.LineFunc = gl_feedback_line; 1061 } 1062 else { 1063 /* GL_SELECT mode */ 1064 ctx->Driver.LineFunc = gl_select_line; 1065 } 1066} 1067 1068