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