Cleanup of derived state calculation prior to seperating software T&L
[mesa.git] / src / mesa / swrast / s_lines.c
1 /* $Id: s_lines.c,v 1.5 2000/11/13 20:02:57 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 #include "glheader.h"
29 #include "macros.h"
30 #include "mmath.h"
31 #include "vb.h"
32 #include "s_aaline.h"
33 #include "s_pb.h"
34 #include "s_context.h"
35 #include "s_depth.h"
36 #include "s_lines.h"
37 #include "s_feedback.h"
38
39
40
41 /**********************************************************************/
42 /***** Rasterization *****/
43 /**********************************************************************/
44
45
46 /*
47 * There are 4 pairs (RGBA, CI) of line drawing functions:
48 * 1. simple: width=1 and no special rasterization functions (fastest)
49 * 2. flat: width=1, non-stippled, flat-shaded, any raster operations
50 * 3. smooth: width=1, non-stippled, smooth-shaded, any raster operations
51 * 4. general: any other kind of line (slowest)
52 */
53
54
55
56 /* Flat, color index line */
57 static void flat_ci_line( GLcontext *ctx,
58 SWvertex *vert0,
59 SWvertex *vert1 )
60 {
61 struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
62
63 PB_SET_INDEX( PB, vert0->index );
64
65 #define INTERP_XY 1
66 #define PLOT(X,Y) PB_WRITE_PIXEL(PB, X, Y, 0, 0);
67
68 #include "s_linetemp.h"
69
70 gl_flush_pb(ctx);
71 }
72
73
74
75 /* Flat, color index line with Z interpolation/testing */
76 static void flat_ci_z_line( GLcontext *ctx,
77 SWvertex *vert0,
78 SWvertex *vert1 )
79 {
80 struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
81 PB_SET_INDEX( PB, vert0->index );
82
83 #define INTERP_XY 1
84 #define INTERP_Z 1
85 #define PLOT(X,Y) PB_WRITE_PIXEL(PB, X, Y, Z, fog0);
86
87 #include "s_linetemp.h"
88
89 gl_flush_pb(ctx);
90 }
91
92
93
94 /* Flat-shaded, RGBA line */
95 static void flat_rgba_line( GLcontext *ctx,
96 SWvertex *vert0,
97 SWvertex *vert1 )
98 {
99 const GLchan *color = vert0->color;
100 struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
101 PB_SET_COLOR( PB, color[0], color[1], color[2], color[3] );
102
103 #define INTERP_XY 1
104 #define PLOT(X,Y) PB_WRITE_PIXEL(PB, X, Y, 0, 0);
105
106 #include "s_linetemp.h"
107
108 gl_flush_pb(ctx);
109 }
110
111
112
113 /* Flat-shaded, RGBA line with Z interpolation/testing */
114 static void flat_rgba_z_line( GLcontext *ctx,
115 SWvertex *vert0,
116 SWvertex *vert1 )
117 {
118 const GLchan *color = vert0->color;
119 struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
120 PB_SET_COLOR( PB, color[0], color[1], color[2], color[3] );
121
122 #define INTERP_XY 1
123 #define INTERP_Z 1
124 #define PLOT(X,Y) PB_WRITE_PIXEL(PB, X, Y, Z, fog0);
125
126 #include "s_linetemp.h"
127
128 gl_flush_pb(ctx);
129 }
130
131
132
133 /* Smooth shaded, color index line */
134 static void smooth_ci_line( GLcontext *ctx,
135 SWvertex *vert0,
136 SWvertex *vert1 )
137 {
138 struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
139 GLint count = PB->count;
140 GLint *pbx = PB->x;
141 GLint *pby = PB->y;
142 GLuint *pbi = PB->index;
143
144 PB->mono = GL_FALSE;
145
146 #define INTERP_XY 1
147 #define INTERP_INDEX 1
148
149 #define PLOT(X,Y) \
150 pbx[count] = X; \
151 pby[count] = Y; \
152 pbi[count] = I; \
153 count++;
154
155 #include "s_linetemp.h"
156
157 PB->count = count;
158 gl_flush_pb(ctx);
159 }
160
161
162
163 /* Smooth shaded, color index line with Z interpolation/testing */
164 static void smooth_ci_z_line( GLcontext *ctx,
165 SWvertex *vert0,
166 SWvertex *vert1 )
167 {
168 struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
169 GLint count = PB->count;
170 GLint *pbx = PB->x;
171 GLint *pby = PB->y;
172 GLdepth *pbz = PB->z;
173 GLuint *pbi = PB->index;
174
175 PB->mono = GL_FALSE;
176
177 #define INTERP_XY 1
178 #define INTERP_Z 1
179 #define INTERP_INDEX 1
180
181 #define PLOT(X,Y) \
182 pbx[count] = X; \
183 pby[count] = Y; \
184 pbz[count] = Z; \
185 pbi[count] = I; \
186 count++;
187
188 #include "s_linetemp.h"
189
190 PB->count = count;
191 gl_flush_pb(ctx);
192 }
193
194
195
196 /* Smooth-shaded, RGBA line */
197 static void smooth_rgba_line( GLcontext *ctx,
198 SWvertex *vert0,
199 SWvertex *vert1 )
200 {
201 struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
202 GLint count = PB->count;
203 GLint *pbx = PB->x;
204 GLint *pby = PB->y;
205 GLchan (*pbrgba)[4] = PB->rgba;
206
207 PB->mono = GL_FALSE;
208
209 #define INTERP_XY 1
210 #define INTERP_RGB 1
211 #define INTERP_ALPHA 1
212
213 #define PLOT(X,Y) \
214 pbx[count] = X; \
215 pby[count] = Y; \
216 pbrgba[count][RCOMP] = FixedToInt(r0); \
217 pbrgba[count][GCOMP] = FixedToInt(g0); \
218 pbrgba[count][BCOMP] = FixedToInt(b0); \
219 pbrgba[count][ACOMP] = FixedToInt(a0); \
220 count++;
221
222 #include "s_linetemp.h"
223
224 PB->count = count;
225 gl_flush_pb(ctx);
226 }
227
228
229
230 /* Smooth-shaded, RGBA line with Z interpolation/testing */
231 static void smooth_rgba_z_line( GLcontext *ctx,
232 SWvertex *vert0,
233 SWvertex *vert1 )
234 {
235 struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
236 GLint count = PB->count;
237 GLint *pbx = PB->x;
238 GLint *pby = PB->y;
239 GLdepth *pbz = PB->z;
240 GLfixed *pbfog = PB->fog;
241 GLchan (*pbrgba)[4] = PB->rgba;
242
243
244 PB->mono = GL_FALSE;
245
246 #define INTERP_XY 1
247 #define INTERP_Z 1
248 #define INTERP_RGB 1
249 #define INTERP_ALPHA 1
250
251 #define PLOT(X,Y) \
252 pbx[count] = X; \
253 pby[count] = Y; \
254 pbz[count] = Z; \
255 pbfog[count] = fog0; \
256 pbrgba[count][RCOMP] = FixedToInt(r0); \
257 pbrgba[count][GCOMP] = FixedToInt(g0); \
258 pbrgba[count][BCOMP] = FixedToInt(b0); \
259 pbrgba[count][ACOMP] = FixedToInt(a0); \
260 count++;
261
262 #include "s_linetemp.h"
263
264 PB->count = count;
265 gl_flush_pb(ctx);
266 }
267
268
269 #define CHECK_FULL(count) \
270 if (count >= PB_SIZE-MAX_WIDTH) { \
271 PB->count = count; \
272 gl_flush_pb(ctx); \
273 count = PB->count; \
274 }
275
276
277
278 /* Smooth shaded, color index, any width, maybe stippled */
279 static void general_smooth_ci_line( GLcontext *ctx,
280 SWvertex *vert0,
281 SWvertex *vert1 )
282 {
283 struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
284 GLint count = PB->count;
285 GLint *pbx = PB->x;
286 GLint *pby = PB->y;
287 GLdepth *pbz = PB->z;
288 GLfixed *pbfog = PB->fog;
289 GLuint *pbi = PB->index;
290
291 PB->mono = GL_FALSE;
292
293 if (ctx->Line.StippleFlag) {
294 /* stippled */
295 #define INTERP_XY 1
296 #define INTERP_Z 1
297 #define INTERP_INDEX 1
298 #define WIDE 1
299 #define STIPPLE 1
300 #define PLOT(X,Y) \
301 pbx[count] = X; \
302 pby[count] = Y; \
303 pbz[count] = Z; \
304 pbfog[count] = fog0; \
305 pbi[count] = I; \
306 count++; \
307 CHECK_FULL(count);
308 #include "s_linetemp.h"
309 }
310 else {
311 /* unstippled */
312 if (ctx->Line.Width==2.0F) {
313 /* special case: unstippled and width=2 */
314 #define INTERP_XY 1
315 #define INTERP_Z 1
316 #define INTERP_INDEX 1
317 #define XMAJOR_PLOT(X,Y) \
318 pbx[count] = X; pbx[count+1] = X; \
319 pby[count] = Y; pby[count+1] = Y+1; \
320 pbz[count] = Z; pbz[count+1] = Z; \
321 pbfog[count] = fog0; pbfog[count+1] = fog0; \
322 pbi[count] = I; pbi[count+1] = I; \
323 count += 2; \
324 CHECK_FULL(count);
325 #define YMAJOR_PLOT(X,Y) \
326 pbx[count] = X; pbx[count+1] = X+1; \
327 pby[count] = Y; pby[count+1] = Y; \
328 pbz[count] = Z; pbz[count+1] = Z; \
329 pbfog[count] = fog0; pbfog[count+1] = fog0; \
330 pbi[count] = I; pbi[count+1] = I; \
331 count += 2; \
332 CHECK_FULL(count);
333 #include "s_linetemp.h"
334 }
335 else {
336 /* unstippled, any width */
337 #define INTERP_XY 1
338 #define INTERP_Z 1
339 #define INTERP_INDEX 1
340 #define WIDE 1
341 #define PLOT(X,Y) \
342 pbx[count] = X; \
343 pby[count] = Y; \
344 pbz[count] = Z; \
345 pbi[count] = I; \
346 pbfog[count] = fog0; \
347 count++; \
348 CHECK_FULL(count);
349 #include "s_linetemp.h"
350 }
351 }
352
353 PB->count = count;
354 gl_flush_pb(ctx);
355 }
356
357
358 /* Flat shaded, color index, any width, maybe stippled */
359 static void general_flat_ci_line( GLcontext *ctx,
360 SWvertex *vert0,
361 SWvertex *vert1 )
362 {
363 struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
364 GLint count;
365 GLint *pbx = PB->x;
366 GLint *pby = PB->y;
367 GLdepth *pbz = PB->z;
368 GLfixed *pbfog = PB->fog;
369 PB_SET_INDEX( PB, vert0->index );
370 count = PB->count;
371
372 if (ctx->Line.StippleFlag) {
373 /* stippled, any width */
374 #define INTERP_XY 1
375 #define INTERP_Z 1
376 #define WIDE 1
377 #define STIPPLE 1
378 #define PLOT(X,Y) \
379 pbx[count] = X; \
380 pby[count] = Y; \
381 pbz[count] = Z; \
382 pbfog[count] = fog0; \
383 count++; \
384 CHECK_FULL(count);
385 #include "s_linetemp.h"
386 }
387 else {
388 /* unstippled */
389 if (ctx->Line.Width==2.0F) {
390 /* special case: unstippled and width=2 */
391 #define INTERP_XY 1
392 #define INTERP_Z 1
393 #define XMAJOR_PLOT(X,Y) \
394 pbx[count] = X; pbx[count+1] = X; \
395 pby[count] = Y; pby[count+1] = Y+1; \
396 pbz[count] = Z; pbz[count+1] = Z; \
397 pbfog[count] = fog0; pbfog[count+1] = fog0; \
398 count += 2; \
399 CHECK_FULL(count);
400 #define YMAJOR_PLOT(X,Y) \
401 pbx[count] = X; pbx[count+1] = X+1; \
402 pby[count] = Y; pby[count+1] = Y; \
403 pbz[count] = Z; pbz[count+1] = Z; \
404 pbfog[count] = fog0; pbfog[count+1] = fog0; \
405 count += 2; \
406 CHECK_FULL(count);
407 #include "s_linetemp.h"
408 }
409 else {
410 /* unstippled, any width */
411 #define INTERP_XY 1
412 #define INTERP_Z 1
413 #define WIDE 1
414 #define PLOT(X,Y) \
415 pbx[count] = X; \
416 pby[count] = Y; \
417 pbz[count] = Z; \
418 pbfog[count] = fog0; \
419 count++; \
420 CHECK_FULL(count);
421 #include "s_linetemp.h"
422 }
423 }
424
425 PB->count = count;
426 gl_flush_pb(ctx);
427 }
428
429
430
431 static void general_smooth_rgba_line( GLcontext *ctx,
432 SWvertex *vert0,
433 SWvertex *vert1 )
434 {
435 struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
436 GLint count = PB->count;
437 GLint *pbx = PB->x;
438 GLint *pby = PB->y;
439 GLdepth *pbz = PB->z;
440 GLfixed *pbfog = PB->fog;
441 GLchan (*pbrgba)[4] = PB->rgba;
442
443 PB->mono = GL_FALSE;
444
445 if (ctx->Line.StippleFlag) {
446 /* stippled */
447 #define INTERP_XY 1
448 #define INTERP_Z 1
449 #define INTERP_RGB 1
450 #define INTERP_ALPHA 1
451 #define WIDE 1
452 #define STIPPLE 1
453 #define PLOT(X,Y) \
454 pbx[count] = X; \
455 pby[count] = Y; \
456 pbz[count] = Z; \
457 pbfog[count] = fog0; \
458 pbrgba[count][RCOMP] = FixedToInt(r0); \
459 pbrgba[count][GCOMP] = FixedToInt(g0); \
460 pbrgba[count][BCOMP] = FixedToInt(b0); \
461 pbrgba[count][ACOMP] = FixedToInt(a0); \
462 count++; \
463 CHECK_FULL(count);
464 #include "s_linetemp.h"
465 }
466 else {
467 /* unstippled */
468 if (ctx->Line.Width==2.0F) {
469 /* special case: unstippled and width=2 */
470 #define INTERP_XY 1
471 #define INTERP_Z 1
472 #define INTERP_RGB 1
473 #define INTERP_ALPHA 1
474 #define XMAJOR_PLOT(X,Y) \
475 pbx[count] = X; pbx[count+1] = X; \
476 pby[count] = Y; pby[count+1] = Y+1; \
477 pbz[count] = Z; pbz[count+1] = Z; \
478 pbfog[count] = fog0; pbfog[count+1] = fog0; \
479 pbrgba[count][RCOMP] = FixedToInt(r0); \
480 pbrgba[count][GCOMP] = FixedToInt(g0); \
481 pbrgba[count][BCOMP] = FixedToInt(b0); \
482 pbrgba[count][ACOMP] = FixedToInt(a0); \
483 pbrgba[count+1][RCOMP] = FixedToInt(r0); \
484 pbrgba[count+1][GCOMP] = FixedToInt(g0); \
485 pbrgba[count+1][BCOMP] = FixedToInt(b0); \
486 pbrgba[count+1][ACOMP] = FixedToInt(a0); \
487 count += 2; \
488 CHECK_FULL(count);
489 #define YMAJOR_PLOT(X,Y) \
490 pbx[count] = X; pbx[count+1] = X+1; \
491 pby[count] = Y; pby[count+1] = Y; \
492 pbz[count] = Z; pbz[count+1] = Z; \
493 pbfog[count] = fog0; pbfog[count+1] = fog0; \
494 pbrgba[count][RCOMP] = FixedToInt(r0); \
495 pbrgba[count][GCOMP] = FixedToInt(g0); \
496 pbrgba[count][BCOMP] = FixedToInt(b0); \
497 pbrgba[count][ACOMP] = FixedToInt(a0); \
498 pbrgba[count+1][RCOMP] = FixedToInt(r0); \
499 pbrgba[count+1][GCOMP] = FixedToInt(g0); \
500 pbrgba[count+1][BCOMP] = FixedToInt(b0); \
501 pbrgba[count+1][ACOMP] = FixedToInt(a0); \
502 count += 2; \
503 CHECK_FULL(count);
504 #include "s_linetemp.h"
505 }
506 else {
507 /* unstippled, any width */
508 #define INTERP_XY 1
509 #define INTERP_Z 1
510 #define INTERP_RGB 1
511 #define INTERP_ALPHA 1
512 #define WIDE 1
513 #define PLOT(X,Y) \
514 pbx[count] = X; \
515 pby[count] = Y; \
516 pbz[count] = Z; \
517 pbfog[count] = fog0; \
518 pbrgba[count][RCOMP] = FixedToInt(r0); \
519 pbrgba[count][GCOMP] = FixedToInt(g0); \
520 pbrgba[count][BCOMP] = FixedToInt(b0); \
521 pbrgba[count][ACOMP] = FixedToInt(a0); \
522 count++; \
523 CHECK_FULL(count);
524 #include "s_linetemp.h"
525 }
526 }
527
528 PB->count = count;
529 gl_flush_pb(ctx);
530 }
531
532
533 static void general_flat_rgba_line( GLcontext *ctx,
534 SWvertex *vert0,
535 SWvertex *vert1 )
536 {
537 struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
538 const GLchan *color = vert0->color;
539 PB_SET_COLOR( PB, color[0], color[1], color[2], color[3] );
540
541 if (ctx->Line.StippleFlag) {
542 /* stippled */
543 #define INTERP_XY 1
544 #define INTERP_Z 1
545 #define WIDE 1
546 #define STIPPLE 1
547 #define PLOT(X,Y) PB_WRITE_PIXEL(PB, X, Y, Z, fog0);
548 #include "s_linetemp.h"
549 }
550 else {
551 /* unstippled */
552 if (ctx->Line.Width==2.0F) {
553 /* special case: unstippled and width=2 */
554 #define INTERP_XY 1
555 #define INTERP_Z 1
556 #define XMAJOR_PLOT(X,Y) PB_WRITE_PIXEL(PB, X, Y, Z, fog0); \
557 PB_WRITE_PIXEL(PB, X, Y+1, Z, fog0);
558 #define YMAJOR_PLOT(X,Y) PB_WRITE_PIXEL(PB, X, Y, Z, fog0); \
559 PB_WRITE_PIXEL(PB, X+1, Y, Z, fog0);
560 #include "s_linetemp.h"
561 }
562 else {
563 /* unstippled, any width */
564 #define INTERP_XY 1
565 #define INTERP_Z 1
566 #define WIDE 1
567 #define PLOT(X,Y) PB_WRITE_PIXEL(PB, X, Y, Z, fog0);
568 #include "s_linetemp.h"
569 }
570 }
571
572 gl_flush_pb(ctx);
573 }
574
575
576 /* Flat-shaded, textured, any width, maybe stippled */
577 static void flat_textured_line( GLcontext *ctx,
578 SWvertex *vert0,
579 SWvertex *vert1 )
580 {
581 struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
582 GLint count;
583 GLint *pbx = PB->x;
584 GLint *pby = PB->y;
585 GLdepth *pbz = PB->z;
586 GLfixed *pbfog = PB->fog;
587 GLfloat *pbs = PB->s[0];
588 GLfloat *pbt = PB->t[0];
589 GLfloat *pbu = PB->u[0];
590 GLchan *color = vert0->color;
591 PB_SET_COLOR( PB, color[0], color[1], color[2], color[3] );
592 count = PB->count;
593
594 if (ctx->Line.StippleFlag) {
595 /* stippled */
596 #define INTERP_XY 1
597 #define INTERP_Z 1
598 #define INTERP_TEX 1
599 #define WIDE 1
600 #define STIPPLE 1
601 #define PLOT(X,Y) \
602 { \
603 pbx[count] = X; \
604 pby[count] = Y; \
605 pbz[count] = Z; \
606 pbfog[count] = fog0; \
607 pbs[count] = fragTexcoord[0];\
608 pbt[count] = fragTexcoord[1];\
609 pbu[count] = fragTexcoord[2];\
610 count++; \
611 CHECK_FULL(count); \
612 }
613 #include "s_linetemp.h"
614 }
615 else {
616 /* unstippled */
617 #define INTERP_XY 1
618 #define INTERP_Z 1
619 #define INTERP_TEX 1
620 #define WIDE 1
621 #define PLOT(X,Y) \
622 { \
623 pbx[count] = X; \
624 pby[count] = Y; \
625 pbz[count] = Z; \
626 pbfog[count] = fog0; \
627 pbs[count] = fragTexcoord[0];\
628 pbt[count] = fragTexcoord[1];\
629 pbu[count] = fragTexcoord[2];\
630 count++; \
631 CHECK_FULL(count); \
632 }
633 #include "s_linetemp.h"
634 }
635
636 PB->count = count;
637 gl_flush_pb(ctx);
638 }
639
640
641
642 /* Smooth-shaded, textured, any width, maybe stippled */
643 static void smooth_textured_line( GLcontext *ctx,
644 SWvertex *vert0,
645 SWvertex *vert1 )
646 {
647 struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
648 GLint count = PB->count;
649 GLint *pbx = PB->x;
650 GLint *pby = PB->y;
651 GLdepth *pbz = PB->z;
652 GLfixed *pbfog = PB->fog;
653 GLfloat *pbs = PB->s[0];
654 GLfloat *pbt = PB->t[0];
655 GLfloat *pbu = PB->u[0];
656 GLchan (*pbrgba)[4] = PB->rgba;
657
658 PB->mono = GL_FALSE;
659
660 if (ctx->Line.StippleFlag) {
661 /* stippled */
662 #define INTERP_XY 1
663 #define INTERP_Z 1
664 #define INTERP_RGB 1
665 #define INTERP_ALPHA 1
666 #define INTERP_TEX 1
667 #define WIDE 1
668 #define STIPPLE 1
669 #define PLOT(X,Y) \
670 { \
671 pbx[count] = X; \
672 pby[count] = Y; \
673 pbz[count] = Z; \
674 pbfog[count] = fog0; \
675 pbs[count] = fragTexcoord[0]; \
676 pbt[count] = fragTexcoord[1]; \
677 pbu[count] = fragTexcoord[2]; \
678 pbrgba[count][RCOMP] = FixedToInt(r0); \
679 pbrgba[count][GCOMP] = FixedToInt(g0); \
680 pbrgba[count][BCOMP] = FixedToInt(b0); \
681 pbrgba[count][ACOMP] = FixedToInt(a0); \
682 count++; \
683 CHECK_FULL(count); \
684 }
685 #include "s_linetemp.h"
686 }
687 else {
688 /* unstippled */
689 #define INTERP_XY 1
690 #define INTERP_Z 1
691 #define INTERP_RGB 1
692 #define INTERP_ALPHA 1
693 #define INTERP_TEX 1
694 #define WIDE 1
695 #define PLOT(X,Y) \
696 { \
697 pbx[count] = X; \
698 pby[count] = Y; \
699 pbz[count] = Z; \
700 pbfog[count] = fog0; \
701 pbs[count] = fragTexcoord[0]; \
702 pbt[count] = fragTexcoord[1]; \
703 pbu[count] = fragTexcoord[2]; \
704 pbrgba[count][RCOMP] = FixedToInt(r0); \
705 pbrgba[count][GCOMP] = FixedToInt(g0); \
706 pbrgba[count][BCOMP] = FixedToInt(b0); \
707 pbrgba[count][ACOMP] = FixedToInt(a0); \
708 count++; \
709 CHECK_FULL(count); \
710 }
711 #include "s_linetemp.h"
712 }
713
714 PB->count = count;
715 gl_flush_pb(ctx);
716 }
717
718
719 /* Smooth-shaded, multitextured, any width, maybe stippled, separate specular
720 * color interpolation.
721 */
722 static void smooth_multitextured_line( GLcontext *ctx,
723 SWvertex *vert0,
724 SWvertex *vert1 )
725 {
726 struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
727 GLint count = PB->count;
728 GLint *pbx = PB->x;
729 GLint *pby = PB->y;
730 GLdepth *pbz = PB->z;
731 GLfixed *pbfog = PB->fog;
732 GLchan (*pbrgba)[4] = PB->rgba;
733 GLchan (*pbspec)[3] = PB->spec;
734
735 PB->mono = GL_FALSE;
736
737 if (ctx->Line.StippleFlag) {
738 /* stippled */
739 #define INTERP_XY 1
740 #define INTERP_Z 1
741 #define INTERP_RGB 1
742 #define INTERP_SPEC 1
743 #define INTERP_ALPHA 1
744 #define INTERP_MULTITEX 1
745 #define WIDE 1
746 #define STIPPLE 1
747 #define PLOT(X,Y) \
748 { \
749 GLuint u; \
750 pbx[count] = X; \
751 pby[count] = Y; \
752 pbz[count] = Z; \
753 pbfog[count] = fog0; \
754 pbrgba[count][RCOMP] = FixedToInt(r0); \
755 pbrgba[count][GCOMP] = FixedToInt(g0); \
756 pbrgba[count][BCOMP] = FixedToInt(b0); \
757 pbrgba[count][ACOMP] = FixedToInt(a0); \
758 pbspec[count][RCOMP] = FixedToInt(sr0); \
759 pbspec[count][GCOMP] = FixedToInt(sg0); \
760 pbspec[count][BCOMP] = FixedToInt(sb0); \
761 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { \
762 if (ctx->Texture.Unit[u]._ReallyEnabled) { \
763 PB->s[u][0] = fragTexcoord[u][0]; \
764 PB->s[u][1] = fragTexcoord[u][1]; \
765 PB->s[u][2] = fragTexcoord[u][2]; \
766 PB->s[u][3] = fragTexcoord[u][3]; \
767 } \
768 } \
769 count++; \
770 CHECK_FULL(count); \
771 }
772 #include "s_linetemp.h"
773 }
774 else {
775 /* unstippled */
776 #define INTERP_XY 1
777 #define INTERP_Z 1
778 #define INTERP_RGB 1
779 #define INTERP_SPEC 1
780 #define INTERP_ALPHA 1
781 #define INTERP_MULTITEX 1
782 #define WIDE 1
783 #define PLOT(X,Y) \
784 { \
785 GLuint u; \
786 pbx[count] = X; \
787 pby[count] = Y; \
788 pbz[count] = Z; \
789 pbfog[count] = fog0; \
790 pbrgba[count][RCOMP] = FixedToInt(r0); \
791 pbrgba[count][GCOMP] = FixedToInt(g0); \
792 pbrgba[count][BCOMP] = FixedToInt(b0); \
793 pbrgba[count][ACOMP] = FixedToInt(a0); \
794 pbspec[count][RCOMP] = FixedToInt(sr0); \
795 pbspec[count][GCOMP] = FixedToInt(sg0); \
796 pbspec[count][BCOMP] = FixedToInt(sb0); \
797 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { \
798 if (ctx->Texture.Unit[u]._ReallyEnabled) { \
799 PB->s[u][0] = fragTexcoord[u][0]; \
800 PB->s[u][1] = fragTexcoord[u][1]; \
801 PB->s[u][2] = fragTexcoord[u][2]; \
802 PB->s[u][3] = fragTexcoord[u][3]; \
803 } \
804 } \
805 count++; \
806 CHECK_FULL(count); \
807 }
808 #include "s_linetemp.h"
809 }
810
811 PB->count = count;
812 gl_flush_pb(ctx);
813 }
814
815
816 /* Flat-shaded, multitextured, any width, maybe stippled, separate specular
817 * color interpolation.
818 */
819 static void flat_multitextured_line( GLcontext *ctx,
820 SWvertex *vert0,
821 SWvertex *vert1 )
822 {
823 struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
824 GLint count = PB->count;
825 GLint *pbx = PB->x;
826 GLint *pby = PB->y;
827 GLdepth *pbz = PB->z;
828 GLfixed *pbfog = PB->fog;
829 GLchan (*pbrgba)[4] = PB->rgba;
830 GLchan (*pbspec)[3] = PB->spec;
831 GLchan *color = vert0->color;
832 GLchan sRed = vert0->specular[0];
833 GLchan sGreen = vert0->specular[1];
834 GLchan sBlue = vert0->specular[2];
835
836 PB->mono = GL_FALSE;
837
838 if (ctx->Line.StippleFlag) {
839 /* stippled */
840 #define INTERP_XY 1
841 #define INTERP_Z 1
842 #define INTERP_ALPHA 1
843 #define INTERP_MULTITEX 1
844 #define WIDE 1
845 #define STIPPLE 1
846 #define PLOT(X,Y) \
847 { \
848 GLuint u; \
849 pbx[count] = X; \
850 pby[count] = Y; \
851 pbz[count] = Z; \
852 pbfog[count] = fog0; \
853 pbrgba[count][RCOMP] = color[0]; \
854 pbrgba[count][GCOMP] = color[1]; \
855 pbrgba[count][BCOMP] = color[2]; \
856 pbrgba[count][ACOMP] = color[3]; \
857 pbspec[count][RCOMP] = sRed; \
858 pbspec[count][GCOMP] = sGreen; \
859 pbspec[count][BCOMP] = sBlue; \
860 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { \
861 if (ctx->Texture.Unit[u]._ReallyEnabled) { \
862 PB->s[u][0] = fragTexcoord[u][0]; \
863 PB->s[u][1] = fragTexcoord[u][1]; \
864 PB->s[u][2] = fragTexcoord[u][2]; \
865 PB->s[u][3] = fragTexcoord[u][3]; \
866 } \
867 } \
868 count++; \
869 CHECK_FULL(count); \
870 }
871 #include "s_linetemp.h"
872 }
873 else {
874 /* unstippled */
875 #define INTERP_XY 1
876 #define INTERP_Z 1
877 #define INTERP_ALPHA 1
878 #define INTERP_MULTITEX 1
879 #define WIDE 1
880 #define PLOT(X,Y) \
881 { \
882 GLuint u; \
883 pbx[count] = X; \
884 pby[count] = Y; \
885 pbz[count] = Z; \
886 pbfog[count] = fog0; \
887 pbrgba[count][RCOMP] = color[0]; \
888 pbrgba[count][GCOMP] = color[1]; \
889 pbrgba[count][BCOMP] = color[2]; \
890 pbrgba[count][ACOMP] = color[3]; \
891 pbspec[count][RCOMP] = sRed; \
892 pbspec[count][GCOMP] = sGreen; \
893 pbspec[count][BCOMP] = sBlue; \
894 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { \
895 if (ctx->Texture.Unit[u]._ReallyEnabled) { \
896 PB->s[u][0] = fragTexcoord[u][0]; \
897 PB->s[u][1] = fragTexcoord[u][1]; \
898 PB->s[u][2] = fragTexcoord[u][2]; \
899 PB->s[u][3] = fragTexcoord[u][3]; \
900 } \
901 } \
902 count++; \
903 CHECK_FULL(count); \
904 }
905 #include "s_linetemp.h"
906 }
907
908 PB->count = count;
909 gl_flush_pb(ctx);
910 }
911
912
913
914 #ifdef DEBUG
915 extern void
916 _mesa_print_line_function(GLcontext *ctx); /* silence compiler warning */
917 void
918 _mesa_print_line_function(GLcontext *ctx)
919 {
920 SWcontext *swrast = SWRAST_CONTEXT(ctx);
921
922 printf("Line Func == ");
923 if (swrast->Line == flat_ci_line)
924 printf("flat_ci_line\n");
925 else if (swrast->Line == flat_ci_z_line)
926 printf("flat_ci_z_line\n");
927 else if (swrast->Line == flat_rgba_line)
928 printf("flat_rgba_line\n");
929 else if (swrast->Line == flat_rgba_z_line)
930 printf("flat_rgba_z_line\n");
931 else if (swrast->Line == smooth_ci_line)
932 printf("smooth_ci_line\n");
933 else if (swrast->Line == smooth_ci_z_line)
934 printf("smooth_ci_z_line\n");
935 else if (swrast->Line == smooth_rgba_line)
936 printf("smooth_rgba_line\n");
937 else if (swrast->Line == smooth_rgba_z_line)
938 printf("smooth_rgba_z_line\n");
939 else if (swrast->Line == general_smooth_ci_line)
940 printf("general_smooth_ci_line\n");
941 else if (swrast->Line == general_flat_ci_line)
942 printf("general_flat_ci_line\n");
943 else if (swrast->Line == general_smooth_rgba_line)
944 printf("general_smooth_rgba_line\n");
945 else if (swrast->Line == general_flat_rgba_line)
946 printf("general_flat_rgba_line\n");
947 else if (swrast->Line == flat_textured_line)
948 printf("flat_textured_line\n");
949 else if (swrast->Line == smooth_textured_line)
950 printf("smooth_textured_line\n");
951 else if (swrast->Line == smooth_multitextured_line)
952 printf("smooth_multitextured_line\n");
953 else if (swrast->Line == flat_multitextured_line)
954 printf("flat_multitextured_line\n");
955 else
956 printf("Driver func %p\n", swrast->Line);
957 }
958 #endif
959
960
961
962 /*
963 * Determine which line drawing function to use given the current
964 * rendering context.
965 *
966 * Please update the summary flag _SWRAST_NEW_LINE if you add or remove
967 * tests to this code.
968 */
969 void
970 _swrast_choose_line( GLcontext *ctx )
971 {
972 SWcontext *swrast = SWRAST_CONTEXT(ctx);
973 const GLboolean rgbmode = ctx->Visual.RGBAflag;
974
975 if (ctx->RenderMode==GL_RENDER) {
976 if (ctx->Line.SmoothFlag) {
977 /* antialiased lines */
978 _swrast_choose_aa_line_function(ctx);
979 ASSERT(swrast->Triangle);
980 }
981 else if (ctx->Texture._ReallyEnabled) {
982 if (swrast->_MultiTextureEnabled
983 || ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR
984 || ctx->Fog.ColorSumEnabled) {
985 /* multi-texture and/or separate specular color */
986 if (ctx->Light.ShadeModel==GL_SMOOTH)
987 swrast->Line = smooth_multitextured_line;
988 else
989 swrast->Line = flat_multitextured_line;
990 }
991 else {
992 if (ctx->Light.ShadeModel==GL_SMOOTH) {
993 swrast->Line = smooth_textured_line;
994 }
995 else {
996 swrast->Line = flat_textured_line;
997 }
998 }
999 }
1000 else if (ctx->Line.Width!=1.0 || ctx->Line.StippleFlag) {
1001 if (ctx->Light.ShadeModel==GL_SMOOTH) {
1002 if (rgbmode)
1003 swrast->Line = general_smooth_rgba_line;
1004 else
1005 swrast->Line = general_smooth_ci_line;
1006 }
1007 else {
1008 if (rgbmode)
1009 swrast->Line = general_flat_rgba_line;
1010 else
1011 swrast->Line = general_flat_ci_line;
1012 }
1013 }
1014 else {
1015 if (ctx->Light.ShadeModel==GL_SMOOTH) {
1016 /* Width==1, non-stippled, smooth-shaded */
1017 if (ctx->Depth.Test || ctx->Fog.Enabled) {
1018 if (rgbmode)
1019 swrast->Line = smooth_rgba_z_line;
1020 else
1021 swrast->Line = smooth_ci_z_line;
1022 }
1023 else {
1024 if (rgbmode)
1025 swrast->Line = smooth_rgba_line;
1026 else
1027 swrast->Line = smooth_ci_line;
1028 }
1029 }
1030 else {
1031 /* Width==1, non-stippled, flat-shaded */
1032 if (ctx->Depth.Test || ctx->Fog.Enabled) {
1033 if (rgbmode)
1034 swrast->Line = flat_rgba_z_line;
1035 else
1036 swrast->Line = flat_ci_z_line;
1037 }
1038 else {
1039 if (rgbmode)
1040 swrast->Line = flat_rgba_line;
1041 else
1042 swrast->Line = flat_ci_line;
1043 }
1044 }
1045 }
1046 }
1047 else if (ctx->RenderMode==GL_FEEDBACK) {
1048 swrast->Line = gl_feedback_line;
1049 }
1050 else {
1051 /* GL_SELECT mode */
1052 swrast->Line = gl_select_line;
1053 }
1054
1055 /*_mesa_print_line_function(ctx);*/
1056 }