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