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