Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

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