add callbacks for stipple
[mesa.git] / src / mesa / main / lines.c
1 /* $Id: lines.c,v 1.8 2000/02/27 20:38:15 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 if (ctx->Driver.LineStipple)
76 ctx->Driver.LineStipple( ctx, factor, pattern );
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 */
114 static 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 gl_flush_pb(ctx);
134 }
135
136
137
138 /* Flat, color index line with Z interpolation/testing */
139 static 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 gl_flush_pb(ctx);
162 }
163
164
165
166 /* Flat-shaded, RGBA line */
167 static 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 gl_flush_pb(ctx);
188 }
189
190
191
192 /* Flat-shaded, RGBA line with Z interpolation/testing */
193 static 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 gl_flush_pb(ctx);
217 }
218
219
220
221 /* Smooth shaded, color index line */
222 static 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 gl_flush_pb(ctx);
244 }
245
246
247
248 /* Smooth shaded, color index line with Z interpolation/testing */
249 static 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 gl_flush_pb(ctx);
274 }
275
276
277
278 /* Smooth-shaded, RGBA line */
279 static 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 gl_flush_pb(ctx);
305 }
306
307
308
309 /* Smooth-shaded, RGBA line with Z interpolation/testing */
310 static 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 gl_flush_pb(ctx);
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 */
352 static 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 gl_flush_pb(ctx);
420 }
421
422
423 /* Flat shaded, color index, any width, maybe stippled */
424 static 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 gl_flush_pb(ctx);
485 }
486
487
488
489 static 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 gl_flush_pb(ctx);
580 }
581
582
583 static 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 gl_flush_pb(ctx);
645 }
646
647
648 /* Flat-shaded, textured, any width, maybe stippled */
649 static 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 gl_flush_pb(ctx);
705 }
706
707
708
709 /* Smooth-shaded, textured, any width, maybe stippled */
710 static 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 gl_flush_pb(ctx);
777 }
778
779
780 /* Smooth-shaded, multitextured, any width, maybe stippled, separate specular
781 * color interpolation.
782 */
783 static 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 gl_flush_pb(ctx);
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 */
880 static 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 */
895 static 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 */
916 static 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 */
936 static 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 */
951 static 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 */
964 void 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 || ctx->FogMode == FOG_FRAGMENT) {
1031 if (rgbmode)
1032 ctx->Driver.LineFunc = smooth_rgba_z_line;
1033 else
1034 ctx->Driver.LineFunc = smooth_ci_z_line;
1035 }
1036 else {
1037 if (rgbmode)
1038 ctx->Driver.LineFunc = smooth_rgba_line;
1039 else
1040 ctx->Driver.LineFunc = smooth_ci_line;
1041 }
1042 }
1043 else {
1044 /* Width==1, non-stippled, flat-shaded */
1045 if (ctx->Depth.Test || ctx->FogMode == FOG_FRAGMENT) {
1046 if (rgbmode)
1047 ctx->Driver.LineFunc = flat_rgba_z_line;
1048 else
1049 ctx->Driver.LineFunc = flat_ci_z_line;
1050 }
1051 else {
1052 if (rgbmode)
1053 ctx->Driver.LineFunc = flat_rgba_line;
1054 else
1055 ctx->Driver.LineFunc = flat_ci_line;
1056 }
1057 }
1058 }
1059 }
1060 else if (ctx->RenderMode==GL_FEEDBACK) {
1061 ctx->Driver.LineFunc = gl_feedback_line;
1062 }
1063 else {
1064 /* GL_SELECT mode */
1065 ctx->Driver.LineFunc = gl_select_line;
1066 }
1067 }
1068