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