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