Fog coordinate stage which drivers may use to replace standard fogging
[mesa.git] / src / mesa / main / lines.c
1 /* $Id: lines.c,v 1.7 2000/02/25 03:55:40 keithw 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
46 void
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
66 void
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 */
111 static 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 */
136 static 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 */
164 static 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 */
190 static 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 */
219 static 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 */
246 static 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 */
276 static 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 */
307 static 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 */
349 static 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 */
421 static 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
486 static 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
580 static 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 */
646 static 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 */
707 static 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 */
780 static 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 */
877 static 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 */
892 static 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 */
913 static 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 */
933 static 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 */
948 static 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 */
961 void 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 || ctx->FogMode == FOG_FRAGMENT) {
1028 if (rgbmode)
1029 ctx->Driver.LineFunc = smooth_rgba_z_line;
1030 else
1031 ctx->Driver.LineFunc = smooth_ci_z_line;
1032 }
1033 else {
1034 if (rgbmode)
1035 ctx->Driver.LineFunc = smooth_rgba_line;
1036 else
1037 ctx->Driver.LineFunc = smooth_ci_line;
1038 }
1039 }
1040 else {
1041 /* Width==1, non-stippled, flat-shaded */
1042 if (ctx->Depth.Test || ctx->FogMode == FOG_FRAGMENT) {
1043 if (rgbmode)
1044 ctx->Driver.LineFunc = flat_rgba_z_line;
1045 else
1046 ctx->Driver.LineFunc = flat_ci_z_line;
1047 }
1048 else {
1049 if (rgbmode)
1050 ctx->Driver.LineFunc = flat_rgba_line;
1051 else
1052 ctx->Driver.LineFunc = flat_ci_line;
1053 }
1054 }
1055 }
1056 }
1057 else if (ctx->RenderMode==GL_FEEDBACK) {
1058 ctx->Driver.LineFunc = gl_feedback_line;
1059 }
1060 else {
1061 /* GL_SELECT mode */
1062 ctx->Driver.LineFunc = gl_select_line;
1063 }
1064 }
1065