1 /* $Id: lines.c,v 1.19 1998/02/03 23:46:00 brianp Exp $ */ 2 3 /* 4 * Mesa 3-D graphics library 5 * Version: 2.4 6 * Copyright (C) 1995-1997 Brian Paul 7 * 8 * This library is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Library General Public 10 * License as published by the Free Software Foundation; either 11 * version 2 of the License, or (at your option) any later version. 12 * 13 * This library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Library General Public License for more details. 17 * 18 * You should have received a copy of the GNU Library General Public 19 * License along with this library; if not, write to the Free 20 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 */ 22 23 24 /* 25 * $Log: lines.c,v $ 26 * Revision 1.19 1998/02/03 23:46:00 brianp 27 * fixed a few problems with condition expressions for Amiga StormC compiler 28 * 29 * Revision 1.18 1997/07/24 01:24:11 brianp 30 * changed precompiled header symbol from PCH to PC_HEADER 31 * 32 * Revision 1.17 1997/07/05 16:03:51 brianp 33 * fixed PB overflow problem 34 * 35 * Revision 1.16 1997/06/20 02:01:49 brianp 36 * changed color components from GLfixed to GLubyte 37 * 38 * Revision 1.15 1997/06/03 01:38:22 brianp 39 * fixed divide by zero problem in feedback function (William Mitchell) 40 * 41 * Revision 1.14 1997/05/28 03:25:26 brianp 42 * added precompiled header (PCH) support 43 * 44 * Revision 1.13 1997/05/03 00:51:02 brianp 45 * removed calls to gl_texturing_enabled() 46 * 47 * Revision 1.12 1997/04/14 02:00:39 brianp 48 * #include "texstate.h" instead of "texture.h" 49 * 50 * Revision 1.11 1997/04/12 12:25:01 brianp 51 * replaced ctx->LineFunc with ctx->Driver.LineFunc, fixed PB->count bug 52 * 53 * Revision 1.10 1997/03/16 02:07:31 brianp 54 * now use linetemp.h in line drawing functions 55 * 56 * Revision 1.9 1997/03/08 02:04:27 brianp 57 * better implementation of feedback function 58 * 59 * Revision 1.8 1997/02/09 18:44:20 brianp 60 * added GL_EXT_texture3D support 61 * 62 * Revision 1.7 1997/01/09 19:48:00 brianp 63 * now call gl_texturing_enabled() 64 * 65 * Revision 1.6 1996/11/08 02:21:21 brianp 66 * added null drawing function for GL_NO_RASTER 67 * 68 * Revision 1.5 1996/09/27 01:28:56 brianp 69 * removed unused variables 70 * 71 * Revision 1.4 1996/09/25 02:01:54 brianp 72 * new texture coord interpolation 73 * 74 * Revision 1.3 1996/09/15 14:18:10 brianp 75 * now use GLframebuffer and GLvisual 76 * 77 * Revision 1.2 1996/09/15 01:48:58 brianp 78 * removed #define NULL 0 79 * 80 * Revision 1.1 1996/09/13 01:38:16 brianp 81 * Initial revision 82 * 83 */ 84 85 86 #ifdef PC_HEADER 87 #include "all.h" 88 #else 89 #include "context.h" 90 #include "depth.h" 91 #include "feedback.h" 92 #include "lines.h" 93 #include "dlist.h" 94 #include "macros.h" 95 #include "pb.h" 96 #include "texstate.h" 97 #include "types.h" 98 #include "vb.h" 99 #include <wine/debug.h> 100 #endif 101 102 WINE_DEFAULT_DEBUG_CHANNEL(opengl32); 103 104 void gl_LineWidth( GLcontext *ctx, GLfloat width ) 105 { 106 if (width<=0.0) { 107 gl_error( ctx, GL_INVALID_VALUE, "glLineWidth" ); 108 return; 109 } 110 if (INSIDE_BEGIN_END(ctx)) { 111 gl_error( ctx, GL_INVALID_OPERATION, "glLineWidth" ); 112 return; 113 } 114 ctx->Line.Width = width; 115 ctx->NewState |= NEW_RASTER_OPS; 116 } 117 118 119 120 void gl_LineStipple( GLcontext *ctx, GLint factor, GLushort pattern ) 121 { 122 if (INSIDE_BEGIN_END(ctx)) { 123 gl_error( ctx, GL_INVALID_OPERATION, "glLineStipple" ); 124 return; 125 } 126 ctx->Line.StippleFactor = CLAMP( factor, 1, 256 ); 127 ctx->Line.StipplePattern = pattern; 128 ctx->NewState |= NEW_RASTER_OPS; 129 } 130 131 132 133 /**********************************************************************/ 134 /***** Rasterization *****/ 135 /**********************************************************************/ 136 137 138 /* 139 * There are 4 pairs (RGBA, CI) of line drawing functions: 140 * 1. simple: width=1 and no special rasterization functions (fastest) 141 * 2. flat: width=1, non-stippled, flat-shaded, any raster operations 142 * 3. smooth: width=1, non-stippled, smooth-shaded, any raster operations 143 * 4. general: any other kind of line (slowest) 144 */ 145 146 147 /* 148 * All line drawing functions have the same arguments: 149 * v1, v2 - indexes of first and second endpoints into vertex buffer arrays 150 * pv - provoking vertex: which vertex color/index to use for flat shading. 151 */ 152 153 154 155 static void feedback_line( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv ) 156 { 157 struct vertex_buffer *VB = ctx->VB; 158 GLfloat x1, y1, z1, w1; 159 GLfloat x2, y2, z2, w2; 160 GLfloat tex1[4], tex2[4], invq; 161 GLfloat invRedScale = ctx->Visual->InvRedScale; 162 GLfloat invGreenScale = ctx->Visual->InvGreenScale; 163 GLfloat invBlueScale = ctx->Visual->InvBlueScale; 164 GLfloat invAlphaScale = ctx->Visual->InvAlphaScale; 165 166 x1 = VB->Win[v1][0]; 167 y1 = VB->Win[v1][1]; 168 z1 = VB->Win[v1][2] / DEPTH_SCALE; 169 w1 = VB->Clip[v1][3]; 170 171 x2 = VB->Win[v2][0]; 172 y2 = VB->Win[v2][1]; 173 z2 = VB->Win[v2][2] / DEPTH_SCALE; 174 w2 = VB->Clip[v2][3]; 175 176 invq = (VB->TexCoord[v1][3]==0.0) ? 1.0 : (1.0F / VB->TexCoord[v1][3]); 177 tex1[0] = VB->TexCoord[v1][0] * invq; 178 tex1[1] = VB->TexCoord[v1][1] * invq; 179 tex1[2] = VB->TexCoord[v1][2] * invq; 180 tex1[3] = VB->TexCoord[v1][3]; 181 invq = (VB->TexCoord[v2][3]==0.0) ? 1.0 : (1.0F / VB->TexCoord[v2][3]); 182 tex2[0] = VB->TexCoord[v2][0] * invq; 183 tex2[1] = VB->TexCoord[v2][1] * invq; 184 tex2[2] = VB->TexCoord[v2][2] * invq; 185 tex2[3] = VB->TexCoord[v2][3]; 186 187 if (ctx->StippleCounter==0) { 188 FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_LINE_RESET_TOKEN ); 189 } 190 else { 191 FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_LINE_TOKEN ); 192 } 193 194 { 195 GLfloat color[4]; 196 /* convert color from integer to a float in [0,1] */ 197 color[0] = (GLfloat) VB->Color[pv][0] * invRedScale; 198 color[1] = (GLfloat) VB->Color[pv][1] * invGreenScale; 199 color[2] = (GLfloat) VB->Color[pv][2] * invBlueScale; 200 color[3] = (GLfloat) VB->Color[pv][3] * invAlphaScale; 201 gl_feedback_vertex( ctx, x1,y1,z1,w1, color, 202 (GLfloat) VB->Index[pv], tex1 ); 203 gl_feedback_vertex( ctx, x2,y2,z2,w2, color, 204 (GLfloat) VB->Index[pv], tex2 ); 205 } 206 207 ctx->StippleCounter++; 208 } 209 210 211 212 static void select_line( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv ) 213 { 214 gl_update_hitflag( ctx, ctx->VB->Win[v1][2] / DEPTH_SCALE ); 215 gl_update_hitflag( ctx, ctx->VB->Win[v2][2] / DEPTH_SCALE ); 216 } 217 218 219 220 #if MAX_WIDTH > MAX_HEIGHT 221 # define MAXPOINTS MAX_WIDTH 222 #else 223 # define MAXPOINTS MAX_HEIGHT 224 #endif 225 226 227 /* Flat, color index line */ 228 static void flat_ci_line( GLcontext *ctx, 229 GLuint vert0, GLuint vert1, GLuint pvert ) 230 { 231 GLint count; 232 GLint *pbx = ctx->PB->x; 233 GLint *pby = ctx->PB->y; 234 PB_SET_INDEX( ctx, ctx->PB, ctx->VB->Index[pvert] ); 235 count = ctx->PB->count; 236 237 #define INTERP_XY 1 238 239 #define PLOT(X,Y) \ 240 pbx[count] = X; \ 241 pby[count] = Y; \ 242 count++; 243 244 #include "linetemp.h" 245 246 ctx->PB->count = count; 247 PB_CHECK_FLUSH( ctx, ctx->PB ); 248 } 249 250 251 252 /* Flat, color index line with Z interpolation/testing */ 253 static void flat_ci_z_line( GLcontext *ctx, 254 GLuint vert0, GLuint vert1, GLuint pvert ) 255 { 256 GLint count; 257 GLint *pbx = ctx->PB->x; 258 GLint *pby = ctx->PB->y; 259 GLdepth *pbz = ctx->PB->z; 260 PB_SET_INDEX( ctx, ctx->PB, ctx->VB->Index[pvert] ); 261 count = ctx->PB->count; 262 263 #define INTERP_XY 1 264 #define INTERP_Z 1 265 266 #define PLOT(X,Y) \ 267 pbx[count] = X; \ 268 pby[count] = Y; \ 269 pbz[count] = Z; \ 270 count++; 271 272 #include "linetemp.h" 273 274 ctx->PB->count = count; 275 PB_CHECK_FLUSH( ctx, ctx->PB ); 276 } 277 278 279 280 /* Flat-shaded, RGBA line */ 281 static void flat_rgba_line( GLcontext *ctx, 282 GLuint vert0, GLuint vert1, GLuint pvert ) 283 { 284 GLint count; 285 GLint *pbx = ctx->PB->x; 286 GLint *pby = ctx->PB->y; 287 GLubyte *color = ctx->VB->Color[pvert]; 288 PB_SET_COLOR( ctx, ctx->PB, color[0], color[1], color[2], color[3] ); 289 count = ctx->PB->count; 290 291 #define INTERP_XY 1 292 293 #define PLOT(X,Y) \ 294 pbx[count] = X; \ 295 pby[count] = Y; \ 296 count++; 297 298 #include "linetemp.h" 299 300 ctx->PB->count = count; 301 PB_CHECK_FLUSH( ctx, ctx->PB ); 302 } 303 304 305 306 /* Flat-shaded, RGBA line with Z interpolation/testing */ 307 static void flat_rgba_z_line( GLcontext *ctx, 308 GLuint vert0, GLuint vert1, GLuint pvert ) 309 { 310 GLint count; 311 GLint *pbx = ctx->PB->x; 312 GLint *pby = ctx->PB->y; 313 GLdepth *pbz = ctx->PB->z; 314 GLubyte *color = ctx->VB->Color[pvert]; 315 PB_SET_COLOR( ctx, ctx->PB, color[0], color[1], color[2], color[3] ); 316 count = ctx->PB->count; 317 318 #define INTERP_XY 1 319 #define INTERP_Z 1 320 321 #define PLOT(X,Y) \ 322 pbx[count] = X; \ 323 pby[count] = Y; \ 324 pbz[count] = Z; \ 325 count++; 326 327 #include "linetemp.h" 328 329 ctx->PB->count = count; 330 PB_CHECK_FLUSH( ctx, ctx->PB ); 331 } 332 333 334 335 /* Smooth shaded, color index line */ 336 static void smooth_ci_line( GLcontext *ctx, 337 GLuint vert0, GLuint vert1, GLuint pvert ) 338 { 339 GLint count = ctx->PB->count; 340 GLint *pbx = ctx->PB->x; 341 GLint *pby = ctx->PB->y; 342 GLuint *pbi = ctx->PB->i; 343 344 #define INTERP_XY 1 345 #define INTERP_INDEX 1 346 347 #define PLOT(X,Y) \ 348 pbx[count] = X; \ 349 pby[count] = Y; \ 350 pbi[count] = I; \ 351 count++; 352 353 #include "linetemp.h" 354 355 ctx->PB->count = count; 356 PB_CHECK_FLUSH( ctx, ctx->PB ); 357 } 358 359 360 361 /* Smooth shaded, color index line with Z interpolation/testing */ 362 static void smooth_ci_z_line( GLcontext *ctx, 363 GLuint vert0, GLuint vert1, GLuint pvert ) 364 { 365 GLint count = ctx->PB->count; 366 GLint *pbx = ctx->PB->x; 367 GLint *pby = ctx->PB->y; 368 GLdepth *pbz = ctx->PB->z; 369 GLuint *pbi = ctx->PB->i; 370 371 #define INTERP_XY 1 372 #define INTERP_Z 1 373 #define INTERP_INDEX 1 374 375 #define PLOT(X,Y) \ 376 pbx[count] = X; \ 377 pby[count] = Y; \ 378 pbz[count] = Z; \ 379 pbi[count] = I; \ 380 count++; 381 382 #include "linetemp.h" 383 384 ctx->PB->count = count; 385 PB_CHECK_FLUSH( ctx, ctx->PB ); 386 } 387 388 389 390 /* Smooth-shaded, RGBA line */ 391 static void smooth_rgba_line( GLcontext *ctx, 392 GLuint vert0, GLuint vert1, GLuint pvert ) 393 { 394 GLint count = ctx->PB->count; 395 GLint *pbx = ctx->PB->x; 396 GLint *pby = ctx->PB->y; 397 GLubyte *pbr = ctx->PB->r; 398 GLubyte *pbg = ctx->PB->g; 399 GLubyte *pbb = ctx->PB->b; 400 GLubyte *pba = ctx->PB->a; 401 402 #define INTERP_XY 1 403 #define INTERP_RGB 1 404 #define INTERP_ALPHA 1 405 406 #define PLOT(X,Y) \ 407 pbx[count] = X; \ 408 pby[count] = Y; \ 409 pbr[count] = FixedToInt(r0); \ 410 pbg[count] = FixedToInt(g0); \ 411 pbb[count] = FixedToInt(b0); \ 412 pba[count] = FixedToInt(a0); \ 413 count++; 414 415 #include "linetemp.h" 416 417 ctx->PB->count = count; 418 PB_CHECK_FLUSH( ctx, ctx->PB ); 419 } 420 421 422 423 /* Smooth-shaded, RGBA line with Z interpolation/testing */ 424 static void smooth_rgba_z_line( GLcontext *ctx, 425 GLuint vert0, GLuint vert1, GLuint pvert ) 426 { 427 GLint count = ctx->PB->count; 428 GLint *pbx = ctx->PB->x; 429 GLint *pby = ctx->PB->y; 430 GLdepth *pbz = ctx->PB->z; 431 GLubyte *pbr = ctx->PB->r; 432 GLubyte *pbg = ctx->PB->g; 433 GLubyte *pbb = ctx->PB->b; 434 GLubyte *pba = ctx->PB->a; 435 436 #define INTERP_XY 1 437 #define INTERP_Z 1 438 #define INTERP_RGB 1 439 #define INTERP_ALPHA 1 440 441 #define PLOT(X,Y) \ 442 pbx[count] = X; \ 443 pby[count] = Y; \ 444 pbz[count] = Z; \ 445 pbr[count] = FixedToInt(r0); \ 446 pbg[count] = FixedToInt(g0); \ 447 pbb[count] = FixedToInt(b0); \ 448 pba[count] = FixedToInt(a0); \ 449 count++; 450 451 #include "linetemp.h" 452 453 ctx->PB->count = count; 454 PB_CHECK_FLUSH( ctx, ctx->PB ); 455 } 456 457 458 #define CHECK_FULL(count) \ 459 if (count >= PB_SIZE-MAX_WIDTH) { \ 460 ctx->PB->count = count; \ 461 gl_flush_pb(ctx); \ 462 count = ctx->PB->count; \ 463 } 464 465 466 467 /* Smooth shaded, color index, any width, maybe stippled */ 468 static void general_smooth_ci_line( GLcontext *ctx, 469 GLuint vert0, GLuint vert1, GLuint pvert ) 470 { 471 GLint count = ctx->PB->count; 472 GLint *pbx = ctx->PB->x; 473 GLint *pby = ctx->PB->y; 474 GLdepth *pbz = ctx->PB->z; 475 GLuint *pbi = ctx->PB->i; 476 477 if (ctx->Line.StippleFlag) { 478 /* stippled */ 479 #define INTERP_XY 1 480 #define INTERP_Z 1 481 #define INTERP_INDEX 1 482 #define WIDE 1 483 #define STIPPLE 1 484 #define PLOT(X,Y) \ 485 pbx[count] = X; \ 486 pby[count] = Y; \ 487 pbz[count] = Z; \ 488 pbi[count] = I; \ 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_INDEX 1 500 #define XMAJOR_PLOT(X,Y) \ 501 pbx[count] = X; pbx[count+1] = X; \ 502 pby[count] = Y; pby[count+1] = Y+1; \ 503 pbz[count] = Z; pbz[count+1] = Z; \ 504 pbi[count] = I; pbi[count+1] = I; \ 505 count += 2; 506 #define YMAJOR_PLOT(X,Y) \ 507 pbx[count] = X; pbx[count+1] = X+1; \ 508 pby[count] = Y; pby[count+1] = Y; \ 509 pbz[count] = Z; pbz[count+1] = Z; \ 510 pbi[count] = I; pbi[count+1] = I; \ 511 count += 2; 512 #include "linetemp.h" 513 } 514 else { 515 /* unstippled, any width */ 516 #define INTERP_XY 1 517 #define INTERP_Z 1 518 #define INTERP_INDEX 1 519 #define WIDE 1 520 #define PLOT(X,Y) \ 521 pbx[count] = X; \ 522 pby[count] = Y; \ 523 pbz[count] = Z; \ 524 pbi[count] = I; \ 525 count++; \ 526 CHECK_FULL(count); 527 #include "linetemp.h" 528 } 529 } 530 531 ctx->PB->count = count; 532 PB_CHECK_FLUSH( ctx, ctx->PB ); 533 } 534 535 536 /* Flat shaded, color index, any width, maybe stippled */ 537 static void general_flat_ci_line( GLcontext *ctx, 538 GLuint vert0, GLuint vert1, GLuint pvert ) 539 { 540 GLint count; 541 GLint *pbx = ctx->PB->x; 542 GLint *pby = ctx->PB->y; 543 GLdepth *pbz = ctx->PB->z; 544 PB_SET_INDEX( ctx, ctx->PB, ctx->VB->Index[pvert] ); 545 count = ctx->PB->count; 546 547 if (ctx->Line.StippleFlag) { 548 /* stippled, any width */ 549 #define INTERP_XY 1 550 #define INTERP_Z 1 551 #define WIDE 1 552 #define STIPPLE 1 553 #define PLOT(X,Y) \ 554 pbx[count] = X; \ 555 pby[count] = Y; \ 556 pbz[count] = Z; \ 557 count++; \ 558 CHECK_FULL(count); 559 #include "linetemp.h" 560 } 561 else { 562 /* unstippled */ 563 if (ctx->Line.Width==2.0F) { 564 /* special case: unstippled and width=2 */ 565 #define INTERP_XY 1 566 #define INTERP_Z 1 567 #define XMAJOR_PLOT(X,Y) \ 568 pbx[count] = X; pbx[count+1] = X; \ 569 pby[count] = Y; pby[count+1] = Y+1; \ 570 pbz[count] = Z; pbz[count+1] = Z; \ 571 count += 2; 572 #define YMAJOR_PLOT(X,Y) \ 573 pbx[count] = X; pbx[count+1] = X+1; \ 574 pby[count] = Y; pby[count+1] = Y; \ 575 pbz[count] = Z; pbz[count+1] = Z; \ 576 count += 2; 577 #include "linetemp.h" 578 } 579 else { 580 /* unstippled, any width */ 581 #define INTERP_XY 1 582 #define INTERP_Z 1 583 #define WIDE 1 584 #define PLOT(X,Y) \ 585 pbx[count] = X; \ 586 pby[count] = Y; \ 587 pbz[count] = Z; \ 588 count++; \ 589 CHECK_FULL(count); 590 #include "linetemp.h" 591 } 592 } 593 594 ctx->PB->count = count; 595 PB_CHECK_FLUSH( ctx, ctx->PB ); 596 } 597 598 599 600 static void general_smooth_rgba_line( GLcontext *ctx, 601 GLuint vert0, GLuint vert1, GLuint pvert) 602 { 603 GLint count = ctx->PB->count; 604 GLint *pbx = ctx->PB->x; 605 GLint *pby = ctx->PB->y; 606 GLdepth *pbz = ctx->PB->z; 607 GLubyte *pbr = ctx->PB->r; 608 GLubyte *pbg = ctx->PB->g; 609 GLubyte *pbb = ctx->PB->b; 610 GLubyte *pba = ctx->PB->a; 611 612 TRACE("Line %3.1f, %3.1f, %3.1f (r%u, g%u, b%u) --> %3.1f, %3.1f, %3.1f (r%u, g%u, b%u)\n", 613 ctx->VB->Win[vert0][0], ctx->VB->Win[vert0][1], ctx->VB->Win[vert0][2], ctx->VB->Color[vert0][0], ctx->VB->Color[vert0][1], ctx->VB->Color[vert0][2], 614 ctx->VB->Win[vert1][0], ctx->VB->Win[vert1][1], ctx->VB->Win[vert1][2], ctx->VB->Color[vert1][0], ctx->VB->Color[vert1][1], ctx->VB->Color[vert1][2]); 615 616 if (ctx->Line.StippleFlag) { 617 /* stippled */ 618 #define INTERP_XY 1 619 #define INTERP_Z 1 620 #define INTERP_RGB 1 621 #define INTERP_ALPHA 1 622 #define WIDE 1 623 #define STIPPLE 1 624 #define PLOT(X,Y) \ 625 pbx[count] = X; \ 626 pby[count] = Y; \ 627 pbz[count] = Z; \ 628 pbr[count] = FixedToInt(r0); \ 629 pbg[count] = FixedToInt(g0); \ 630 pbb[count] = FixedToInt(b0); \ 631 pba[count] = FixedToInt(a0); \ 632 count++; \ 633 CHECK_FULL(count); 634 #include "linetemp.h" 635 } 636 else { 637 /* unstippled */ 638 if (ctx->Line.Width==2.0F) { 639 /* special case: unstippled and width=2 */ 640 #define INTERP_XY 1 641 #define INTERP_Z 1 642 #define INTERP_RGB 1 643 #define INTERP_ALPHA 1 644 #define XMAJOR_PLOT(X,Y) \ 645 pbx[count] = X; pbx[count+1] = X; \ 646 pby[count] = Y; pby[count+1] = Y+1; \ 647 pbz[count] = Z; pbz[count+1] = Z; \ 648 pbr[count] = FixedToInt(r0); pbr[count+1] = FixedToInt(r0); \ 649 pbg[count] = FixedToInt(g0); pbg[count+1] = FixedToInt(g0); \ 650 pbb[count] = FixedToInt(b0); pbb[count+1] = FixedToInt(b0); \ 651 pba[count] = FixedToInt(a0); pba[count+1] = FixedToInt(a0); \ 652 count += 2; 653 #define YMAJOR_PLOT(X,Y) \ 654 pbx[count] = X; pbx[count+1] = X+1; \ 655 pby[count] = Y; pby[count+1] = Y; \ 656 pbz[count] = Z; pbz[count+1] = Z; \ 657 pbr[count] = FixedToInt(r0); pbr[count+1] = FixedToInt(r0); \ 658 pbg[count] = FixedToInt(g0); pbg[count+1] = FixedToInt(g0); \ 659 pbb[count] = FixedToInt(b0); pbb[count+1] = FixedToInt(b0); \ 660 pba[count] = FixedToInt(a0); pba[count+1] = FixedToInt(a0); \ 661 count += 2; 662 #include "linetemp.h" 663 } 664 else { 665 /* unstippled, any width */ 666 #define INTERP_XY 1 667 #define INTERP_Z 1 668 #define INTERP_RGB 1 669 #define INTERP_ALPHA 1 670 #define WIDE 1 671 #define PLOT(X,Y) \ 672 pbx[count] = X; \ 673 pby[count] = Y; \ 674 pbz[count] = Z; \ 675 pbr[count] = FixedToInt(r0); \ 676 pbg[count] = FixedToInt(g0); \ 677 pbb[count] = FixedToInt(b0); \ 678 pba[count] = FixedToInt(a0); \ 679 count++; \ 680 CHECK_FULL(count); 681 #include "linetemp.h" 682 } 683 } 684 685 ctx->PB->count = count; 686 PB_CHECK_FLUSH( ctx, ctx->PB ); 687 } 688 689 690 static void general_flat_rgba_line( GLcontext *ctx, 691 GLuint vert0, GLuint vert1, GLuint pvert ) 692 { 693 GLint count; 694 GLint *pbx = ctx->PB->x; 695 GLint *pby = ctx->PB->y; 696 GLdepth *pbz = ctx->PB->z; 697 GLubyte *color = ctx->VB->Color[pvert]; 698 PB_SET_COLOR( ctx, ctx->PB, color[0], color[1], color[2], color[3] ); 699 count = ctx->PB->count; 700 701 if (ctx->Line.StippleFlag) { 702 /* stippled */ 703 #define INTERP_XY 1 704 #define INTERP_Z 1 705 #define WIDE 1 706 #define STIPPLE 1 707 #define PLOT(X,Y) \ 708 pbx[count] = X; \ 709 pby[count] = Y; \ 710 pbz[count] = Z; \ 711 count++; \ 712 CHECK_FULL(count); 713 #include "linetemp.h" 714 } 715 else { 716 /* unstippled */ 717 if (ctx->Line.Width==2.0F) { 718 /* special case: unstippled and width=2 */ 719 #define INTERP_XY 1 720 #define INTERP_Z 1 721 #define XMAJOR_PLOT(X,Y) \ 722 pbx[count] = X; pbx[count+1] = X; \ 723 pby[count] = Y; pby[count+1] = Y+1; \ 724 pbz[count] = Z; pbz[count+1] = Z; \ 725 count += 2; 726 #define YMAJOR_PLOT(X,Y) \ 727 pbx[count] = X; pbx[count+1] = X+1; \ 728 pby[count] = Y; pby[count+1] = Y; \ 729 pbz[count] = Z; pbz[count+1] = Z; \ 730 count += 2; 731 #include "linetemp.h" 732 } 733 else { 734 /* unstippled, any width */ 735 #define INTERP_XY 1 736 #define INTERP_Z 1 737 #define WIDE 1 738 #define PLOT(X,Y) \ 739 pbx[count] = X; \ 740 pby[count] = Y; \ 741 pbz[count] = Z; \ 742 count++; \ 743 CHECK_FULL(count); 744 #include "linetemp.h" 745 } 746 } 747 748 ctx->PB->count = count; 749 PB_CHECK_FLUSH( ctx, ctx->PB ); 750 } 751 752 753 754 /* Flat-shaded, textured, any width, maybe stippled */ 755 static void flat_textured_line( GLcontext *ctx, 756 GLuint vert0, GLuint vert1, GLuint pv ) 757 { 758 GLint count; 759 GLint *pbx = ctx->PB->x; 760 GLint *pby = ctx->PB->y; 761 GLdepth *pbz = ctx->PB->z; 762 GLfloat *pbs = ctx->PB->s; 763 GLfloat *pbt = ctx->PB->t; 764 GLfloat *pbu = ctx->PB->u; 765 GLubyte *color = ctx->VB->Color[pv]; 766 PB_SET_COLOR( ctx, ctx->PB, color[0], color[1], color[2], color[3] ); 767 count = ctx->PB->count; 768 769 if (ctx->Line.StippleFlag) { 770 /* stippled */ 771 #define INTERP_XY 1 772 #define INTERP_Z 1 773 #define INTERP_STW 1 774 #define INTERP_UV 1 775 #define WIDE 1 776 #define STIPPLE 1 777 #define PLOT(X,Y) \ 778 pbx[count] = X; \ 779 pby[count] = Y; \ 780 pbz[count] = Z; \ 781 pbs[count] = s0 / w0; \ 782 pbt[count] = t0 / w0; \ 783 pbu[count] = u0 / w0; \ 784 count++; \ 785 CHECK_FULL(count); 786 #include "linetemp.h" 787 } 788 else { 789 /* unstippled */ 790 #define INTERP_XY 1 791 #define INTERP_Z 1 792 #define INTERP_STW 1 793 #define INTERP_UV 1 794 #define WIDE 1 795 #define PLOT(X,Y) \ 796 pbx[count] = X; \ 797 pby[count] = Y; \ 798 pbz[count] = Z; \ 799 pbs[count] = s0 / w0; \ 800 pbt[count] = t0 / w0; \ 801 pbu[count] = u0 / w0; \ 802 count++; \ 803 CHECK_FULL(count); 804 #include "linetemp.h" 805 } 806 807 ctx->PB->count = count; 808 PB_CHECK_FLUSH( ctx, ctx->PB ); 809 } 810 811 812 813 /* Smooth-shaded, textured, any width, maybe stippled */ 814 static void smooth_textured_line( GLcontext *ctx, 815 GLuint vert0, GLuint vert1, GLuint pv ) 816 { 817 GLint count = ctx->PB->count; 818 GLint *pbx = ctx->PB->x; 819 GLint *pby = ctx->PB->y; 820 GLdepth *pbz = ctx->PB->z; 821 GLfloat *pbs = ctx->PB->s; 822 GLfloat *pbt = ctx->PB->t; 823 GLfloat *pbu = ctx->PB->u; 824 GLubyte *pbr = ctx->PB->r; 825 GLubyte *pbg = ctx->PB->g; 826 GLubyte *pbb = ctx->PB->b; 827 GLubyte *pba = ctx->PB->a; 828 829 if (ctx->Line.StippleFlag) { 830 /* stippled */ 831 #define INTERP_XY 1 832 #define INTERP_Z 1 833 #define INTERP_RGB 1 834 #define INTERP_ALPHA 1 835 #define INTERP_STW 1 836 #define INTERP_UV 1 837 #define WIDE 1 838 #define STIPPLE 1 839 #define PLOT(X,Y) \ 840 pbx[count] = X; \ 841 pby[count] = Y; \ 842 pbz[count] = Z; \ 843 pbs[count] = s0 / w0; \ 844 pbt[count] = t0 / w0; \ 845 pbu[count] = u0 / w0; \ 846 pbr[count] = FixedToInt(r0); \ 847 pbg[count] = FixedToInt(g0); \ 848 pbb[count] = FixedToInt(b0); \ 849 pba[count] = FixedToInt(a0); \ 850 count++; \ 851 CHECK_FULL(count); 852 #include "linetemp.h" 853 } 854 else { 855 /* unstippled */ 856 #define INTERP_XY 1 857 #define INTERP_Z 1 858 #define INTERP_RGB 1 859 #define INTERP_ALPHA 1 860 #define INTERP_STW 1 861 #define INTERP_UV 1 862 #define WIDE 1 863 #define PLOT(X,Y) \ 864 pbx[count] = X; \ 865 pby[count] = Y; \ 866 pbz[count] = Z; \ 867 pbs[count] = s0 / w0; \ 868 pbt[count] = t0 / w0; \ 869 pbu[count] = u0 / w0; \ 870 pbr[count] = FixedToInt(r0); \ 871 pbg[count] = FixedToInt(g0); \ 872 pbb[count] = FixedToInt(b0); \ 873 pba[count] = FixedToInt(a0); \ 874 count++; \ 875 CHECK_FULL(count); 876 #include "linetemp.h" 877 } 878 879 ctx->PB->count = count; 880 PB_CHECK_FLUSH( ctx, ctx->PB ); 881 } 882 883 884 885 /* 886 * Null rasterizer for measuring transformation speed. 887 */ 888 static void null_line( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv ) 889 { 890 } 891 892 893 894 /* 895 * Determine which line drawing function to use given the current 896 * rendering context. 897 */ 898 void gl_set_line_function( GLcontext *ctx ) 899 { 900 GLboolean rgbmode = ctx->Visual->RGBAflag; 901 /* TODO: antialiased lines */ 902 903 if (ctx->RenderMode==GL_RENDER) { 904 if (ctx->NoRaster) { 905 ctx->Driver.LineFunc = null_line; 906 return; 907 } 908 if (ctx->Driver.LineFunc) { 909 /* Device driver will draw lines. */ 910 ctx->Driver.LineFunc = ctx->Driver.LineFunc; 911 } 912 else if (ctx->Texture.Enabled) { 913 if (ctx->Light.ShadeModel==GL_SMOOTH) { 914 ctx->Driver.LineFunc = smooth_textured_line; 915 } 916 else { 917 ctx->Driver.LineFunc = flat_textured_line; 918 } 919 } 920 else if (ctx->Line.Width!=1.0 || ctx->Line.StippleFlag 921 || ctx->Line.SmoothFlag || ctx->Texture.Enabled) { 922 if (ctx->Light.ShadeModel==GL_SMOOTH) { 923 if (rgbmode) 924 ctx->Driver.LineFunc = general_smooth_rgba_line; 925 else 926 ctx->Driver.LineFunc = general_smooth_ci_line; 927 } 928 else { 929 if (rgbmode) 930 ctx->Driver.LineFunc = general_flat_rgba_line; 931 else 932 ctx->Driver.LineFunc = general_flat_ci_line; 933 } 934 } 935 else { 936 if (ctx->Light.ShadeModel==GL_SMOOTH) { 937 /* Width==1, non-stippled, smooth-shaded */ 938 if (ctx->Depth.Test 939 || (ctx->Fog.Enabled && ctx->Hint.Fog==GL_NICEST)) { 940 if (rgbmode) 941 ctx->Driver.LineFunc = smooth_rgba_z_line; 942 else 943 ctx->Driver.LineFunc = smooth_ci_z_line; 944 } 945 else { 946 if (rgbmode) 947 ctx->Driver.LineFunc = smooth_rgba_line; 948 else 949 ctx->Driver.LineFunc = smooth_ci_line; 950 } 951 } 952 else { 953 /* Width==1, non-stippled, flat-shaded */ 954 if (ctx->Depth.Test 955 || (ctx->Fog.Enabled && ctx->Hint.Fog==GL_NICEST)) { 956 if (rgbmode) 957 ctx->Driver.LineFunc = flat_rgba_z_line; 958 else 959 ctx->Driver.LineFunc = flat_ci_z_line; 960 } 961 else { 962 if (rgbmode) 963 ctx->Driver.LineFunc = flat_rgba_line; 964 else 965 ctx->Driver.LineFunc = flat_ci_line; 966 } 967 } 968 } 969 } 970 else if (ctx->RenderMode==GL_FEEDBACK) { 971 ctx->Driver.LineFunc = feedback_line; 972 } 973 else { 974 /* GL_SELECT mode */ 975 ctx->Driver.LineFunc = select_line; 976 } 977 } 978 979