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