fixed PB bugs, removed MutablePixels, MonoPixels from GLcontext
[mesa.git] / src / mesa / main / lines.c
1 /* $Id: lines.c,v 1.10 2000/05/10 22:36:05 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
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 if (ctx->Driver.LineWidth)
62 (*ctx->Driver.LineWidth)(ctx, width);
63 }
64 }
65
66
67
68 void
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 */
116 static 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 */
132 static 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 */
149 static 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 */
166 static 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 */
184 static 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 */
213 static 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 */
245 static 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 */
278 static 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 */
322 static 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 */
396 static 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
461 static 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
557 static void general_flat_rgba_line( GLcontext *ctx,
558 GLuint vert0, GLuint vert1, GLuint pvert )
559 {
560 GLint count;
561 GLint *pbx = ctx->PB->x;
562 GLint *pby = ctx->PB->y;
563 GLdepth *pbz = ctx->PB->z;
564 GLubyte *color = ctx->VB->ColorPtr->data[pvert];
565 PB_SET_COLOR( ctx->PB, color[0], color[1], color[2], color[3] );
566 count = ctx->PB->count;
567
568 if (ctx->Line.StippleFlag) {
569 /* stippled */
570 #define INTERP_XY 1
571 #define INTERP_Z 1
572 #define WIDE 1
573 #define STIPPLE 1
574 #define PLOT(X,Y) \
575 pbx[count] = X; \
576 pby[count] = Y; \
577 pbz[count] = Z; \
578 count++; \
579 CHECK_FULL(count);
580 #include "linetemp.h"
581 }
582 else {
583 /* unstippled */
584 if (ctx->Line.Width==2.0F) {
585 /* special case: unstippled and width=2 */
586 #define INTERP_XY 1
587 #define INTERP_Z 1
588 #define XMAJOR_PLOT(X,Y) \
589 pbx[count] = X; pbx[count+1] = X; \
590 pby[count] = Y; pby[count+1] = Y+1; \
591 pbz[count] = Z; pbz[count+1] = Z; \
592 count += 2; \
593 CHECK_FULL(count);
594 #define YMAJOR_PLOT(X,Y) \
595 pbx[count] = X; pbx[count+1] = X+1; \
596 pby[count] = Y; pby[count+1] = Y; \
597 pbz[count] = Z; pbz[count+1] = Z; \
598 count += 2; \
599 CHECK_FULL(count);
600 #include "linetemp.h"
601 }
602 else {
603 /* unstippled, any width */
604 #define INTERP_XY 1
605 #define INTERP_Z 1
606 #define WIDE 1
607 #define PLOT(X,Y) \
608 pbx[count] = X; \
609 pby[count] = Y; \
610 pbz[count] = Z; \
611 count++; \
612 CHECK_FULL(count);
613 #include "linetemp.h"
614 }
615 }
616
617 ctx->PB->count = count;
618 gl_flush_pb(ctx);
619 }
620
621
622 /* Flat-shaded, textured, any width, maybe stippled */
623 static void flat_textured_line( GLcontext *ctx,
624 GLuint vert0, GLuint vert1, GLuint pv )
625 {
626 GLint count;
627 GLint *pbx = ctx->PB->x;
628 GLint *pby = ctx->PB->y;
629 GLdepth *pbz = ctx->PB->z;
630 GLfloat *pbs = ctx->PB->s[0];
631 GLfloat *pbt = ctx->PB->t[0];
632 GLfloat *pbu = ctx->PB->u[0];
633 GLubyte *color = ctx->VB->ColorPtr->data[pv];
634 PB_SET_COLOR( ctx->PB, color[0], color[1], color[2], color[3] );
635 count = ctx->PB->count;
636
637 if (ctx->Line.StippleFlag) {
638 /* stippled */
639 #define INTERP_XY 1
640 #define INTERP_Z 1
641 #define INTERP_STUV0 1
642 #define WIDE 1
643 #define STIPPLE 1
644 #define PLOT(X,Y) \
645 { \
646 pbx[count] = X; \
647 pby[count] = Y; \
648 pbz[count] = Z; \
649 pbs[count] = s; \
650 pbt[count] = t; \
651 pbu[count] = u; \
652 count++; \
653 CHECK_FULL(count); \
654 }
655 #include "linetemp.h"
656 }
657 else {
658 /* unstippled */
659 #define INTERP_XY 1
660 #define INTERP_Z 1
661 #define INTERP_STUV0 1
662 #define WIDE 1
663 #define PLOT(X,Y) \
664 { \
665 pbx[count] = X; \
666 pby[count] = Y; \
667 pbz[count] = Z; \
668 pbs[count] = s; \
669 pbt[count] = t; \
670 pbu[count] = u; \
671 count++; \
672 CHECK_FULL(count); \
673 }
674 #include "linetemp.h"
675 }
676
677 ctx->PB->count = count;
678 gl_flush_pb(ctx);
679 }
680
681
682
683 /* Smooth-shaded, textured, any width, maybe stippled */
684 static void smooth_textured_line( GLcontext *ctx,
685 GLuint vert0, GLuint vert1, GLuint pvert )
686 {
687 GLint count = ctx->PB->count;
688 GLint *pbx = ctx->PB->x;
689 GLint *pby = ctx->PB->y;
690 GLdepth *pbz = ctx->PB->z;
691 GLfloat *pbs = ctx->PB->s[0];
692 GLfloat *pbt = ctx->PB->t[0];
693 GLfloat *pbu = ctx->PB->u[0];
694 GLubyte (*pbrgba)[4] = ctx->PB->rgba;
695 (void) pvert;
696
697 ctx->PB->mono = GL_FALSE;
698
699 if (ctx->Line.StippleFlag) {
700 /* stippled */
701 #define INTERP_XY 1
702 #define INTERP_Z 1
703 #define INTERP_RGB 1
704 #define INTERP_ALPHA 1
705 #define INTERP_STUV0 1
706 #define WIDE 1
707 #define STIPPLE 1
708 #define PLOT(X,Y) \
709 { \
710 pbx[count] = X; \
711 pby[count] = Y; \
712 pbz[count] = Z; \
713 pbs[count] = s; \
714 pbt[count] = t; \
715 pbu[count] = u; \
716 pbrgba[count][RCOMP] = FixedToInt(r0); \
717 pbrgba[count][GCOMP] = FixedToInt(g0); \
718 pbrgba[count][BCOMP] = FixedToInt(b0); \
719 pbrgba[count][ACOMP] = FixedToInt(a0); \
720 count++; \
721 CHECK_FULL(count); \
722 }
723 #include "linetemp.h"
724 }
725 else {
726 /* unstippled */
727 #define INTERP_XY 1
728 #define INTERP_Z 1
729 #define INTERP_RGB 1
730 #define INTERP_ALPHA 1
731 #define INTERP_STUV0 1
732 #define WIDE 1
733 #define PLOT(X,Y) \
734 { \
735 pbx[count] = X; \
736 pby[count] = Y; \
737 pbz[count] = Z; \
738 pbs[count] = s; \
739 pbt[count] = t; \
740 pbu[count] = u; \
741 pbrgba[count][RCOMP] = FixedToInt(r0); \
742 pbrgba[count][GCOMP] = FixedToInt(g0); \
743 pbrgba[count][BCOMP] = FixedToInt(b0); \
744 pbrgba[count][ACOMP] = FixedToInt(a0); \
745 count++; \
746 CHECK_FULL(count); \
747 }
748 #include "linetemp.h"
749 }
750
751 ctx->PB->count = count;
752 gl_flush_pb(ctx);
753 }
754
755
756 /* Smooth-shaded, multitextured, any width, maybe stippled, separate specular
757 * color interpolation.
758 */
759 static void smooth_multitextured_line( GLcontext *ctx,
760 GLuint vert0, GLuint vert1, GLuint pvert )
761 {
762 GLint count = ctx->PB->count;
763 GLint *pbx = ctx->PB->x;
764 GLint *pby = ctx->PB->y;
765 GLdepth *pbz = ctx->PB->z;
766 GLfloat *pbs = ctx->PB->s[0];
767 GLfloat *pbt = ctx->PB->t[0];
768 GLfloat *pbu = ctx->PB->u[0];
769 GLfloat *pbs1 = ctx->PB->s[1];
770 GLfloat *pbt1 = ctx->PB->t[1];
771 GLfloat *pbu1 = ctx->PB->u[1];
772 GLubyte (*pbrgba)[4] = ctx->PB->rgba;
773 GLubyte (*pbspec)[3] = ctx->PB->spec;
774 (void) pvert;
775
776 ctx->PB->mono = GL_FALSE;
777
778 if (ctx->Line.StippleFlag) {
779 /* stippled */
780 #define INTERP_XY 1
781 #define INTERP_Z 1
782 #define INTERP_RGB 1
783 #define INTERP_SPEC 1
784 #define INTERP_ALPHA 1
785 #define INTERP_STUV0 1
786 #define INTERP_STUV1 1
787 #define WIDE 1
788 #define STIPPLE 1
789 #define PLOT(X,Y) \
790 { \
791 pbx[count] = X; \
792 pby[count] = Y; \
793 pbz[count] = Z; \
794 pbs[count] = s; \
795 pbt[count] = t; \
796 pbu[count] = u; \
797 pbs1[count] = s1; \
798 pbt1[count] = t1; \
799 pbu1[count] = u1; \
800 pbrgba[count][RCOMP] = FixedToInt(r0); \
801 pbrgba[count][GCOMP] = FixedToInt(g0); \
802 pbrgba[count][BCOMP] = FixedToInt(b0); \
803 pbrgba[count][ACOMP] = FixedToInt(a0); \
804 pbspec[count][RCOMP] = FixedToInt(sr0); \
805 pbspec[count][GCOMP] = FixedToInt(sg0); \
806 pbspec[count][BCOMP] = FixedToInt(sb0); \
807 count++; \
808 CHECK_FULL(count); \
809 }
810 #include "linetemp.h"
811 }
812 else {
813 /* unstippled */
814 #define INTERP_XY 1
815 #define INTERP_Z 1
816 #define INTERP_RGB 1
817 #define INTERP_SPEC 1
818 #define INTERP_ALPHA 1
819 #define INTERP_STUV0 1
820 #define INTERP_STUV1 1
821 #define WIDE 1
822 #define PLOT(X,Y) \
823 { \
824 pbx[count] = X; \
825 pby[count] = Y; \
826 pbz[count] = Z; \
827 pbs[count] = s; \
828 pbt[count] = t; \
829 pbu[count] = u; \
830 pbs1[count] = s1; \
831 pbt1[count] = t1; \
832 pbu1[count] = u1; \
833 pbrgba[count][RCOMP] = FixedToInt(r0); \
834 pbrgba[count][GCOMP] = FixedToInt(g0); \
835 pbrgba[count][BCOMP] = FixedToInt(b0); \
836 pbrgba[count][ACOMP] = FixedToInt(a0); \
837 pbspec[count][RCOMP] = FixedToInt(sr0); \
838 pbspec[count][GCOMP] = FixedToInt(sg0); \
839 pbspec[count][BCOMP] = FixedToInt(sb0); \
840 count++; \
841 CHECK_FULL(count); \
842 }
843 #include "linetemp.h"
844 }
845
846 ctx->PB->count = count;
847 gl_flush_pb(ctx);
848 }
849
850
851 /*
852 * Antialiased RGBA line
853 *
854 * This AA line function isn't terribly efficient but it's pretty
855 * straight-forward to understand. Also, it doesn't exactly conform
856 * to the specification.
857 */
858 static void aa_rgba_line( GLcontext *ctx,
859 GLuint vert0, GLuint vert1, GLuint pvert )
860 {
861 #define INTERP_RGBA 1
862 #define PLOT(x, y) { PB_WRITE_RGBA_PIXEL( pb, (x), (y), z, red, green, blue, coverage ); }
863 #include "lnaatemp.h"
864 }
865
866 /*
867 * Antialiased Textured RGBA line
868 *
869 * This AA line function isn't terribly efficient but it's pretty
870 * straight-forward to understand. Also, it doesn't exactly conform
871 * to the specification.
872 */
873 static void aa_tex_rgba_line( GLcontext *ctx,
874 GLuint vert0, GLuint vert1, GLuint pvert )
875 {
876 #define INTERP_RGBA 1
877 #define INTERP_STUV0 1
878 #define PLOT(x, y) \
879 { \
880 PB_WRITE_TEX_PIXEL( pb, (x), (y), z, red, green, blue, coverage, \
881 s, t, u ); \
882 }
883 #include "lnaatemp.h"
884 }
885
886
887 /*
888 * Antialiased Multitextured RGBA line
889 *
890 * This AA line function isn't terribly efficient but it's pretty
891 * straight-forward to understand. Also, it doesn't exactly conform
892 * to the specification.
893 */
894 static void aa_multitex_rgba_line( GLcontext *ctx,
895 GLuint vert0, GLuint vert1, GLuint pvert )
896 {
897 #define INTERP_RGBA 1
898 #define INTERP_SPEC 1
899 #define INTERP_STUV0 1
900 #define INTERP_STUV1 1
901 #define PLOT(x, y) \
902 { \
903 PB_WRITE_MULTITEX_SPEC_PIXEL( pb, (x), (y), z, \
904 red, green, blue, coverage, specRed, specGreen, specBlue, \
905 s, t, u, s1, t1, u1 ); \
906 }
907 #include "lnaatemp.h"
908 }
909
910
911 /*
912 * Antialiased CI line. Same comments for RGBA antialiased lines apply.
913 */
914 static void aa_ci_line( GLcontext *ctx,
915 GLuint vert0, GLuint vert1, GLuint pvert )
916 {
917 #define INTERP_INDEX 1
918 #define PLOT(x, y) \
919 { \
920 PB_WRITE_CI_PIXEL( pb, (x), (y), z, index + coverage ); \
921 }
922 #include "lnaatemp.h"
923 }
924
925
926 /*
927 * Null rasterizer for measuring transformation speed.
928 */
929 static void null_line( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv )
930 {
931 (void) ctx;
932 (void) v1;
933 (void) v2;
934 (void) pv;
935 }
936
937
938 /*
939 * Determine which line drawing function to use given the current
940 * rendering context.
941 */
942 void gl_set_line_function( GLcontext *ctx )
943 {
944 GLboolean rgbmode = ctx->Visual->RGBAflag;
945 /* TODO: antialiased lines */
946
947 if (ctx->RenderMode==GL_RENDER) {
948 if (ctx->NoRaster) {
949 ctx->Driver.LineFunc = null_line;
950 return;
951 }
952 if (ctx->Driver.LineFunc) {
953 /* Device driver will draw lines. */
954 return;
955 }
956
957 if (ctx->Line.SmoothFlag) {
958 /* antialiased lines */
959 if (rgbmode) {
960 if (ctx->Texture.ReallyEnabled) {
961 if (ctx->Texture.ReallyEnabled >= TEXTURE1_1D
962 || ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR)
963 /* Multitextured! */
964 ctx->Driver.LineFunc = aa_multitex_rgba_line;
965 else
966 ctx->Driver.LineFunc = aa_tex_rgba_line;
967 } else {
968 ctx->Driver.LineFunc = aa_rgba_line;
969 }
970 }
971 else {
972 ctx->Driver.LineFunc = aa_ci_line;
973 }
974 }
975 else if (ctx->Texture.ReallyEnabled) {
976 if (ctx->Texture.ReallyEnabled >= TEXTURE1_1D
977 || ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR) {
978 /* multi-texture and/or separate specular color */
979 ctx->Driver.LineFunc = smooth_multitextured_line;
980 }
981 else {
982 if (ctx->Light.ShadeModel==GL_SMOOTH) {
983 ctx->Driver.LineFunc = smooth_textured_line;
984 }
985 else {
986 ctx->Driver.LineFunc = flat_textured_line;
987 }
988 }
989 }
990 else if (ctx->Line.Width!=1.0 || ctx->Line.StippleFlag
991 || ctx->Line.SmoothFlag) {
992 if (ctx->Light.ShadeModel==GL_SMOOTH) {
993 if (rgbmode)
994 ctx->Driver.LineFunc = general_smooth_rgba_line;
995 else
996 ctx->Driver.LineFunc = general_smooth_ci_line;
997 }
998 else {
999 if (rgbmode)
1000 ctx->Driver.LineFunc = general_flat_rgba_line;
1001 else
1002 ctx->Driver.LineFunc = general_flat_ci_line;
1003 }
1004 }
1005 else {
1006 if (ctx->Light.ShadeModel==GL_SMOOTH) {
1007 /* Width==1, non-stippled, smooth-shaded */
1008 if (ctx->Depth.Test || ctx->FogMode == FOG_FRAGMENT) {
1009 if (rgbmode)
1010 ctx->Driver.LineFunc = smooth_rgba_z_line;
1011 else
1012 ctx->Driver.LineFunc = smooth_ci_z_line;
1013 }
1014 else {
1015 if (rgbmode)
1016 ctx->Driver.LineFunc = smooth_rgba_line;
1017 else
1018 ctx->Driver.LineFunc = smooth_ci_line;
1019 }
1020 }
1021 else {
1022 /* Width==1, non-stippled, flat-shaded */
1023 if (ctx->Depth.Test || ctx->FogMode == FOG_FRAGMENT) {
1024 if (rgbmode)
1025 ctx->Driver.LineFunc = flat_rgba_z_line;
1026 else
1027 ctx->Driver.LineFunc = flat_ci_z_line;
1028 }
1029 else {
1030 if (rgbmode)
1031 ctx->Driver.LineFunc = flat_rgba_line;
1032 else
1033 ctx->Driver.LineFunc = flat_ci_line;
1034 }
1035 }
1036 }
1037 }
1038 else if (ctx->RenderMode==GL_FEEDBACK) {
1039 ctx->Driver.LineFunc = gl_feedback_line;
1040 }
1041 else {
1042 /* GL_SELECT mode */
1043 ctx->Driver.LineFunc = gl_select_line;
1044 }
1045 }
1046