Klaus Niederkrueger's latest changes: use INIT_SPAN() to init span primitive
[mesa.git] / src / mesa / swrast / s_lines.c
1 /* $Id: s_lines.c,v 1.27 2002/04/12 15:39:59 brianp Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 4.1
6 *
7 * Copyright (C) 1999-2002 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 "colormac.h"
30 #include "macros.h"
31 #include "mmath.h"
32 #include "s_aaline.h"
33 #include "s_context.h"
34 #include "s_depth.h"
35 #include "s_feedback.h"
36 #include "s_lines.h"
37 #include "s_span.h"
38
39
40 /*
41 * Init the mask[] array to implement a line stipple.
42 */
43 static void
44 compute_stipple_mask( GLcontext *ctx, GLuint len, GLubyte mask[] )
45 {
46 SWcontext *swrast = SWRAST_CONTEXT(ctx);
47 GLuint i;
48
49 for (i = 0; i < len; i++) {
50 GLuint bit = (swrast->StippleCounter / ctx->Line.StippleFactor) & 0xf;
51 if ((1 << bit) & ctx->Line.StipplePattern) {
52 mask[i] = GL_TRUE;
53 }
54 else {
55 mask[i] = GL_FALSE;
56 }
57 swrast->StippleCounter++;
58 }
59 }
60
61
62 /*
63 * To draw a wide line we can simply redraw the span N times, side by side.
64 */
65 static void
66 draw_wide_line( GLcontext *ctx, struct sw_span *span, GLboolean xMajor )
67 {
68 GLint width, start;
69
70 ASSERT(span->end < MAX_WIDTH);
71
72 width = (GLint) CLAMP( ctx->Line.Width, MIN_LINE_WIDTH, MAX_LINE_WIDTH );
73
74 if (width & 1)
75 start = width / 2;
76 else
77 start = width / 2 - 1;
78
79 if (xMajor) {
80 GLuint i, w;
81 for (w = 0; w < width; w++) {
82 if (w == 0) {
83 for (i = 0; i < span->end; i++)
84 span->yArray[i] -= start;
85 }
86 else {
87 for (i = 0; i < span->end; i++)
88 span->yArray[i]++;
89 }
90 if ((span->interpMask | span->arrayMask) & SPAN_TEXTURE)
91 _mesa_write_texture_span(ctx, span);
92 else if ((span->interpMask | span->arrayMask) & SPAN_RGBA)
93 _mesa_write_rgba_span(ctx, span);
94 else
95 _mesa_write_index_span(ctx, span);
96 }
97 }
98 else {
99 GLuint i, w;
100 for (w = 0; w < width; w++) {
101 if (w == 0) {
102 for (i = 0; i < span->end; i++)
103 span->xArray[i] -= start;
104 }
105 else {
106 for (i = 0; i < span->end; i++)
107 span->xArray[i]++;
108 }
109 if ((span->interpMask | span->arrayMask) & SPAN_TEXTURE)
110 _mesa_write_texture_span(ctx, span);
111 else if ((span->interpMask | span->arrayMask) & SPAN_RGBA)
112 _mesa_write_rgba_span(ctx, span);
113 else
114 _mesa_write_index_span(ctx, span);
115 }
116 }
117 }
118
119
120
121 /**********************************************************************/
122 /***** Rasterization *****/
123 /**********************************************************************/
124
125
126 /* Flat, color index line */
127 static void flat_ci_line( GLcontext *ctx,
128 const SWvertex *vert0,
129 const SWvertex *vert1 )
130 {
131 struct sw_span span;
132
133 ASSERT(ctx->Light.ShadeModel == GL_FLAT);
134 ASSERT(!ctx->Line.StippleFlag);
135 ASSERT(ctx->Line.Width == 1.0F);
136
137 INIT_SPAN(span, GL_LINE, 0, SPAN_INDEX, SPAN_XY);
138 /*span.arrayMask |= SPAN_XY;
139 span.interpMask |= SPAN_INDEX;*/
140 span.index = IntToFixed(vert1->index);
141 span.indexStep = 0;
142
143 #define INTERP_XY 1
144 #define PLOT(X,Y) \
145 { \
146 span.xArray[span.end] = X; \
147 span.yArray[span.end] = Y; \
148 span.end++; \
149 }
150
151 #include "s_linetemp.h"
152
153 _mesa_write_index_span(ctx, &span);
154 }
155
156
157 /* Flat-shaded, RGBA line */
158 static void flat_rgba_line( GLcontext *ctx,
159 const SWvertex *vert0,
160 const SWvertex *vert1 )
161 {
162 struct sw_span span;
163
164 ASSERT(ctx->Light.ShadeModel == GL_FLAT);
165 ASSERT(!ctx->Line.StippleFlag);
166 ASSERT(ctx->Line.Width == 1.0F);
167
168 INIT_SPAN(span, GL_LINE, 0, SPAN_RGBA, SPAN_XY);
169 /*span.arrayMask |= SPAN_XY;
170 span.interpMask |= SPAN_RGBA;*/
171 span.red = ChanToFixed(vert1->color[0]);
172 span.green = ChanToFixed(vert1->color[1]);
173 span.blue = ChanToFixed(vert1->color[2]);
174 span.alpha = ChanToFixed(vert1->color[3]);
175 span.redStep = 0;
176 span.greenStep = 0;
177 span.blueStep = 0;
178 span.alphaStep = 0;
179
180 #define INTERP_XY 1
181 #define PLOT(X,Y) \
182 { \
183 span.xArray[span.end] = X; \
184 span.yArray[span.end] = Y; \
185 span.end++; \
186 }
187
188 #include "s_linetemp.h"
189
190 _mesa_write_rgba_span(ctx, &span);
191 }
192
193
194 /* Smooth shaded, color index line */
195 static void smooth_ci_line( GLcontext *ctx,
196 const SWvertex *vert0,
197 const SWvertex *vert1 )
198 {
199 struct sw_span span;
200
201 ASSERT(ctx->Light.ShadeModel == GL_SMOOTH);
202 ASSERT(!ctx->Line.StippleFlag);
203 ASSERT(ctx->Line.Width == 1.0F);
204
205 INIT_SPAN(span, GL_LINE, 0, 0, SPAN_XY | SPAN_INDEX);
206 /*span.arrayMask |= (SPAN_XY | SPAN_INDEX);*/
207
208 #define INTERP_XY 1
209 #define INTERP_INDEX 1
210 #define PLOT(X,Y) \
211 { \
212 span.xArray[span.end] = X; \
213 span.yArray[span.end] = Y; \
214 span.color.index[span.end] = I; \
215 span.end++; \
216 }
217
218 #include "s_linetemp.h"
219
220 _mesa_write_index_span(ctx, &span);
221 }
222
223
224 /* Smooth-shaded, RGBA line */
225 static void smooth_rgba_line( GLcontext *ctx,
226 const SWvertex *vert0,
227 const SWvertex *vert1 )
228 {
229 struct sw_span span;
230
231 ASSERT(ctx->Light.ShadeModel == GL_SMOOTH);
232 ASSERT(!ctx->Line.StippleFlag);
233 ASSERT(ctx->Line.Width == 1.0F);
234
235 INIT_SPAN(span, GL_LINE, 0, 0, SPAN_XY | SPAN_RGBA);
236 /*span.arrayMask |= (SPAN_XY | SPAN_RGBA);*/
237
238 #define INTERP_XY 1
239 #define INTERP_RGB 1
240 #define INTERP_ALPHA 1
241 #define PLOT(X,Y) \
242 { \
243 span.xArray[span.end] = X; \
244 span.yArray[span.end] = Y; \
245 span.color.rgba[span.end][RCOMP] = FixedToInt(r0); \
246 span.color.rgba[span.end][GCOMP] = FixedToInt(g0); \
247 span.color.rgba[span.end][BCOMP] = FixedToInt(b0); \
248 span.color.rgba[span.end][ACOMP] = FixedToInt(a0); \
249 span.end++; \
250 }
251
252 #include "s_linetemp.h"
253
254 _mesa_write_rgba_span(ctx, &span);
255 }
256
257
258 /* Smooth shaded, color index, any width, maybe stippled */
259 static void general_smooth_ci_line( GLcontext *ctx,
260 const SWvertex *vert0,
261 const SWvertex *vert1 )
262 {
263 GLboolean xMajor = GL_FALSE;
264 struct sw_span span;
265
266 ASSERT(ctx->Light.ShadeModel == GL_SMOOTH);
267
268 INIT_SPAN(span, GL_LINE, 0, 0,
269 SPAN_XY | SPAN_Z | SPAN_FOG | SPAN_INDEX);
270 /*span.arrayMask |= (SPAN_XY | SPAN_Z | SPAN_FOG | SPAN_INDEX);*/
271
272 #define SET_XMAJOR 1
273 #define INTERP_XY 1
274 #define INTERP_Z 1
275 #define INTERP_FOG 1
276 #define INTERP_INDEX 1
277 #define PLOT(X,Y) \
278 { \
279 span.xArray[span.end] = X; \
280 span.yArray[span.end] = Y; \
281 span.zArray[span.end] = Z; \
282 span.fogArray[span.end] = fog0; \
283 span.color.index[span.end] = I; \
284 span.end++; \
285 }
286 #include "s_linetemp.h"
287
288 if (ctx->Line.StippleFlag) {
289 span.arrayMask |= SPAN_MASK;
290 compute_stipple_mask(ctx, span.end, span.mask);
291 }
292
293 if (ctx->Line.Width > 1.0) {
294 draw_wide_line(ctx, &span, xMajor);
295 }
296 else {
297 _mesa_write_index_span(ctx, &span);
298 }
299 }
300
301
302 /* Flat shaded, color index, any width, maybe stippled */
303 static void general_flat_ci_line( GLcontext *ctx,
304 const SWvertex *vert0,
305 const SWvertex *vert1 )
306 {
307 GLboolean xMajor = GL_FALSE;
308 struct sw_span span;
309
310 ASSERT(ctx->Light.ShadeModel == GL_FLAT);
311
312 INIT_SPAN(span, GL_LINE, 0, SPAN_INDEX,
313 SPAN_XY | SPAN_Z | SPAN_FOG);
314 /*span.arrayMask |= (SPAN_XY | SPAN_Z | SPAN_FOG);
315 span.interpMask |= SPAN_INDEX;*/
316 span.index = IntToFixed(vert1->index);
317 span.indexStep = 0;
318
319 #define SET_XMAJOR 1
320 #define INTERP_XY 1
321 #define INTERP_Z 1
322 #define INTERP_FOG 1
323 #define PLOT(X,Y) \
324 { \
325 span.xArray[span.end] = X; \
326 span.yArray[span.end] = Y; \
327 span.zArray[span.end] = Z; \
328 span.fogArray[span.end] = fog0; \
329 span.end++; \
330 }
331 #include "s_linetemp.h"
332
333 if (ctx->Line.StippleFlag) {
334 span.arrayMask |= SPAN_MASK;
335 compute_stipple_mask(ctx, span.end, span.mask);
336 }
337
338 if (ctx->Line.Width > 1.0) {
339 draw_wide_line(ctx, &span, xMajor);
340 }
341 else {
342 _mesa_write_index_span(ctx, &span);
343 }
344 }
345
346
347
348 static void general_smooth_rgba_line( GLcontext *ctx,
349 const SWvertex *vert0,
350 const SWvertex *vert1 )
351 {
352 GLboolean xMajor = GL_FALSE;
353 struct sw_span span;
354
355 ASSERT(ctx->Light.ShadeModel == GL_SMOOTH);
356
357 INIT_SPAN(span, GL_LINE, 0, 0,
358 SPAN_XY | SPAN_Z | SPAN_FOG | SPAN_RGBA);
359 /*span.arrayMask |= (SPAN_XY | SPAN_Z | SPAN_FOG | SPAN_RGBA);*/
360
361 #define SET_XMAJOR 1
362 #define INTERP_XY 1
363 #define INTERP_Z 1
364 #define INTERP_FOG 1
365 #define INTERP_RGB 1
366 #define INTERP_ALPHA 1
367 #define PLOT(X,Y) \
368 { \
369 span.xArray[span.end] = X; \
370 span.yArray[span.end] = Y; \
371 span.zArray[span.end] = Z; \
372 span.color.rgba[span.end][RCOMP] = FixedToInt(r0); \
373 span.color.rgba[span.end][GCOMP] = FixedToInt(g0); \
374 span.color.rgba[span.end][BCOMP] = FixedToInt(b0); \
375 span.color.rgba[span.end][ACOMP] = FixedToInt(a0); \
376 span.fogArray[span.end] = fog0; \
377 span.end++; \
378 }
379 #include "s_linetemp.h"
380
381 if (ctx->Line.StippleFlag) {
382 span.arrayMask |= SPAN_MASK;
383 compute_stipple_mask(ctx, span.end, span.mask);
384 }
385
386 if (ctx->Line.Width > 1.0) {
387 draw_wide_line(ctx, &span, xMajor);
388 }
389 else {
390 _mesa_write_rgba_span(ctx, &span);
391 }
392 }
393
394
395 static void general_flat_rgba_line( GLcontext *ctx,
396 const SWvertex *vert0,
397 const SWvertex *vert1 )
398 {
399 GLboolean xMajor = GL_FALSE;
400 struct sw_span span;
401
402 ASSERT(ctx->Light.ShadeModel == GL_FLAT);
403
404 INIT_SPAN(span, GL_LINE, 0, SPAN_RGBA,
405 SPAN_XY | SPAN_Z | SPAN_FOG);
406 /*span.arrayMask |= (SPAN_XY | SPAN_Z | SPAN_FOG);
407 span.interpMask |= SPAN_RGBA;*/
408 span.red = ChanToFixed(vert1->color[0]);
409 span.green = ChanToFixed(vert1->color[1]);
410 span.blue = ChanToFixed(vert1->color[2]);
411 span.alpha = ChanToFixed(vert1->color[3]);
412 span.redStep = 0;
413 span.greenStep = 0;
414 span.blueStep = 0;
415 span.alphaStep = 0;
416
417 #define SET_XMAJOR 1
418 #define INTERP_XY 1
419 #define INTERP_Z 1
420 #define INTERP_FOG 1
421 #define PLOT(X,Y) \
422 { \
423 span.xArray[span.end] = X; \
424 span.yArray[span.end] = Y; \
425 span.zArray[span.end] = Z; \
426 span.fogArray[span.end] = fog0; \
427 span.end++; \
428 }
429 #include "s_linetemp.h"
430
431 if (ctx->Line.StippleFlag) {
432 span.arrayMask |= SPAN_MASK;
433 compute_stipple_mask(ctx, span.end, span.mask);
434 }
435
436 if (ctx->Line.Width > 1.0) {
437 draw_wide_line(ctx, &span, xMajor);
438 }
439 else {
440 _mesa_write_rgba_span(ctx, &span);
441 }
442 }
443
444
445 /* Flat-shaded, textured, any width, maybe stippled */
446 static void flat_textured_line( GLcontext *ctx,
447 const SWvertex *vert0,
448 const SWvertex *vert1 )
449 {
450 GLboolean xMajor = GL_FALSE;
451 struct sw_span span;
452
453 ASSERT(ctx->Light.ShadeModel == GL_FLAT);
454
455 INIT_SPAN(span, GL_LINE, 0, SPAN_RGBA | SPAN_SPEC,
456 SPAN_XY | SPAN_Z | SPAN_FOG | SPAN_TEXTURE | SPAN_RGBA);
457 /*span.arrayMask |= (SPAN_XY | SPAN_Z | SPAN_FOG | SPAN_TEXTURE | SPAN_LAMBDA);
458 span.interpMask |= (SPAN_RGBA | SPAN_SPEC);*/
459 span.red = ChanToFixed(vert1->color[0]);
460 span.green = ChanToFixed(vert1->color[1]);
461 span.blue = ChanToFixed(vert1->color[2]);
462 span.alpha = ChanToFixed(vert1->color[3]);
463 span.redStep = 0;
464 span.greenStep = 0;
465 span.blueStep = 0;
466 span.alphaStep = 0;
467 span.specRed = ChanToFixed(vert1->specular[0]);
468 span.specGreen = ChanToFixed(vert1->specular[1]);
469 span.specBlue = ChanToFixed(vert1->specular[2]);
470 span.specRedStep = 0;
471 span.specGreenStep = 0;
472 span.specBlueStep = 0;
473
474 #define SET_XMAJOR 1
475 #define INTERP_XY 1
476 #define INTERP_Z 1
477 #define INTERP_FOG 1
478 #define INTERP_TEX 1
479 #define PLOT(X,Y) \
480 { \
481 span.xArray[span.end] = X; \
482 span.yArray[span.end] = Y; \
483 span.zArray[span.end] = Z; \
484 span.fogArray[span.end] = fog0; \
485 span.texcoords[0][span.end][0] = fragTexcoord[0]; \
486 span.texcoords[0][span.end][1] = fragTexcoord[1]; \
487 span.texcoords[0][span.end][2] = fragTexcoord[2]; \
488 span.lambda[0][span.end] = 0.0; \
489 span.end++; \
490 }
491 #include "s_linetemp.h"
492
493 if (ctx->Line.StippleFlag) {
494 span.arrayMask |= SPAN_MASK;
495 compute_stipple_mask(ctx, span.end, span.mask);
496 }
497
498 if (ctx->Line.Width > 1.0) {
499 draw_wide_line(ctx, &span, xMajor);
500 }
501 else {
502 _mesa_write_texture_span(ctx, &span);
503 }
504 }
505
506
507
508 /* Smooth-shaded, textured, any width, maybe stippled */
509 static void smooth_textured_line( GLcontext *ctx,
510 const SWvertex *vert0,
511 const SWvertex *vert1 )
512 {
513 GLboolean xMajor = GL_FALSE;
514 struct sw_span span;
515
516 ASSERT(ctx->Light.ShadeModel == GL_SMOOTH);
517
518 INIT_SPAN(span, GL_LINE, 0, 0,
519 SPAN_XY | SPAN_Z | SPAN_FOG | SPAN_RGBA | SPAN_TEXTURE | SPAN_LAMBDA);
520 /*span.arrayMask |= (SPAN_XY | SPAN_Z | SPAN_FOG | SPAN_RGBA | SPAN_TEXTURE | SPAN_LAMBDA);*/
521
522 #define SET_XMAJOR 1
523 #define INTERP_XY 1
524 #define INTERP_Z 1
525 #define INTERP_FOG 1
526 #define INTERP_RGB 1
527 #define INTERP_ALPHA 1
528 #define INTERP_TEX 1
529 #define PLOT(X,Y) \
530 { \
531 span.xArray[span.end] = X; \
532 span.yArray[span.end] = Y; \
533 span.zArray[span.end] = Z; \
534 span.fogArray[span.end] = fog0; \
535 span.color.rgba[span.end][RCOMP] = FixedToInt(r0); \
536 span.color.rgba[span.end][GCOMP] = FixedToInt(g0); \
537 span.color.rgba[span.end][BCOMP] = FixedToInt(b0); \
538 span.color.rgba[span.end][ACOMP] = FixedToInt(a0); \
539 span.texcoords[0][span.end][0] = fragTexcoord[0]; \
540 span.texcoords[0][span.end][1] = fragTexcoord[1]; \
541 span.texcoords[0][span.end][2] = fragTexcoord[2]; \
542 span.lambda[0][span.end] = 0.0; \
543 span.end++; \
544 }
545 #include "s_linetemp.h"
546
547 if (ctx->Line.StippleFlag) {
548 span.arrayMask |= SPAN_MASK;
549 compute_stipple_mask(ctx, span.end, span.mask);
550 }
551
552 if (ctx->Line.Width > 1.0) {
553 draw_wide_line(ctx, &span, xMajor);
554 }
555 else {
556 _mesa_write_texture_span(ctx, &span);
557 }
558 }
559
560
561 /* Smooth-shaded, multitextured, any width, maybe stippled, separate specular
562 * color interpolation.
563 */
564 static void smooth_multitextured_line( GLcontext *ctx,
565 const SWvertex *vert0,
566 const SWvertex *vert1 )
567 {
568 GLboolean xMajor = GL_FALSE;
569 struct sw_span span;
570 GLuint u;
571
572 ASSERT(ctx->Light.ShadeModel == GL_SMOOTH);
573
574 INIT_SPAN(span, GL_LINE, 0, 0,
575 SPAN_XY | SPAN_Z | SPAN_FOG | SPAN_RGBA | SPAN_SPEC | SPAN_TEXTURE | SPAN_LAMBDA);
576 /*span.arrayMask |= (SPAN_XY | SPAN_Z | SPAN_FOG | SPAN_RGBA | SPAN_SPEC | SPAN_TEXTURE | SPAN_LAMBDA);*/
577
578 #define SET_XMAJOR 1
579 #define INTERP_XY 1
580 #define INTERP_Z 1
581 #define INTERP_FOG 1
582 #define INTERP_RGB 1
583 #define INTERP_SPEC 1
584 #define INTERP_ALPHA 1
585 #define INTERP_MULTITEX 1
586 #define PLOT(X,Y) \
587 { \
588 span.xArray[span.end] = X; \
589 span.yArray[span.end] = Y; \
590 span.zArray[span.end] = Z; \
591 span.fogArray[span.end] = fog0; \
592 span.color.rgba[span.end][RCOMP] = FixedToInt(r0); \
593 span.color.rgba[span.end][GCOMP] = FixedToInt(g0); \
594 span.color.rgba[span.end][BCOMP] = FixedToInt(b0); \
595 span.color.rgba[span.end][ACOMP] = FixedToInt(a0); \
596 span.specArray[span.end][RCOMP] = FixedToInt(sr0); \
597 span.specArray[span.end][GCOMP] = FixedToInt(sb0); \
598 span.specArray[span.end][BCOMP] = FixedToInt(sb0); \
599 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { \
600 if (ctx->Texture.Unit[u]._ReallyEnabled) { \
601 span.texcoords[u][span.end][0] = fragTexcoord[u][0]; \
602 span.texcoords[u][span.end][1] = fragTexcoord[u][1]; \
603 span.texcoords[u][span.end][2] = fragTexcoord[u][2]; \
604 span.lambda[u][span.end] = 0.0; \
605 } \
606 } \
607 span.end++; \
608 }
609 #include "s_linetemp.h"
610
611 if (ctx->Line.StippleFlag) {
612 span.arrayMask |= SPAN_MASK;
613 compute_stipple_mask(ctx, span.end, span.mask);
614 }
615
616 if (ctx->Line.Width > 1.0) {
617 draw_wide_line(ctx, &span, xMajor);
618 }
619 else {
620 _mesa_write_texture_span(ctx, &span);
621 }
622 }
623
624
625 /* Flat-shaded, multitextured, any width, maybe stippled, separate specular
626 * color interpolation.
627 */
628 static void flat_multitextured_line( GLcontext *ctx,
629 const SWvertex *vert0,
630 const SWvertex *vert1 )
631 {
632 GLboolean xMajor = GL_FALSE;
633 struct sw_span span;
634 GLuint u;
635
636 ASSERT(ctx->Light.ShadeModel == GL_FLAT);
637
638 INIT_SPAN(span, GL_LINE, 0, SPAN_RGBA | SPAN_SPEC,
639 SPAN_XY | SPAN_Z | SPAN_FOG | SPAN_TEXTURE | SPAN_LAMBDA);
640 /*span.arrayMask |= (SPAN_XY | SPAN_Z | SPAN_FOG | SPAN_TEXTURE | SPAN_LAMBDA);
641 span.interpMask |= (SPAN_RGBA | SPAN_SPEC);*/
642 span.red = ChanToFixed(vert1->color[0]);
643 span.green = ChanToFixed(vert1->color[1]);
644 span.blue = ChanToFixed(vert1->color[2]);
645 span.alpha = ChanToFixed(vert1->color[3]);
646 span.redStep = 0;
647 span.greenStep = 0;
648 span.blueStep = 0;
649 span.alphaStep = 0;
650 span.specRed = ChanToFixed(vert1->specular[0]);
651 span.specGreen = ChanToFixed(vert1->specular[1]);
652 span.specBlue = ChanToFixed(vert1->specular[2]);
653 span.specRedStep = 0;
654 span.specGreenStep = 0;
655 span.specBlueStep = 0;
656
657 #define SET_XMAJOR 1
658 #define INTERP_XY 1
659 #define INTERP_Z 1
660 #define INTERP_FOG 1
661 #define INTERP_MULTITEX 1
662 #define PLOT(X,Y) \
663 { \
664 span.xArray[span.end] = X; \
665 span.yArray[span.end] = Y; \
666 span.zArray[span.end] = Z; \
667 span.fogArray[span.end] = fog0; \
668 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { \
669 if (ctx->Texture.Unit[u]._ReallyEnabled) { \
670 span.texcoords[u][span.end][0] = fragTexcoord[u][0]; \
671 span.texcoords[u][span.end][1] = fragTexcoord[u][1]; \
672 span.texcoords[u][span.end][2] = fragTexcoord[u][2]; \
673 span.lambda[u][span.end] = 0.0; \
674 } \
675 } \
676 span.end++; \
677 }
678 #include "s_linetemp.h"
679
680 if (ctx->Line.StippleFlag) {
681 span.arrayMask |= SPAN_MASK;
682 compute_stipple_mask(ctx, span.end, span.mask);
683 }
684
685 if (ctx->Line.Width > 1.0) {
686 draw_wide_line(ctx, &span, xMajor);
687 }
688 else {
689 _mesa_write_texture_span(ctx, &span);
690 }
691 }
692
693
694 void _swrast_add_spec_terms_line( GLcontext *ctx,
695 const SWvertex *v0,
696 const SWvertex *v1 )
697 {
698 SWvertex *ncv0 = (SWvertex *)v0;
699 SWvertex *ncv1 = (SWvertex *)v1;
700 GLchan c[2][4];
701 COPY_CHAN4( c[0], ncv0->color );
702 COPY_CHAN4( c[1], ncv1->color );
703 ACC_3V( ncv0->color, ncv0->specular );
704 ACC_3V( ncv1->color, ncv1->specular );
705 SWRAST_CONTEXT(ctx)->SpecLine( ctx, ncv0, ncv1 );
706 COPY_CHAN4( ncv0->color, c[0] );
707 COPY_CHAN4( ncv1->color, c[1] );
708 }
709
710
711 #ifdef DEBUG
712 extern void
713 _mesa_print_line_function(GLcontext *ctx); /* silence compiler warning */
714 void
715 _mesa_print_line_function(GLcontext *ctx)
716 {
717 SWcontext *swrast = SWRAST_CONTEXT(ctx);
718
719 printf("Line Func == ");
720 if (swrast->Line == flat_ci_line)
721 printf("flat_ci_line\n");
722 else if (swrast->Line == flat_rgba_line)
723 printf("flat_rgba_line\n");
724 else if (swrast->Line == smooth_ci_line)
725 printf("smooth_ci_line\n");
726 else if (swrast->Line == smooth_rgba_line)
727 printf("smooth_rgba_line\n");
728 else if (swrast->Line == general_smooth_ci_line)
729 printf("general_smooth_ci_line\n");
730 else if (swrast->Line == general_flat_ci_line)
731 printf("general_flat_ci_line\n");
732 else if (swrast->Line == general_smooth_rgba_line)
733 printf("general_smooth_rgba_line\n");
734 else if (swrast->Line == general_flat_rgba_line)
735 printf("general_flat_rgba_line\n");
736 else if (swrast->Line == flat_textured_line)
737 printf("flat_textured_line\n");
738 else if (swrast->Line == smooth_textured_line)
739 printf("smooth_textured_line\n");
740 else if (swrast->Line == smooth_multitextured_line)
741 printf("smooth_multitextured_line\n");
742 else if (swrast->Line == flat_multitextured_line)
743 printf("flat_multitextured_line\n");
744 else
745 printf("Driver func %p\n", (void *) swrast->Line);
746 }
747 #endif
748
749
750
751 #ifdef DEBUG
752
753 /* record the current line function name */
754 static const char *lineFuncName = NULL;
755
756 #define USE(lineFunc) \
757 do { \
758 lineFuncName = #lineFunc; \
759 /*printf("%s\n", lineFuncName);*/ \
760 swrast->Line = lineFunc; \
761 } while (0)
762
763 #else
764
765 #define USE(lineFunc) swrast->Line = lineFunc
766
767 #endif
768
769
770
771 /*
772 * Determine which line drawing function to use given the current
773 * rendering context.
774 *
775 * Please update the summary flag _SWRAST_NEW_LINE if you add or remove
776 * tests to this code.
777 */
778 void
779 _swrast_choose_line( GLcontext *ctx )
780 {
781 SWcontext *swrast = SWRAST_CONTEXT(ctx);
782 const GLboolean rgbmode = ctx->Visual.rgbMode;
783
784 if (ctx->RenderMode == GL_RENDER) {
785 if (ctx->Line.SmoothFlag) {
786 /* antialiased lines */
787 _swrast_choose_aa_line_function(ctx);
788 ASSERT(swrast->Triangle);
789 }
790 else if (ctx->Texture._ReallyEnabled) {
791 if (ctx->Texture._ReallyEnabled > TEXTURE0_ANY ||
792 (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)) {
793 /* multi-texture and/or separate specular color */
794 if (ctx->Light.ShadeModel == GL_SMOOTH)
795 USE(smooth_multitextured_line);
796 else
797 USE(flat_multitextured_line);
798 }
799 else {
800 if (ctx->Light.ShadeModel == GL_SMOOTH) {
801 USE(smooth_textured_line);
802 }
803 else {
804 USE(flat_textured_line);
805 }
806 }
807 }
808 else {
809 if (ctx->Light.ShadeModel == GL_SMOOTH) {
810 if (ctx->Depth.Test || ctx->Fog.Enabled || ctx->Line.Width != 1.0
811 || ctx->Line.StippleFlag) {
812 if (rgbmode)
813 USE(general_smooth_rgba_line);
814 else
815 USE(general_smooth_ci_line);
816 }
817 else {
818 if (rgbmode)
819 USE(smooth_rgba_line);
820 else
821 USE(smooth_ci_line);
822 }
823 }
824 else {
825 if (ctx->Depth.Test || ctx->Fog.Enabled || ctx->Line.Width != 1.0
826 || ctx->Line.StippleFlag) {
827 if (rgbmode)
828 USE(general_flat_rgba_line);
829 else
830 USE(general_flat_ci_line);
831 }
832 else {
833 if (rgbmode)
834 USE(flat_rgba_line);
835 else
836 USE(flat_ci_line);
837 }
838 }
839 }
840 }
841 else if (ctx->RenderMode == GL_FEEDBACK) {
842 USE(_mesa_feedback_line);
843 }
844 else {
845 ASSERT(ctx->RenderMode == GL_SELECT);
846 USE(_mesa_select_line);
847 }
848
849 /*_mesa_print_line_function(ctx);*/
850 }