added GL_SGIX/SGIS_pixel_texture
[mesa.git] / src / mesa / main / lines.c
1 /* $Id: lines.c,v 1.9 2000/03/03 18:55:45 brianp Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 3.3
6 *
7 * Copyright (C) 1999 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 GLint count;
120 GLint *pbx = ctx->PB->x;
121 GLint *pby = ctx->PB->y;
122 PB_SET_INDEX( ctx, ctx->PB, ctx->VB->IndexPtr->data[pvert] );
123 count = ctx->PB->count;
124
125 #define INTERP_XY 1
126
127 #define PLOT(X,Y) \
128 pbx[count] = X; \
129 pby[count] = Y; \
130 count++;
131
132 #include "linetemp.h"
133
134 ctx->PB->count = count;
135 gl_flush_pb(ctx);
136 }
137
138
139
140 /* Flat, color index line with Z interpolation/testing */
141 static void flat_ci_z_line( GLcontext *ctx,
142 GLuint vert0, GLuint vert1, GLuint pvert )
143 {
144 GLint count;
145 GLint *pbx = ctx->PB->x;
146 GLint *pby = ctx->PB->y;
147 GLdepth *pbz = ctx->PB->z;
148 PB_SET_INDEX( ctx, ctx->PB, ctx->VB->IndexPtr->data[pvert] );
149 count = ctx->PB->count;
150
151 #define INTERP_XY 1
152 #define INTERP_Z 1
153
154 #define PLOT(X,Y) \
155 pbx[count] = X; \
156 pby[count] = Y; \
157 pbz[count] = Z; \
158 count++;
159
160 #include "linetemp.h"
161
162 ctx->PB->count = count;
163 gl_flush_pb(ctx);
164 }
165
166
167
168 /* Flat-shaded, RGBA line */
169 static void flat_rgba_line( GLcontext *ctx,
170 GLuint vert0, GLuint vert1, GLuint pvert )
171 {
172 GLint count;
173 GLint *pbx = ctx->PB->x;
174 GLint *pby = ctx->PB->y;
175 GLubyte *color = ctx->VB->ColorPtr->data[pvert];
176 PB_SET_COLOR( ctx, ctx->PB, color[0], color[1], color[2], color[3] );
177 count = ctx->PB->count;
178
179 #define INTERP_XY 1
180
181 #define PLOT(X,Y) \
182 pbx[count] = X; \
183 pby[count] = Y; \
184 count++;
185
186 #include "linetemp.h"
187
188 ctx->PB->count = count;
189 gl_flush_pb(ctx);
190 }
191
192
193
194 /* Flat-shaded, RGBA line with Z interpolation/testing */
195 static void flat_rgba_z_line( GLcontext *ctx,
196 GLuint vert0, GLuint vert1, GLuint pvert )
197 {
198 GLint count;
199 GLint *pbx = ctx->PB->x;
200 GLint *pby = ctx->PB->y;
201 GLdepth *pbz = ctx->PB->z;
202 GLubyte *color = ctx->VB->ColorPtr->data[pvert];
203 PB_SET_COLOR( ctx, ctx->PB, color[0], color[1], color[2], color[3] );
204 count = ctx->PB->count;
205
206 #define INTERP_XY 1
207 #define INTERP_Z 1
208
209 #define PLOT(X,Y) \
210 pbx[count] = X; \
211 pby[count] = Y; \
212 pbz[count] = Z; \
213 count++;
214
215 #include "linetemp.h"
216
217 ctx->PB->count = count;
218 gl_flush_pb(ctx);
219 }
220
221
222
223 /* Smooth shaded, color index line */
224 static void smooth_ci_line( GLcontext *ctx,
225 GLuint vert0, GLuint vert1, GLuint pvert )
226 {
227 GLint count = ctx->PB->count;
228 GLint *pbx = ctx->PB->x;
229 GLint *pby = ctx->PB->y;
230 GLuint *pbi = ctx->PB->i;
231 (void) pvert;
232
233 #define INTERP_XY 1
234 #define INTERP_INDEX 1
235
236 #define PLOT(X,Y) \
237 pbx[count] = X; \
238 pby[count] = Y; \
239 pbi[count] = I; \
240 count++;
241
242 #include "linetemp.h"
243
244 ctx->PB->count = count;
245 gl_flush_pb(ctx);
246 }
247
248
249
250 /* Smooth shaded, color index line with Z interpolation/testing */
251 static void smooth_ci_z_line( GLcontext *ctx,
252 GLuint vert0, GLuint vert1, GLuint pvert )
253 {
254 GLint count = ctx->PB->count;
255 GLint *pbx = ctx->PB->x;
256 GLint *pby = ctx->PB->y;
257 GLdepth *pbz = ctx->PB->z;
258 GLuint *pbi = ctx->PB->i;
259 (void) pvert;
260
261 #define INTERP_XY 1
262 #define INTERP_Z 1
263 #define INTERP_INDEX 1
264
265 #define PLOT(X,Y) \
266 pbx[count] = X; \
267 pby[count] = Y; \
268 pbz[count] = Z; \
269 pbi[count] = I; \
270 count++;
271
272 #include "linetemp.h"
273
274 ctx->PB->count = count;
275 gl_flush_pb(ctx);
276 }
277
278
279
280 /* Smooth-shaded, RGBA line */
281 static void smooth_rgba_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 GLubyte (*pbrgba)[4] = ctx->PB->rgba;
288 (void) pvert;
289
290 #define INTERP_XY 1
291 #define INTERP_RGB 1
292 #define INTERP_ALPHA 1
293
294 #define PLOT(X,Y) \
295 pbx[count] = X; \
296 pby[count] = Y; \
297 pbrgba[count][RCOMP] = FixedToInt(r0); \
298 pbrgba[count][GCOMP] = FixedToInt(g0); \
299 pbrgba[count][BCOMP] = FixedToInt(b0); \
300 pbrgba[count][ACOMP] = FixedToInt(a0); \
301 count++;
302
303 #include "linetemp.h"
304
305 ctx->PB->count = count;
306 gl_flush_pb(ctx);
307 }
308
309
310
311 /* Smooth-shaded, RGBA line with Z interpolation/testing */
312 static void smooth_rgba_z_line( GLcontext *ctx,
313 GLuint vert0, GLuint vert1, GLuint pvert )
314 {
315 GLint count = ctx->PB->count;
316 GLint *pbx = ctx->PB->x;
317 GLint *pby = ctx->PB->y;
318 GLdepth *pbz = ctx->PB->z;
319 GLubyte (*pbrgba)[4] = ctx->PB->rgba;
320 (void) pvert;
321
322 #define INTERP_XY 1
323 #define INTERP_Z 1
324 #define INTERP_RGB 1
325 #define INTERP_ALPHA 1
326
327 #define PLOT(X,Y) \
328 pbx[count] = X; \
329 pby[count] = Y; \
330 pbz[count] = Z; \
331 pbrgba[count][RCOMP] = FixedToInt(r0); \
332 pbrgba[count][GCOMP] = FixedToInt(g0); \
333 pbrgba[count][BCOMP] = FixedToInt(b0); \
334 pbrgba[count][ACOMP] = FixedToInt(a0); \
335 count++;
336
337 #include "linetemp.h"
338
339 ctx->PB->count = count;
340 gl_flush_pb(ctx);
341 }
342
343
344 #define CHECK_FULL(count) \
345 if (count >= PB_SIZE-MAX_WIDTH) { \
346 ctx->PB->count = count; \
347 gl_flush_pb(ctx); \
348 count = ctx->PB->count; \
349 }
350
351
352
353 /* Smooth shaded, color index, any width, maybe stippled */
354 static void general_smooth_ci_line( GLcontext *ctx,
355 GLuint vert0, GLuint vert1, GLuint pvert )
356 {
357 GLint count = ctx->PB->count;
358 GLint *pbx = ctx->PB->x;
359 GLint *pby = ctx->PB->y;
360 GLdepth *pbz = ctx->PB->z;
361 GLuint *pbi = ctx->PB->i;
362 (void) pvert;
363
364 if (ctx->Line.StippleFlag) {
365 /* stippled */
366 #define INTERP_XY 1
367 #define INTERP_Z 1
368 #define INTERP_INDEX 1
369 #define WIDE 1
370 #define STIPPLE 1
371 #define PLOT(X,Y) \
372 pbx[count] = X; \
373 pby[count] = Y; \
374 pbz[count] = Z; \
375 pbi[count] = I; \
376 count++; \
377 CHECK_FULL(count);
378 #include "linetemp.h"
379 }
380 else {
381 /* unstippled */
382 if (ctx->Line.Width==2.0F) {
383 /* special case: unstippled and width=2 */
384 #define INTERP_XY 1
385 #define INTERP_Z 1
386 #define INTERP_INDEX 1
387 #define XMAJOR_PLOT(X,Y) \
388 pbx[count] = X; pbx[count+1] = X; \
389 pby[count] = Y; pby[count+1] = Y+1; \
390 pbz[count] = Z; pbz[count+1] = Z; \
391 pbi[count] = I; pbi[count+1] = I; \
392 count += 2; \
393 CHECK_FULL(count);
394 #define YMAJOR_PLOT(X,Y) \
395 pbx[count] = X; pbx[count+1] = X+1; \
396 pby[count] = Y; pby[count+1] = Y; \
397 pbz[count] = Z; pbz[count+1] = Z; \
398 pbi[count] = I; pbi[count+1] = I; \
399 count += 2; \
400 CHECK_FULL(count);
401 #include "linetemp.h"
402 }
403 else {
404 /* unstippled, any width */
405 #define INTERP_XY 1
406 #define INTERP_Z 1
407 #define INTERP_INDEX 1
408 #define WIDE 1
409 #define PLOT(X,Y) \
410 pbx[count] = X; \
411 pby[count] = Y; \
412 pbz[count] = Z; \
413 pbi[count] = I; \
414 count++; \
415 CHECK_FULL(count);
416 #include "linetemp.h"
417 }
418 }
419
420 ctx->PB->count = count;
421 gl_flush_pb(ctx);
422 }
423
424
425 /* Flat shaded, color index, any width, maybe stippled */
426 static void general_flat_ci_line( GLcontext *ctx,
427 GLuint vert0, GLuint vert1, GLuint pvert )
428 {
429 GLint count;
430 GLint *pbx = ctx->PB->x;
431 GLint *pby = ctx->PB->y;
432 GLdepth *pbz = ctx->PB->z;
433 PB_SET_INDEX( ctx, ctx->PB, ctx->VB->IndexPtr->data[pvert] );
434 count = ctx->PB->count;
435
436 if (ctx->Line.StippleFlag) {
437 /* stippled, any width */
438 #define INTERP_XY 1
439 #define INTERP_Z 1
440 #define WIDE 1
441 #define STIPPLE 1
442 #define PLOT(X,Y) \
443 pbx[count] = X; \
444 pby[count] = Y; \
445 pbz[count] = Z; \
446 count++; \
447 CHECK_FULL(count);
448 #include "linetemp.h"
449 }
450 else {
451 /* unstippled */
452 if (ctx->Line.Width==2.0F) {
453 /* special case: unstippled and width=2 */
454 #define INTERP_XY 1
455 #define INTERP_Z 1
456 #define XMAJOR_PLOT(X,Y) \
457 pbx[count] = X; pbx[count+1] = X; \
458 pby[count] = Y; pby[count+1] = Y+1; \
459 pbz[count] = Z; pbz[count+1] = Z; \
460 count += 2; \
461 CHECK_FULL(count);
462 #define YMAJOR_PLOT(X,Y) \
463 pbx[count] = X; pbx[count+1] = X+1; \
464 pby[count] = Y; pby[count+1] = Y; \
465 pbz[count] = Z; pbz[count+1] = Z; \
466 count += 2; \
467 CHECK_FULL(count);
468 #include "linetemp.h"
469 }
470 else {
471 /* unstippled, any width */
472 #define INTERP_XY 1
473 #define INTERP_Z 1
474 #define WIDE 1
475 #define PLOT(X,Y) \
476 pbx[count] = X; \
477 pby[count] = Y; \
478 pbz[count] = Z; \
479 count++; \
480 CHECK_FULL(count);
481 #include "linetemp.h"
482 }
483 }
484
485 ctx->PB->count = count;
486 gl_flush_pb(ctx);
487 }
488
489
490
491 static void general_smooth_rgba_line( GLcontext *ctx,
492 GLuint vert0, GLuint vert1, GLuint pvert)
493 {
494 GLint count = ctx->PB->count;
495 GLint *pbx = ctx->PB->x;
496 GLint *pby = ctx->PB->y;
497 GLdepth *pbz = ctx->PB->z;
498 GLubyte (*pbrgba)[4] = ctx->PB->rgba;
499 (void) pvert;
500
501 if (ctx->Line.StippleFlag) {
502 /* stippled */
503 #define INTERP_XY 1
504 #define INTERP_Z 1
505 #define INTERP_RGB 1
506 #define INTERP_ALPHA 1
507 #define WIDE 1
508 #define STIPPLE 1
509 #define PLOT(X,Y) \
510 pbx[count] = X; \
511 pby[count] = Y; \
512 pbz[count] = Z; \
513 pbrgba[count][RCOMP] = FixedToInt(r0); \
514 pbrgba[count][GCOMP] = FixedToInt(g0); \
515 pbrgba[count][BCOMP] = FixedToInt(b0); \
516 pbrgba[count][ACOMP] = FixedToInt(a0); \
517 count++; \
518 CHECK_FULL(count);
519 #include "linetemp.h"
520 }
521 else {
522 /* unstippled */
523 if (ctx->Line.Width==2.0F) {
524 /* special case: unstippled and width=2 */
525 #define INTERP_XY 1
526 #define INTERP_Z 1
527 #define INTERP_RGB 1
528 #define INTERP_ALPHA 1
529 #define XMAJOR_PLOT(X,Y) \
530 pbx[count] = X; pbx[count+1] = X; \
531 pby[count] = Y; pby[count+1] = Y+1; \
532 pbz[count] = Z; pbz[count+1] = Z; \
533 pbrgba[count][RCOMP] = FixedToInt(r0); \
534 pbrgba[count][GCOMP] = FixedToInt(g0); \
535 pbrgba[count][BCOMP] = FixedToInt(b0); \
536 pbrgba[count][ACOMP] = FixedToInt(a0); \
537 pbrgba[count+1][RCOMP] = FixedToInt(r0); \
538 pbrgba[count+1][GCOMP] = FixedToInt(g0); \
539 pbrgba[count+1][BCOMP] = FixedToInt(b0); \
540 pbrgba[count+1][ACOMP] = FixedToInt(a0); \
541 count += 2; \
542 CHECK_FULL(count);
543 #define YMAJOR_PLOT(X,Y) \
544 pbx[count] = X; pbx[count+1] = X+1; \
545 pby[count] = Y; pby[count+1] = Y; \
546 pbz[count] = Z; pbz[count+1] = Z; \
547 pbrgba[count][RCOMP] = FixedToInt(r0); \
548 pbrgba[count][GCOMP] = FixedToInt(g0); \
549 pbrgba[count][BCOMP] = FixedToInt(b0); \
550 pbrgba[count][ACOMP] = FixedToInt(a0); \
551 pbrgba[count+1][RCOMP] = FixedToInt(r0); \
552 pbrgba[count+1][GCOMP] = FixedToInt(g0); \
553 pbrgba[count+1][BCOMP] = FixedToInt(b0); \
554 pbrgba[count+1][ACOMP] = FixedToInt(a0); \
555 count += 2; \
556 CHECK_FULL(count);
557 #include "linetemp.h"
558 }
559 else {
560 /* unstippled, any width */
561 #define INTERP_XY 1
562 #define INTERP_Z 1
563 #define INTERP_RGB 1
564 #define INTERP_ALPHA 1
565 #define WIDE 1
566 #define PLOT(X,Y) \
567 pbx[count] = X; \
568 pby[count] = Y; \
569 pbz[count] = Z; \
570 pbrgba[count][RCOMP] = FixedToInt(r0); \
571 pbrgba[count][GCOMP] = FixedToInt(g0); \
572 pbrgba[count][BCOMP] = FixedToInt(b0); \
573 pbrgba[count][ACOMP] = FixedToInt(a0); \
574 count++; \
575 CHECK_FULL(count);
576 #include "linetemp.h"
577 }
578 }
579
580 ctx->PB->count = count;
581 gl_flush_pb(ctx);
582 }
583
584
585 static void general_flat_rgba_line( GLcontext *ctx,
586 GLuint vert0, GLuint vert1, GLuint pvert )
587 {
588 GLint count;
589 GLint *pbx = ctx->PB->x;
590 GLint *pby = ctx->PB->y;
591 GLdepth *pbz = ctx->PB->z;
592 GLubyte *color = ctx->VB->ColorPtr->data[pvert];
593 PB_SET_COLOR( ctx, ctx->PB, color[0], color[1], color[2], color[3] );
594 count = ctx->PB->count;
595
596 if (ctx->Line.StippleFlag) {
597 /* stippled */
598 #define INTERP_XY 1
599 #define INTERP_Z 1
600 #define WIDE 1
601 #define STIPPLE 1
602 #define PLOT(X,Y) \
603 pbx[count] = X; \
604 pby[count] = Y; \
605 pbz[count] = Z; \
606 count++; \
607 CHECK_FULL(count);
608 #include "linetemp.h"
609 }
610 else {
611 /* unstippled */
612 if (ctx->Line.Width==2.0F) {
613 /* special case: unstippled and width=2 */
614 #define INTERP_XY 1
615 #define INTERP_Z 1
616 #define XMAJOR_PLOT(X,Y) \
617 pbx[count] = X; pbx[count+1] = X; \
618 pby[count] = Y; pby[count+1] = Y+1; \
619 pbz[count] = Z; pbz[count+1] = Z; \
620 count += 2; \
621 CHECK_FULL(count);
622 #define YMAJOR_PLOT(X,Y) \
623 pbx[count] = X; pbx[count+1] = X+1; \
624 pby[count] = Y; pby[count+1] = Y; \
625 pbz[count] = Z; pbz[count+1] = Z; \
626 count += 2; \
627 CHECK_FULL(count);
628 #include "linetemp.h"
629 }
630 else {
631 /* unstippled, any width */
632 #define INTERP_XY 1
633 #define INTERP_Z 1
634 #define WIDE 1
635 #define PLOT(X,Y) \
636 pbx[count] = X; \
637 pby[count] = Y; \
638 pbz[count] = Z; \
639 count++; \
640 CHECK_FULL(count);
641 #include "linetemp.h"
642 }
643 }
644
645 ctx->PB->count = count;
646 gl_flush_pb(ctx);
647 }
648
649
650 /* Flat-shaded, textured, any width, maybe stippled */
651 static void flat_textured_line( GLcontext *ctx,
652 GLuint vert0, GLuint vert1, GLuint pv )
653 {
654 GLint count;
655 GLint *pbx = ctx->PB->x;
656 GLint *pby = ctx->PB->y;
657 GLdepth *pbz = ctx->PB->z;
658 GLfloat *pbs = ctx->PB->s[0];
659 GLfloat *pbt = ctx->PB->t[0];
660 GLfloat *pbu = ctx->PB->u[0];
661 GLubyte *color = ctx->VB->ColorPtr->data[pv];
662 PB_SET_COLOR( ctx, ctx->PB, color[0], color[1], color[2], color[3] );
663 count = ctx->PB->count;
664
665 if (ctx->Line.StippleFlag) {
666 /* stippled */
667 #define INTERP_XY 1
668 #define INTERP_Z 1
669 #define INTERP_STUV0 1
670 #define WIDE 1
671 #define STIPPLE 1
672 #define PLOT(X,Y) \
673 { \
674 pbx[count] = X; \
675 pby[count] = Y; \
676 pbz[count] = Z; \
677 pbs[count] = s; \
678 pbt[count] = t; \
679 pbu[count] = u; \
680 count++; \
681 CHECK_FULL(count); \
682 }
683 #include "linetemp.h"
684 }
685 else {
686 /* unstippled */
687 #define INTERP_XY 1
688 #define INTERP_Z 1
689 #define INTERP_STUV0 1
690 #define WIDE 1
691 #define PLOT(X,Y) \
692 { \
693 pbx[count] = X; \
694 pby[count] = Y; \
695 pbz[count] = Z; \
696 pbs[count] = s; \
697 pbt[count] = t; \
698 pbu[count] = u; \
699 count++; \
700 CHECK_FULL(count); \
701 }
702 #include "linetemp.h"
703 }
704
705 ctx->PB->count = count;
706 gl_flush_pb(ctx);
707 }
708
709
710
711 /* Smooth-shaded, textured, any width, maybe stippled */
712 static void smooth_textured_line( GLcontext *ctx,
713 GLuint vert0, GLuint vert1, GLuint pvert )
714 {
715 GLint count = ctx->PB->count;
716 GLint *pbx = ctx->PB->x;
717 GLint *pby = ctx->PB->y;
718 GLdepth *pbz = ctx->PB->z;
719 GLfloat *pbs = ctx->PB->s[0];
720 GLfloat *pbt = ctx->PB->t[0];
721 GLfloat *pbu = ctx->PB->u[0];
722 GLubyte (*pbrgba)[4] = ctx->PB->rgba;
723 (void) pvert;
724
725 if (ctx->Line.StippleFlag) {
726 /* stippled */
727 #define INTERP_XY 1
728 #define INTERP_Z 1
729 #define INTERP_RGB 1
730 #define INTERP_ALPHA 1
731 #define INTERP_STUV0 1
732 #define WIDE 1
733 #define STIPPLE 1
734 #define PLOT(X,Y) \
735 { \
736 pbx[count] = X; \
737 pby[count] = Y; \
738 pbz[count] = Z; \
739 pbs[count] = s; \
740 pbt[count] = t; \
741 pbu[count] = u; \
742 pbrgba[count][RCOMP] = FixedToInt(r0); \
743 pbrgba[count][GCOMP] = FixedToInt(g0); \
744 pbrgba[count][BCOMP] = FixedToInt(b0); \
745 pbrgba[count][ACOMP] = FixedToInt(a0); \
746 count++; \
747 CHECK_FULL(count); \
748 }
749 #include "linetemp.h"
750 }
751 else {
752 /* unstippled */
753 #define INTERP_XY 1
754 #define INTERP_Z 1
755 #define INTERP_RGB 1
756 #define INTERP_ALPHA 1
757 #define INTERP_STUV0 1
758 #define WIDE 1
759 #define PLOT(X,Y) \
760 { \
761 pbx[count] = X; \
762 pby[count] = Y; \
763 pbz[count] = Z; \
764 pbs[count] = s; \
765 pbt[count] = t; \
766 pbu[count] = u; \
767 pbrgba[count][RCOMP] = FixedToInt(r0); \
768 pbrgba[count][GCOMP] = FixedToInt(g0); \
769 pbrgba[count][BCOMP] = FixedToInt(b0); \
770 pbrgba[count][ACOMP] = FixedToInt(a0); \
771 count++; \
772 CHECK_FULL(count); \
773 }
774 #include "linetemp.h"
775 }
776
777 ctx->PB->count = count;
778 gl_flush_pb(ctx);
779 }
780
781
782 /* Smooth-shaded, multitextured, any width, maybe stippled, separate specular
783 * color interpolation.
784 */
785 static void smooth_multitextured_line( GLcontext *ctx,
786 GLuint vert0, GLuint vert1, GLuint pvert )
787 {
788 GLint count = ctx->PB->count;
789 GLint *pbx = ctx->PB->x;
790 GLint *pby = ctx->PB->y;
791 GLdepth *pbz = ctx->PB->z;
792 GLfloat *pbs = ctx->PB->s[0];
793 GLfloat *pbt = ctx->PB->t[0];
794 GLfloat *pbu = ctx->PB->u[0];
795 GLfloat *pbs1 = ctx->PB->s[1];
796 GLfloat *pbt1 = ctx->PB->t[1];
797 GLfloat *pbu1 = ctx->PB->u[1];
798 GLubyte (*pbrgba)[4] = ctx->PB->rgba;
799 GLubyte (*pbspec)[3] = ctx->PB->spec;
800 (void) pvert;
801
802 if (ctx->Line.StippleFlag) {
803 /* stippled */
804 #define INTERP_XY 1
805 #define INTERP_Z 1
806 #define INTERP_RGB 1
807 #define INTERP_SPEC 1
808 #define INTERP_ALPHA 1
809 #define INTERP_STUV0 1
810 #define INTERP_STUV1 1
811 #define WIDE 1
812 #define STIPPLE 1
813 #define PLOT(X,Y) \
814 { \
815 pbx[count] = X; \
816 pby[count] = Y; \
817 pbz[count] = Z; \
818 pbs[count] = s; \
819 pbt[count] = t; \
820 pbu[count] = u; \
821 pbs1[count] = s1; \
822 pbt1[count] = t1; \
823 pbu1[count] = u1; \
824 pbrgba[count][RCOMP] = FixedToInt(r0); \
825 pbrgba[count][GCOMP] = FixedToInt(g0); \
826 pbrgba[count][BCOMP] = FixedToInt(b0); \
827 pbrgba[count][ACOMP] = FixedToInt(a0); \
828 pbspec[count][RCOMP] = FixedToInt(sr0); \
829 pbspec[count][GCOMP] = FixedToInt(sg0); \
830 pbspec[count][BCOMP] = FixedToInt(sb0); \
831 count++; \
832 CHECK_FULL(count); \
833 }
834 #include "linetemp.h"
835 }
836 else {
837 /* unstippled */
838 #define INTERP_XY 1
839 #define INTERP_Z 1
840 #define INTERP_RGB 1
841 #define INTERP_SPEC 1
842 #define INTERP_ALPHA 1
843 #define INTERP_STUV0 1
844 #define INTERP_STUV1 1
845 #define WIDE 1
846 #define PLOT(X,Y) \
847 { \
848 pbx[count] = X; \
849 pby[count] = Y; \
850 pbz[count] = Z; \
851 pbs[count] = s; \
852 pbt[count] = t; \
853 pbu[count] = u; \
854 pbs1[count] = s1; \
855 pbt1[count] = t1; \
856 pbu1[count] = u1; \
857 pbrgba[count][RCOMP] = FixedToInt(r0); \
858 pbrgba[count][GCOMP] = FixedToInt(g0); \
859 pbrgba[count][BCOMP] = FixedToInt(b0); \
860 pbrgba[count][ACOMP] = FixedToInt(a0); \
861 pbspec[count][RCOMP] = FixedToInt(sr0); \
862 pbspec[count][GCOMP] = FixedToInt(sg0); \
863 pbspec[count][BCOMP] = FixedToInt(sb0); \
864 count++; \
865 CHECK_FULL(count); \
866 }
867 #include "linetemp.h"
868 }
869
870 ctx->PB->count = count;
871 gl_flush_pb(ctx);
872 }
873
874
875 /*
876 * Antialiased RGBA line
877 *
878 * This AA line function isn't terribly efficient but it's pretty
879 * straight-forward to understand. Also, it doesn't exactly conform
880 * to the specification.
881 */
882 static void aa_rgba_line( GLcontext *ctx,
883 GLuint vert0, GLuint vert1, GLuint pvert )
884 {
885 #define INTERP_RGBA 1
886 #define PLOT(x, y) { PB_WRITE_RGBA_PIXEL( pb, (x), (y), z, red, green, blue, coverage ); }
887 #include "lnaatemp.h"
888 }
889
890 /*
891 * Antialiased Textured RGBA line
892 *
893 * This AA line function isn't terribly efficient but it's pretty
894 * straight-forward to understand. Also, it doesn't exactly conform
895 * to the specification.
896 */
897 static void aa_tex_rgba_line( GLcontext *ctx,
898 GLuint vert0, GLuint vert1, GLuint pvert )
899 {
900 #define INTERP_RGBA 1
901 #define INTERP_STUV0 1
902 #define PLOT(x, y) \
903 { \
904 PB_WRITE_TEX_PIXEL( pb, (x), (y), z, red, green, blue, coverage, \
905 s, t, u ); \
906 }
907 #include "lnaatemp.h"
908 }
909
910
911 /*
912 * Antialiased Multitextured RGBA line
913 *
914 * This AA line function isn't terribly efficient but it's pretty
915 * straight-forward to understand. Also, it doesn't exactly conform
916 * to the specification.
917 */
918 static void aa_multitex_rgba_line( GLcontext *ctx,
919 GLuint vert0, GLuint vert1, GLuint pvert )
920 {
921 #define INTERP_RGBA 1
922 #define INTERP_SPEC 1
923 #define INTERP_STUV0 1
924 #define INTERP_STUV1 1
925 #define PLOT(x, y) \
926 { \
927 PB_WRITE_MULTITEX_SPEC_PIXEL( pb, (x), (y), z, \
928 red, green, blue, coverage, specRed, specGreen, specBlue, \
929 s, t, u, s1, t1, u1 ); \
930 }
931 #include "lnaatemp.h"
932 }
933
934
935 /*
936 * Antialiased CI line. Same comments for RGBA antialiased lines apply.
937 */
938 static void aa_ci_line( GLcontext *ctx,
939 GLuint vert0, GLuint vert1, GLuint pvert )
940 {
941 #define INTERP_INDEX 1
942 #define PLOT(x, y) \
943 { \
944 PB_WRITE_CI_PIXEL( pb, (x), (y), z, index + coverage ); \
945 }
946 #include "lnaatemp.h"
947 }
948
949
950 /*
951 * Null rasterizer for measuring transformation speed.
952 */
953 static void null_line( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv )
954 {
955 (void) ctx;
956 (void) v1;
957 (void) v2;
958 (void) pv;
959 }
960
961
962 /*
963 * Determine which line drawing function to use given the current
964 * rendering context.
965 */
966 void gl_set_line_function( GLcontext *ctx )
967 {
968 GLboolean rgbmode = ctx->Visual->RGBAflag;
969 /* TODO: antialiased lines */
970
971 if (ctx->RenderMode==GL_RENDER) {
972 if (ctx->NoRaster) {
973 ctx->Driver.LineFunc = null_line;
974 return;
975 }
976 if (ctx->Driver.LineFunc) {
977 /* Device driver will draw lines. */
978 return;
979 }
980
981 if (ctx->Line.SmoothFlag) {
982 /* antialiased lines */
983 if (rgbmode) {
984 if (ctx->Texture.ReallyEnabled) {
985 if (ctx->Texture.ReallyEnabled >= TEXTURE1_1D
986 || ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR)
987 /* Multitextured! */
988 ctx->Driver.LineFunc = aa_multitex_rgba_line;
989 else
990 ctx->Driver.LineFunc = aa_tex_rgba_line;
991 } else {
992 ctx->Driver.LineFunc = aa_rgba_line;
993 }
994 }
995 else {
996 ctx->Driver.LineFunc = aa_ci_line;
997 }
998 }
999 else if (ctx->Texture.ReallyEnabled) {
1000 if (ctx->Texture.ReallyEnabled >= TEXTURE1_1D
1001 || ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR) {
1002 /* multi-texture and/or separate specular color */
1003 ctx->Driver.LineFunc = smooth_multitextured_line;
1004 }
1005 else {
1006 if (ctx->Light.ShadeModel==GL_SMOOTH) {
1007 ctx->Driver.LineFunc = smooth_textured_line;
1008 }
1009 else {
1010 ctx->Driver.LineFunc = flat_textured_line;
1011 }
1012 }
1013 }
1014 else if (ctx->Line.Width!=1.0 || ctx->Line.StippleFlag
1015 || ctx->Line.SmoothFlag) {
1016 if (ctx->Light.ShadeModel==GL_SMOOTH) {
1017 if (rgbmode)
1018 ctx->Driver.LineFunc = general_smooth_rgba_line;
1019 else
1020 ctx->Driver.LineFunc = general_smooth_ci_line;
1021 }
1022 else {
1023 if (rgbmode)
1024 ctx->Driver.LineFunc = general_flat_rgba_line;
1025 else
1026 ctx->Driver.LineFunc = general_flat_ci_line;
1027 }
1028 }
1029 else {
1030 if (ctx->Light.ShadeModel==GL_SMOOTH) {
1031 /* Width==1, non-stippled, smooth-shaded */
1032 if (ctx->Depth.Test || ctx->FogMode == FOG_FRAGMENT) {
1033 if (rgbmode)
1034 ctx->Driver.LineFunc = smooth_rgba_z_line;
1035 else
1036 ctx->Driver.LineFunc = smooth_ci_z_line;
1037 }
1038 else {
1039 if (rgbmode)
1040 ctx->Driver.LineFunc = smooth_rgba_line;
1041 else
1042 ctx->Driver.LineFunc = smooth_ci_line;
1043 }
1044 }
1045 else {
1046 /* Width==1, non-stippled, flat-shaded */
1047 if (ctx->Depth.Test || ctx->FogMode == FOG_FRAGMENT) {
1048 if (rgbmode)
1049 ctx->Driver.LineFunc = flat_rgba_z_line;
1050 else
1051 ctx->Driver.LineFunc = flat_ci_z_line;
1052 }
1053 else {
1054 if (rgbmode)
1055 ctx->Driver.LineFunc = flat_rgba_line;
1056 else
1057 ctx->Driver.LineFunc = flat_ci_line;
1058 }
1059 }
1060 }
1061 }
1062 else if (ctx->RenderMode==GL_FEEDBACK) {
1063 ctx->Driver.LineFunc = gl_feedback_line;
1064 }
1065 else {
1066 /* GL_SELECT mode */
1067 ctx->Driver.LineFunc = gl_select_line;
1068 }
1069 }
1070