xref: /reactos/dll/opengl/mesa/lines.c (revision 5f2bebf7)
1 /* $Id: lines.c,v 1.19 1998/02/03 23:46:00 brianp Exp $ */
2 
3 /*
4  * Mesa 3-D graphics library
5  * Version:  2.4
6  * Copyright (C) 1995-1997  Brian Paul
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the Free
20  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */
22 
23 
24 /*
25  * $Log: lines.c,v $
26  * Revision 1.19  1998/02/03 23:46:00  brianp
27  * fixed a few problems with condition expressions for Amiga StormC compiler
28  *
29  * Revision 1.18  1997/07/24 01:24:11  brianp
30  * changed precompiled header symbol from PCH to PC_HEADER
31  *
32  * Revision 1.17  1997/07/05 16:03:51  brianp
33  * fixed PB overflow problem
34  *
35  * Revision 1.16  1997/06/20 02:01:49  brianp
36  * changed color components from GLfixed to GLubyte
37  *
38  * Revision 1.15  1997/06/03 01:38:22  brianp
39  * fixed divide by zero problem in feedback function (William Mitchell)
40  *
41  * Revision 1.14  1997/05/28 03:25:26  brianp
42  * added precompiled header (PCH) support
43  *
44  * Revision 1.13  1997/05/03 00:51:02  brianp
45  * removed calls to gl_texturing_enabled()
46  *
47  * Revision 1.12  1997/04/14 02:00:39  brianp
48  * #include "texstate.h" instead of "texture.h"
49  *
50  * Revision 1.11  1997/04/12 12:25:01  brianp
51  * replaced ctx->LineFunc with ctx->Driver.LineFunc, fixed PB->count bug
52  *
53  * Revision 1.10  1997/03/16 02:07:31  brianp
54  * now use linetemp.h in line drawing functions
55  *
56  * Revision 1.9  1997/03/08 02:04:27  brianp
57  * better implementation of feedback function
58  *
59  * Revision 1.8  1997/02/09 18:44:20  brianp
60  * added GL_EXT_texture3D support
61  *
62  * Revision 1.7  1997/01/09 19:48:00  brianp
63  * now call gl_texturing_enabled()
64  *
65  * Revision 1.6  1996/11/08 02:21:21  brianp
66  * added null drawing function for GL_NO_RASTER
67  *
68  * Revision 1.5  1996/09/27 01:28:56  brianp
69  * removed unused variables
70  *
71  * Revision 1.4  1996/09/25 02:01:54  brianp
72  * new texture coord interpolation
73  *
74  * Revision 1.3  1996/09/15 14:18:10  brianp
75  * now use GLframebuffer and GLvisual
76  *
77  * Revision 1.2  1996/09/15 01:48:58  brianp
78  * removed #define NULL 0
79  *
80  * Revision 1.1  1996/09/13 01:38:16  brianp
81  * Initial revision
82  *
83  */
84 
85 
86 #ifdef PC_HEADER
87 #include "all.h"
88 #else
89 #include "context.h"
90 #include "depth.h"
91 #include "feedback.h"
92 #include "lines.h"
93 #include "dlist.h"
94 #include "macros.h"
95 #include "pb.h"
96 #include "texstate.h"
97 #include "types.h"
98 #include "vb.h"
99 #include <wine/debug.h>
100 #endif
101 
102 WINE_DEFAULT_DEBUG_CHANNEL(opengl32);
103 
gl_LineWidth(GLcontext * ctx,GLfloat width)104 void gl_LineWidth( GLcontext *ctx, GLfloat width )
105 {
106    if (width<=0.0) {
107       gl_error( ctx, GL_INVALID_VALUE, "glLineWidth" );
108       return;
109    }
110    if (INSIDE_BEGIN_END(ctx)) {
111       gl_error( ctx, GL_INVALID_OPERATION, "glLineWidth" );
112       return;
113    }
114    ctx->Line.Width = width;
115    ctx->NewState |= NEW_RASTER_OPS;
116 }
117 
118 
119 
gl_LineStipple(GLcontext * ctx,GLint factor,GLushort pattern)120 void gl_LineStipple( GLcontext *ctx, GLint factor, GLushort pattern )
121 {
122    if (INSIDE_BEGIN_END(ctx)) {
123       gl_error( ctx, GL_INVALID_OPERATION, "glLineStipple" );
124       return;
125    }
126    ctx->Line.StippleFactor = CLAMP( factor, 1, 256 );
127    ctx->Line.StipplePattern = pattern;
128    ctx->NewState |= NEW_RASTER_OPS;
129 }
130 
131 
132 
133 /**********************************************************************/
134 /*****                    Rasterization                           *****/
135 /**********************************************************************/
136 
137 
138 /*
139  * There are 4 pairs (RGBA, CI) of line drawing functions:
140  *   1. simple:  width=1 and no special rasterization functions (fastest)
141  *   2. flat:  width=1, non-stippled, flat-shaded, any raster operations
142  *   3. smooth:  width=1, non-stippled, smooth-shaded, any raster operations
143  *   4. general:  any other kind of line (slowest)
144  */
145 
146 
147 /*
148  * All line drawing functions have the same arguments:
149  * v1, v2 - indexes of first and second endpoints into vertex buffer arrays
150  * pv     - provoking vertex: which vertex color/index to use for flat shading.
151  */
152 
153 
154 
feedback_line(GLcontext * ctx,GLuint v1,GLuint v2,GLuint pv)155 static void feedback_line( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv )
156 {
157    struct vertex_buffer *VB = ctx->VB;
158    GLfloat x1, y1, z1, w1;
159    GLfloat x2, y2, z2, w2;
160    GLfloat tex1[4], tex2[4], invq;
161    GLfloat invRedScale   = ctx->Visual->InvRedScale;
162    GLfloat invGreenScale = ctx->Visual->InvGreenScale;
163    GLfloat invBlueScale  = ctx->Visual->InvBlueScale;
164    GLfloat invAlphaScale = ctx->Visual->InvAlphaScale;
165 
166    x1 = VB->Win[v1][0];
167    y1 = VB->Win[v1][1];
168    z1 = VB->Win[v1][2] / DEPTH_SCALE;
169    w1 = VB->Clip[v1][3];
170 
171    x2 = VB->Win[v2][0];
172    y2 = VB->Win[v2][1];
173    z2 = VB->Win[v2][2] / DEPTH_SCALE;
174    w2 = VB->Clip[v2][3];
175 
176    invq = (VB->TexCoord[v1][3]==0.0) ? 1.0 : (1.0F / VB->TexCoord[v1][3]);
177    tex1[0] = VB->TexCoord[v1][0] * invq;
178    tex1[1] = VB->TexCoord[v1][1] * invq;
179    tex1[2] = VB->TexCoord[v1][2] * invq;
180    tex1[3] = VB->TexCoord[v1][3];
181    invq = (VB->TexCoord[v2][3]==0.0) ? 1.0 : (1.0F / VB->TexCoord[v2][3]);
182    tex2[0] = VB->TexCoord[v2][0] * invq;
183    tex2[1] = VB->TexCoord[v2][1] * invq;
184    tex2[2] = VB->TexCoord[v2][2] * invq;
185    tex2[3] = VB->TexCoord[v2][3];
186 
187    if (ctx->StippleCounter==0) {
188       FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_LINE_RESET_TOKEN );
189    }
190    else {
191       FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_LINE_TOKEN );
192    }
193 
194    {
195       GLfloat color[4];
196       /* convert color from integer to a float in [0,1] */
197       color[0] = (GLfloat) VB->Color[pv][0] * invRedScale;
198       color[1] = (GLfloat) VB->Color[pv][1] * invGreenScale;
199       color[2] = (GLfloat) VB->Color[pv][2] * invBlueScale;
200       color[3] = (GLfloat) VB->Color[pv][3] * invAlphaScale;
201       gl_feedback_vertex( ctx, x1,y1,z1,w1, color,
202                           (GLfloat) VB->Index[pv], tex1 );
203       gl_feedback_vertex( ctx, x2,y2,z2,w2, color,
204                           (GLfloat) VB->Index[pv], tex2 );
205    }
206 
207    ctx->StippleCounter++;
208 }
209 
210 
211 
select_line(GLcontext * ctx,GLuint v1,GLuint v2,GLuint pv)212 static void select_line( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv )
213 {
214    gl_update_hitflag( ctx, ctx->VB->Win[v1][2] / DEPTH_SCALE );
215    gl_update_hitflag( ctx, ctx->VB->Win[v2][2] / DEPTH_SCALE );
216 }
217 
218 
219 
220 #if MAX_WIDTH > MAX_HEIGHT
221 #  define MAXPOINTS MAX_WIDTH
222 #else
223 #  define MAXPOINTS MAX_HEIGHT
224 #endif
225 
226 
227 /* Flat, color index line */
flat_ci_line(GLcontext * ctx,GLuint vert0,GLuint vert1,GLuint pvert)228 static void flat_ci_line( GLcontext *ctx,
229                           GLuint vert0, GLuint vert1, GLuint pvert )
230 {
231    GLint count;
232    GLint *pbx = ctx->PB->x;
233    GLint *pby = ctx->PB->y;
234    PB_SET_INDEX( ctx, ctx->PB, ctx->VB->Index[pvert] );
235    count = ctx->PB->count;
236 
237 #define INTERP_XY 1
238 
239 #define PLOT(X,Y)		\
240 	pbx[count] = X;		\
241 	pby[count] = Y;		\
242 	count++;
243 
244 #include "linetemp.h"
245 
246    ctx->PB->count = count;
247    PB_CHECK_FLUSH( ctx, ctx->PB );
248 }
249 
250 
251 
252 /* Flat, color index line with Z interpolation/testing */
flat_ci_z_line(GLcontext * ctx,GLuint vert0,GLuint vert1,GLuint pvert)253 static void flat_ci_z_line( GLcontext *ctx,
254                             GLuint vert0, GLuint vert1, GLuint pvert )
255 {
256    GLint count;
257    GLint *pbx = ctx->PB->x;
258    GLint *pby = ctx->PB->y;
259    GLdepth *pbz = ctx->PB->z;
260    PB_SET_INDEX( ctx, ctx->PB, ctx->VB->Index[pvert] );
261    count = ctx->PB->count;
262 
263 #define INTERP_XY 1
264 #define INTERP_Z 1
265 
266 #define PLOT(X,Y)		\
267 	pbx[count] = X;		\
268 	pby[count] = Y;		\
269 	pbz[count] = Z;		\
270 	count++;
271 
272 #include "linetemp.h"
273 
274    ctx->PB->count = count;
275    PB_CHECK_FLUSH( ctx, ctx->PB );
276 }
277 
278 
279 
280 /* Flat-shaded, RGBA line */
flat_rgba_line(GLcontext * ctx,GLuint vert0,GLuint vert1,GLuint pvert)281 static void flat_rgba_line( GLcontext *ctx,
282                             GLuint vert0, GLuint vert1, GLuint pvert )
283 {
284    GLint count;
285    GLint *pbx = ctx->PB->x;
286    GLint *pby = ctx->PB->y;
287    GLubyte *color = ctx->VB->Color[pvert];
288    PB_SET_COLOR( ctx, ctx->PB, color[0], color[1], color[2], color[3] );
289    count = ctx->PB->count;
290 
291 #define INTERP_XY 1
292 
293 #define PLOT(X,Y)		\
294 	pbx[count] = X;		\
295 	pby[count] = Y;		\
296 	count++;
297 
298 #include "linetemp.h"
299 
300    ctx->PB->count = count;
301    PB_CHECK_FLUSH( ctx, ctx->PB );
302 }
303 
304 
305 
306 /* Flat-shaded, RGBA line with Z interpolation/testing */
flat_rgba_z_line(GLcontext * ctx,GLuint vert0,GLuint vert1,GLuint pvert)307 static void flat_rgba_z_line( GLcontext *ctx,
308                               GLuint vert0, GLuint vert1, GLuint pvert )
309 {
310    GLint count;
311    GLint *pbx = ctx->PB->x;
312    GLint *pby = ctx->PB->y;
313    GLdepth *pbz = ctx->PB->z;
314    GLubyte *color = ctx->VB->Color[pvert];
315    PB_SET_COLOR( ctx, ctx->PB, color[0], color[1], color[2], color[3] );
316    count = ctx->PB->count;
317 
318 #define INTERP_XY 1
319 #define INTERP_Z 1
320 
321 #define PLOT(X,Y)	\
322 	pbx[count] = X;	\
323 	pby[count] = Y;	\
324 	pbz[count] = Z;	\
325 	count++;
326 
327 #include "linetemp.h"
328 
329    ctx->PB->count = count;
330    PB_CHECK_FLUSH( ctx, ctx->PB );
331 }
332 
333 
334 
335 /* Smooth shaded, color index line */
smooth_ci_line(GLcontext * ctx,GLuint vert0,GLuint vert1,GLuint pvert)336 static void smooth_ci_line( GLcontext *ctx,
337                             GLuint vert0, GLuint vert1, GLuint pvert )
338 {
339    GLint count = ctx->PB->count;
340    GLint *pbx = ctx->PB->x;
341    GLint *pby = ctx->PB->y;
342    GLuint *pbi = ctx->PB->i;
343 
344 #define INTERP_XY 1
345 #define INTERP_INDEX 1
346 
347 #define PLOT(X,Y)		\
348 	pbx[count] = X;		\
349 	pby[count] = Y;		\
350 	pbi[count] = I;		\
351 	count++;
352 
353 #include "linetemp.h"
354 
355    ctx->PB->count = count;
356    PB_CHECK_FLUSH( ctx, ctx->PB );
357 }
358 
359 
360 
361 /* Smooth shaded, color index line with Z interpolation/testing */
smooth_ci_z_line(GLcontext * ctx,GLuint vert0,GLuint vert1,GLuint pvert)362 static void smooth_ci_z_line( GLcontext *ctx,
363                               GLuint vert0, GLuint vert1, GLuint pvert )
364 {
365    GLint count = ctx->PB->count;
366    GLint *pbx = ctx->PB->x;
367    GLint *pby = ctx->PB->y;
368    GLdepth *pbz = ctx->PB->z;
369    GLuint *pbi = ctx->PB->i;
370 
371 #define INTERP_XY 1
372 #define INTERP_Z 1
373 #define INTERP_INDEX 1
374 
375 #define PLOT(X,Y)		\
376 	pbx[count] = X;		\
377 	pby[count] = Y;		\
378 	pbz[count] = Z;		\
379 	pbi[count] = I;		\
380 	count++;
381 
382 #include "linetemp.h"
383 
384    ctx->PB->count = count;
385    PB_CHECK_FLUSH( ctx, ctx->PB );
386 }
387 
388 
389 
390 /* Smooth-shaded, RGBA line */
smooth_rgba_line(GLcontext * ctx,GLuint vert0,GLuint vert1,GLuint pvert)391 static void smooth_rgba_line( GLcontext *ctx,
392                        	      GLuint vert0, GLuint vert1, GLuint pvert )
393 {
394    GLint count = ctx->PB->count;
395    GLint *pbx = ctx->PB->x;
396    GLint *pby = ctx->PB->y;
397    GLubyte *pbr = ctx->PB->r;
398    GLubyte *pbg = ctx->PB->g;
399    GLubyte *pbb = ctx->PB->b;
400    GLubyte *pba = ctx->PB->a;
401 
402 #define INTERP_XY 1
403 #define INTERP_RGB 1
404 #define INTERP_ALPHA 1
405 
406 #define PLOT(X,Y)			\
407 	pbx[count] = X;			\
408 	pby[count] = Y;			\
409 	pbr[count] = FixedToInt(r0);	\
410 	pbg[count] = FixedToInt(g0);	\
411 	pbb[count] = FixedToInt(b0);	\
412 	pba[count] = FixedToInt(a0);	\
413 	count++;
414 
415 #include "linetemp.h"
416 
417    ctx->PB->count = count;
418    PB_CHECK_FLUSH( ctx, ctx->PB );
419 }
420 
421 
422 
423 /* Smooth-shaded, RGBA line with Z interpolation/testing */
smooth_rgba_z_line(GLcontext * ctx,GLuint vert0,GLuint vert1,GLuint pvert)424 static void smooth_rgba_z_line( GLcontext *ctx,
425                        	        GLuint vert0, GLuint vert1, GLuint pvert )
426 {
427    GLint count = ctx->PB->count;
428    GLint *pbx = ctx->PB->x;
429    GLint *pby = ctx->PB->y;
430    GLdepth *pbz = ctx->PB->z;
431    GLubyte *pbr = ctx->PB->r;
432    GLubyte *pbg = ctx->PB->g;
433    GLubyte *pbb = ctx->PB->b;
434    GLubyte *pba = ctx->PB->a;
435 
436 #define INTERP_XY 1
437 #define INTERP_Z 1
438 #define INTERP_RGB 1
439 #define INTERP_ALPHA 1
440 
441 #define PLOT(X,Y)			\
442 	pbx[count] = X;			\
443 	pby[count] = Y;			\
444 	pbz[count] = Z;			\
445 	pbr[count] = FixedToInt(r0);	\
446 	pbg[count] = FixedToInt(g0);	\
447 	pbb[count] = FixedToInt(b0);	\
448 	pba[count] = FixedToInt(a0);	\
449 	count++;
450 
451 #include "linetemp.h"
452 
453    ctx->PB->count = count;
454    PB_CHECK_FLUSH( ctx, ctx->PB );
455 }
456 
457 
458 #define CHECK_FULL(count)			\
459 	if (count >= PB_SIZE-MAX_WIDTH) {	\
460 	   ctx->PB->count = count;		\
461 	   gl_flush_pb(ctx);			\
462 	   count = ctx->PB->count;		\
463 	}
464 
465 
466 
467 /* Smooth shaded, color index, any width, maybe stippled */
general_smooth_ci_line(GLcontext * ctx,GLuint vert0,GLuint vert1,GLuint pvert)468 static void general_smooth_ci_line( GLcontext *ctx,
469                            	    GLuint vert0, GLuint vert1, GLuint pvert )
470 {
471    GLint count = ctx->PB->count;
472    GLint *pbx = ctx->PB->x;
473    GLint *pby = ctx->PB->y;
474    GLdepth *pbz = ctx->PB->z;
475    GLuint *pbi = ctx->PB->i;
476 
477    if (ctx->Line.StippleFlag) {
478       /* stippled */
479 #define INTERP_XY 1
480 #define INTERP_Z 1
481 #define INTERP_INDEX 1
482 #define WIDE 1
483 #define STIPPLE 1
484 #define PLOT(X,Y)		\
485 	pbx[count] = X;		\
486 	pby[count] = Y;		\
487 	pbz[count] = Z;		\
488 	pbi[count] = I;		\
489 	count++;		\
490 	CHECK_FULL(count);
491 #include "linetemp.h"
492    }
493    else {
494       /* unstippled */
495       if (ctx->Line.Width==2.0F) {
496          /* special case: unstippled and width=2 */
497 #define INTERP_XY 1
498 #define INTERP_Z 1
499 #define INTERP_INDEX 1
500 #define XMAJOR_PLOT(X,Y)			\
501 	pbx[count] = X;  pbx[count+1] = X;	\
502 	pby[count] = Y;  pby[count+1] = Y+1;	\
503 	pbz[count] = Z;  pbz[count+1] = Z;	\
504 	pbi[count] = I;  pbi[count+1] = I;	\
505 	count += 2;
506 #define YMAJOR_PLOT(X,Y)			\
507 	pbx[count] = X;  pbx[count+1] = X+1;	\
508 	pby[count] = Y;  pby[count+1] = Y;	\
509 	pbz[count] = Z;  pbz[count+1] = Z;	\
510 	pbi[count] = I;  pbi[count+1] = I;	\
511 	count += 2;
512 #include "linetemp.h"
513       }
514       else {
515          /* unstippled, any width */
516 #define INTERP_XY 1
517 #define INTERP_Z 1
518 #define INTERP_INDEX 1
519 #define WIDE 1
520 #define PLOT(X,Y)		\
521 	pbx[count] = X;		\
522 	pby[count] = Y;		\
523 	pbz[count] = Z;		\
524 	pbi[count] = I;		\
525 	count++;		\
526 	CHECK_FULL(count);
527 #include "linetemp.h"
528       }
529    }
530 
531    ctx->PB->count = count;
532    PB_CHECK_FLUSH( ctx, ctx->PB );
533 }
534 
535 
536 /* Flat shaded, color index, any width, maybe stippled */
general_flat_ci_line(GLcontext * ctx,GLuint vert0,GLuint vert1,GLuint pvert)537 static void general_flat_ci_line( GLcontext *ctx,
538                                   GLuint vert0, GLuint vert1, GLuint pvert )
539 {
540    GLint count;
541    GLint *pbx = ctx->PB->x;
542    GLint *pby = ctx->PB->y;
543    GLdepth *pbz = ctx->PB->z;
544    PB_SET_INDEX( ctx, ctx->PB, ctx->VB->Index[pvert] );
545    count = ctx->PB->count;
546 
547    if (ctx->Line.StippleFlag) {
548       /* stippled, any width */
549 #define INTERP_XY 1
550 #define INTERP_Z 1
551 #define WIDE 1
552 #define STIPPLE 1
553 #define PLOT(X,Y)		\
554 	pbx[count] = X;		\
555 	pby[count] = Y;		\
556 	pbz[count] = Z;		\
557 	count++;		\
558 	CHECK_FULL(count);
559 #include "linetemp.h"
560    }
561    else {
562       /* unstippled */
563       if (ctx->Line.Width==2.0F) {
564          /* special case: unstippled and width=2 */
565 #define INTERP_XY 1
566 #define INTERP_Z 1
567 #define XMAJOR_PLOT(X,Y)			\
568 	pbx[count] = X;  pbx[count+1] = X;	\
569 	pby[count] = Y;  pby[count+1] = Y+1;	\
570 	pbz[count] = Z;  pbz[count+1] = Z;	\
571 	count += 2;
572 #define YMAJOR_PLOT(X,Y)			\
573 	pbx[count] = X;  pbx[count+1] = X+1;	\
574 	pby[count] = Y;  pby[count+1] = Y;	\
575 	pbz[count] = Z;  pbz[count+1] = Z;	\
576 	count += 2;
577 #include "linetemp.h"
578       }
579       else {
580          /* unstippled, any width */
581 #define INTERP_XY 1
582 #define INTERP_Z 1
583 #define WIDE 1
584 #define PLOT(X,Y)		\
585 	pbx[count] = X;		\
586 	pby[count] = Y;		\
587 	pbz[count] = Z;		\
588 	count++;		\
589 	CHECK_FULL(count);
590 #include "linetemp.h"
591       }
592    }
593 
594    ctx->PB->count = count;
595    PB_CHECK_FLUSH( ctx, ctx->PB );
596 }
597 
598 
599 
general_smooth_rgba_line(GLcontext * ctx,GLuint vert0,GLuint vert1,GLuint pvert)600 static void general_smooth_rgba_line( GLcontext *ctx,
601                                       GLuint vert0, GLuint vert1, GLuint pvert)
602 {
603    GLint count = ctx->PB->count;
604    GLint *pbx = ctx->PB->x;
605    GLint *pby = ctx->PB->y;
606    GLdepth *pbz = ctx->PB->z;
607    GLubyte *pbr = ctx->PB->r;
608    GLubyte *pbg = ctx->PB->g;
609    GLubyte *pbb = ctx->PB->b;
610    GLubyte *pba = ctx->PB->a;
611 
612    TRACE("Line %3.1f, %3.1f, %3.1f (r%u, g%u, b%u) --> %3.1f, %3.1f, %3.1f (r%u, g%u, b%u)\n",
613            ctx->VB->Win[vert0][0], ctx->VB->Win[vert0][1], ctx->VB->Win[vert0][2], ctx->VB->Color[vert0][0], ctx->VB->Color[vert0][1], ctx->VB->Color[vert0][2],
614            ctx->VB->Win[vert1][0], ctx->VB->Win[vert1][1], ctx->VB->Win[vert1][2], ctx->VB->Color[vert1][0], ctx->VB->Color[vert1][1], ctx->VB->Color[vert1][2]);
615 
616    if (ctx->Line.StippleFlag) {
617       /* stippled */
618 #define INTERP_XY 1
619 #define INTERP_Z 1
620 #define INTERP_RGB 1
621 #define INTERP_ALPHA 1
622 #define WIDE 1
623 #define STIPPLE 1
624 #define PLOT(X,Y)			\
625 	pbx[count] = X;			\
626 	pby[count] = Y;			\
627 	pbz[count] = Z;			\
628 	pbr[count] = FixedToInt(r0);	\
629 	pbg[count] = FixedToInt(g0);	\
630 	pbb[count] = FixedToInt(b0);	\
631 	pba[count] = FixedToInt(a0);	\
632 	count++;			\
633 	CHECK_FULL(count);
634 #include "linetemp.h"
635    }
636    else {
637       /* unstippled */
638       if (ctx->Line.Width==2.0F) {
639          /* special case: unstippled and width=2 */
640 #define INTERP_XY 1
641 #define INTERP_Z 1
642 #define INTERP_RGB 1
643 #define INTERP_ALPHA 1
644 #define XMAJOR_PLOT(X,Y)						\
645 	pbx[count] = X;  pbx[count+1] = X;				\
646 	pby[count] = Y;  pby[count+1] = Y+1;				\
647 	pbz[count] = Z;  pbz[count+1] = Z;				\
648 	pbr[count] = FixedToInt(r0);  pbr[count+1] = FixedToInt(r0);	\
649 	pbg[count] = FixedToInt(g0);  pbg[count+1] = FixedToInt(g0);	\
650 	pbb[count] = FixedToInt(b0);  pbb[count+1] = FixedToInt(b0);	\
651 	pba[count] = FixedToInt(a0);  pba[count+1] = FixedToInt(a0);	\
652 	count += 2;
653 #define YMAJOR_PLOT(X,Y)						\
654 	pbx[count] = X;  pbx[count+1] = X+1;				\
655 	pby[count] = Y;  pby[count+1] = Y;				\
656 	pbz[count] = Z;  pbz[count+1] = Z;				\
657 	pbr[count] = FixedToInt(r0);  pbr[count+1] = FixedToInt(r0);	\
658 	pbg[count] = FixedToInt(g0);  pbg[count+1] = FixedToInt(g0);	\
659 	pbb[count] = FixedToInt(b0);  pbb[count+1] = FixedToInt(b0);	\
660 	pba[count] = FixedToInt(a0);  pba[count+1] = FixedToInt(a0);	\
661 	count += 2;
662 #include "linetemp.h"
663       }
664       else {
665          /* unstippled, any width */
666 #define INTERP_XY 1
667 #define INTERP_Z 1
668 #define INTERP_RGB 1
669 #define INTERP_ALPHA 1
670 #define WIDE 1
671 #define PLOT(X,Y)			\
672 	pbx[count] = X;			\
673 	pby[count] = Y;			\
674 	pbz[count] = Z;			\
675 	pbr[count] = FixedToInt(r0);	\
676 	pbg[count] = FixedToInt(g0);	\
677 	pbb[count] = FixedToInt(b0);	\
678 	pba[count] = FixedToInt(a0);	\
679 	count++;			\
680 	CHECK_FULL(count);
681 #include "linetemp.h"
682       }
683    }
684 
685    ctx->PB->count = count;
686    PB_CHECK_FLUSH( ctx, ctx->PB );
687 }
688 
689 
general_flat_rgba_line(GLcontext * ctx,GLuint vert0,GLuint vert1,GLuint pvert)690 static void general_flat_rgba_line( GLcontext *ctx,
691                                     GLuint vert0, GLuint vert1, GLuint pvert )
692 {
693    GLint count;
694    GLint *pbx = ctx->PB->x;
695    GLint *pby = ctx->PB->y;
696    GLdepth *pbz = ctx->PB->z;
697    GLubyte *color = ctx->VB->Color[pvert];
698    PB_SET_COLOR( ctx, ctx->PB, color[0], color[1], color[2], color[3] );
699    count = ctx->PB->count;
700 
701    if (ctx->Line.StippleFlag) {
702       /* stippled */
703 #define INTERP_XY 1
704 #define INTERP_Z 1
705 #define WIDE 1
706 #define STIPPLE 1
707 #define PLOT(X,Y)			\
708 	pbx[count] = X;			\
709 	pby[count] = Y;			\
710 	pbz[count] = Z;			\
711 	count++;			\
712 	CHECK_FULL(count);
713 #include "linetemp.h"
714    }
715    else {
716       /* unstippled */
717       if (ctx->Line.Width==2.0F) {
718          /* special case: unstippled and width=2 */
719 #define INTERP_XY 1
720 #define INTERP_Z 1
721 #define XMAJOR_PLOT(X,Y)			\
722 	pbx[count] = X;  pbx[count+1] = X;	\
723 	pby[count] = Y;  pby[count+1] = Y+1;	\
724 	pbz[count] = Z;  pbz[count+1] = Z;	\
725 	count += 2;
726 #define YMAJOR_PLOT(X,Y)			\
727 	pbx[count] = X;  pbx[count+1] = X+1;	\
728 	pby[count] = Y;  pby[count+1] = Y;	\
729 	pbz[count] = Z;  pbz[count+1] = Z;	\
730 	count += 2;
731 #include "linetemp.h"
732       }
733       else {
734          /* unstippled, any width */
735 #define INTERP_XY 1
736 #define INTERP_Z 1
737 #define WIDE 1
738 #define PLOT(X,Y)			\
739 	pbx[count] = X;			\
740 	pby[count] = Y;			\
741 	pbz[count] = Z;			\
742 	count++;			\
743 	CHECK_FULL(count);
744 #include "linetemp.h"
745       }
746    }
747 
748    ctx->PB->count = count;
749    PB_CHECK_FLUSH( ctx, ctx->PB );
750 }
751 
752 
753 
754 /* Flat-shaded, textured, any width, maybe stippled */
flat_textured_line(GLcontext * ctx,GLuint vert0,GLuint vert1,GLuint pv)755 static void flat_textured_line( GLcontext *ctx,
756                                 GLuint vert0, GLuint vert1, GLuint pv )
757 {
758    GLint count;
759    GLint *pbx = ctx->PB->x;
760    GLint *pby = ctx->PB->y;
761    GLdepth *pbz = ctx->PB->z;
762    GLfloat *pbs = ctx->PB->s;
763    GLfloat *pbt = ctx->PB->t;
764    GLfloat *pbu = ctx->PB->u;
765    GLubyte *color = ctx->VB->Color[pv];
766    PB_SET_COLOR( ctx, ctx->PB, color[0], color[1], color[2], color[3] );
767    count = ctx->PB->count;
768 
769    if (ctx->Line.StippleFlag) {
770       /* stippled */
771 #define INTERP_XY 1
772 #define INTERP_Z 1
773 #define INTERP_STW 1
774 #define INTERP_UV 1
775 #define WIDE 1
776 #define STIPPLE 1
777 #define PLOT(X,Y)			\
778 	pbx[count] = X;			\
779 	pby[count] = Y;			\
780 	pbz[count] = Z;			\
781 	pbs[count] = s0 / w0;		\
782 	pbt[count] = t0 / w0;		\
783 	pbu[count] = u0 / w0;		\
784 	count++;			\
785 	CHECK_FULL(count);
786 #include "linetemp.h"
787    }
788    else {
789       /* unstippled */
790 #define INTERP_XY 1
791 #define INTERP_Z 1
792 #define INTERP_STW 1
793 #define INTERP_UV 1
794 #define WIDE 1
795 #define PLOT(X,Y)			\
796 	pbx[count] = X;			\
797 	pby[count] = Y;			\
798 	pbz[count] = Z;			\
799 	pbs[count] = s0 / w0;		\
800 	pbt[count] = t0 / w0;		\
801 	pbu[count] = u0 / w0;		\
802 	count++;			\
803 	CHECK_FULL(count);
804 #include "linetemp.h"
805    }
806 
807    ctx->PB->count = count;
808    PB_CHECK_FLUSH( ctx, ctx->PB );
809 }
810 
811 
812 
813 /* Smooth-shaded, textured, any width, maybe stippled */
smooth_textured_line(GLcontext * ctx,GLuint vert0,GLuint vert1,GLuint pv)814 static void smooth_textured_line( GLcontext *ctx,
815                                   GLuint vert0, GLuint vert1, GLuint pv )
816 {
817    GLint count = ctx->PB->count;
818    GLint *pbx = ctx->PB->x;
819    GLint *pby = ctx->PB->y;
820    GLdepth *pbz = ctx->PB->z;
821    GLfloat *pbs = ctx->PB->s;
822    GLfloat *pbt = ctx->PB->t;
823    GLfloat *pbu = ctx->PB->u;
824    GLubyte *pbr = ctx->PB->r;
825    GLubyte *pbg = ctx->PB->g;
826    GLubyte *pbb = ctx->PB->b;
827    GLubyte *pba = ctx->PB->a;
828 
829    if (ctx->Line.StippleFlag) {
830       /* stippled */
831 #define INTERP_XY 1
832 #define INTERP_Z 1
833 #define INTERP_RGB 1
834 #define INTERP_ALPHA 1
835 #define INTERP_STW 1
836 #define INTERP_UV 1
837 #define WIDE 1
838 #define STIPPLE 1
839 #define PLOT(X,Y)			\
840 	pbx[count] = X;			\
841 	pby[count] = Y;			\
842 	pbz[count] = Z;			\
843 	pbs[count] = s0 / w0;		\
844 	pbt[count] = t0 / w0;		\
845 	pbu[count] = u0 / w0;		\
846 	pbr[count] = FixedToInt(r0);	\
847 	pbg[count] = FixedToInt(g0);	\
848 	pbb[count] = FixedToInt(b0);	\
849 	pba[count] = FixedToInt(a0);	\
850 	count++;			\
851 	CHECK_FULL(count);
852 #include "linetemp.h"
853    }
854    else {
855       /* unstippled */
856 #define INTERP_XY 1
857 #define INTERP_Z 1
858 #define INTERP_RGB 1
859 #define INTERP_ALPHA 1
860 #define INTERP_STW 1
861 #define INTERP_UV 1
862 #define WIDE 1
863 #define PLOT(X,Y)			\
864 	pbx[count] = X;			\
865 	pby[count] = Y;			\
866 	pbz[count] = Z;			\
867 	pbs[count] = s0 / w0;		\
868 	pbt[count] = t0 / w0;		\
869 	pbu[count] = u0 / w0;		\
870 	pbr[count] = FixedToInt(r0);	\
871 	pbg[count] = FixedToInt(g0);	\
872 	pbb[count] = FixedToInt(b0);	\
873 	pba[count] = FixedToInt(a0);	\
874 	count++;			\
875 	CHECK_FULL(count);
876 #include "linetemp.h"
877    }
878 
879    ctx->PB->count = count;
880    PB_CHECK_FLUSH( ctx, ctx->PB );
881 }
882 
883 
884 
885 /*
886  * Null rasterizer for measuring transformation speed.
887  */
null_line(GLcontext * ctx,GLuint v1,GLuint v2,GLuint pv)888 static void null_line( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv )
889 {
890 }
891 
892 
893 
894 /*
895  * Determine which line drawing function to use given the current
896  * rendering context.
897  */
gl_set_line_function(GLcontext * ctx)898 void gl_set_line_function( GLcontext *ctx )
899 {
900    GLboolean rgbmode = ctx->Visual->RGBAflag;
901    /* TODO: antialiased lines */
902 
903    if (ctx->RenderMode==GL_RENDER) {
904       if (ctx->NoRaster) {
905          ctx->Driver.LineFunc = null_line;
906          return;
907       }
908       if (ctx->Driver.LineFunc) {
909          /* Device driver will draw lines. */
910          ctx->Driver.LineFunc = ctx->Driver.LineFunc;
911       }
912       else if (ctx->Texture.Enabled) {
913          if (ctx->Light.ShadeModel==GL_SMOOTH) {
914             ctx->Driver.LineFunc = smooth_textured_line;
915          }
916          else {
917             ctx->Driver.LineFunc = flat_textured_line;
918          }
919       }
920       else if (ctx->Line.Width!=1.0 || ctx->Line.StippleFlag
921                || ctx->Line.SmoothFlag || ctx->Texture.Enabled) {
922          if (ctx->Light.ShadeModel==GL_SMOOTH) {
923             if (rgbmode)
924                ctx->Driver.LineFunc = general_smooth_rgba_line;
925             else
926                ctx->Driver.LineFunc = general_smooth_ci_line;
927          }
928          else {
929             if (rgbmode)
930                ctx->Driver.LineFunc = general_flat_rgba_line;
931             else
932                ctx->Driver.LineFunc = general_flat_ci_line;
933          }
934       }
935       else {
936 	 if (ctx->Light.ShadeModel==GL_SMOOTH) {
937 	    /* Width==1, non-stippled, smooth-shaded */
938             if (ctx->Depth.Test
939 	        || (ctx->Fog.Enabled && ctx->Hint.Fog==GL_NICEST)) {
940                if (rgbmode)
941                   ctx->Driver.LineFunc = smooth_rgba_z_line;
942                else
943                   ctx->Driver.LineFunc = smooth_ci_z_line;
944             }
945             else {
946                if (rgbmode)
947                   ctx->Driver.LineFunc = smooth_rgba_line;
948                else
949                   ctx->Driver.LineFunc = smooth_ci_line;
950             }
951 	 }
952          else {
953 	    /* Width==1, non-stippled, flat-shaded */
954             if (ctx->Depth.Test
955                 || (ctx->Fog.Enabled && ctx->Hint.Fog==GL_NICEST)) {
956                if (rgbmode)
957                   ctx->Driver.LineFunc = flat_rgba_z_line;
958                else
959                   ctx->Driver.LineFunc = flat_ci_z_line;
960             }
961             else {
962                if (rgbmode)
963                   ctx->Driver.LineFunc = flat_rgba_line;
964                else
965                   ctx->Driver.LineFunc = flat_ci_line;
966             }
967          }
968       }
969    }
970    else if (ctx->RenderMode==GL_FEEDBACK) {
971       ctx->Driver.LineFunc = feedback_line;
972    }
973    else {
974       /* GL_SELECT mode */
975       ctx->Driver.LineFunc = select_line;
976    }
977 }
978 
979