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