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