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