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