s_lines.c revision 0070d398d13759adc519f9bc764ffd39bc88890e
1d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath/* $Id: s_lines.c,v 1.3 2000/11/05 23:18:36 brianp Exp $ */
2d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath
3d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath/*
4d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath * Mesa 3-D graphics library
5d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath * Version:  3.5
6d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath *
7d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath * Copyright (C) 1999-2000  Brian Paul   All Rights Reserved.
8d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath *
9d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath * Permission is hereby granted, free of charge, to any person obtaining a
10d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath * copy of this software and associated documentation files (the "Software"),
11d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath * to deal in the Software without restriction, including without limitation
12d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath * and/or sell copies of the Software, and to permit persons to whom the
14d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath * Software is furnished to do so, subject to the following conditions:
15d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath *
16d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath * The above copyright notice and this permission notice shall be included
17d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath * in all copies or substantial portions of the Software.
18d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath *
19d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
22d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath */
26d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath
27d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath
28d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath#include "glheader.h"
29d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath#include "macros.h"
30d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath#include "mmath.h"
31d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath#include "vb.h"
32d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath#include "s_aaline.h"
33d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath#include "s_pb.h"
34d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath#include "s_context.h"
35d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath#include "s_depth.h"
36d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath#include "s_lines.h"
37d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath#include "s_feedback.h"
38d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath
39d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath
40d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath
41d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath/**********************************************************************/
42d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath/*****                    Rasterization                           *****/
43d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath/**********************************************************************/
44d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath
45d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath
46d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath/*
47d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath * There are 4 pairs (RGBA, CI) of line drawing functions:
48d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath *   1. simple:  width=1 and no special rasterization functions (fastest)
49d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath *   2. flat:  width=1, non-stippled, flat-shaded, any raster operations
50d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath *   3. smooth:  width=1, non-stippled, smooth-shaded, any raster operations
51d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath *   4. general:  any other kind of line (slowest)
52d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath */
53d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath
54d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath
55d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath
56d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath/* Flat, color index line */
57d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamathstatic void flat_ci_line( GLcontext *ctx,
58d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath                          SWvertex *vert0,
59d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath			  SWvertex *vert1 )
60d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath{
61d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath   struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
62d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath
63d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath   PB_SET_INDEX( PB, vert0->index );
64d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath
65d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath#define INTERP_XY 1
66d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath#define PLOT(X,Y)  PB_WRITE_PIXEL(PB, X, Y, 0, 0);
67d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath
68d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath#include "s_linetemp.h"
69d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath
70d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath   gl_flush_pb(ctx);
71d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath}
72d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath
73d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath
74d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath
75d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath/* Flat, color index line with Z interpolation/testing */
76d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamathstatic void flat_ci_z_line( GLcontext *ctx,
77d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath                            SWvertex *vert0,
78d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath			    SWvertex *vert1 )
79d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath{
80d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath   struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
81d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath   PB_SET_INDEX( PB, vert0->index );
82d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath
83d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath#define INTERP_XY 1
84d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath#define INTERP_Z 1
85d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath#define PLOT(X,Y)  PB_WRITE_PIXEL(PB, X, Y, Z, fog0);
86d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath
87d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath#include "s_linetemp.h"
88d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath
89d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath   gl_flush_pb(ctx);
90d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath}
91d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath
92d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath
93d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath
94d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath/* Flat-shaded, RGBA line */
95d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamathstatic void flat_rgba_line( GLcontext *ctx,
96d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath                            SWvertex *vert0,
97d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath			    SWvertex *vert1 )
98d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath{
99d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath   const GLchan *color = vert0->color;
100d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath   struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
101d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath   PB_SET_COLOR( PB, color[0], color[1], color[2], color[3] );
102d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath
103d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath#define INTERP_XY 1
104d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath#define PLOT(X,Y)   PB_WRITE_PIXEL(PB, X, Y, 0, 0);
105d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath
106d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath#include "s_linetemp.h"
107d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath
108d6b37fdf6c24321a87566ad4053dad5daa3a844aNarayan Kamath   gl_flush_pb(ctx);
109}
110
111
112
113/* Flat-shaded, RGBA line with Z interpolation/testing */
114static void flat_rgba_z_line( GLcontext *ctx,
115                              SWvertex *vert0,
116			      SWvertex *vert1 )
117{
118   const GLchan *color = vert0->color;
119   struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
120   PB_SET_COLOR( PB, color[0], color[1], color[2], color[3] );
121
122#define INTERP_XY 1
123#define INTERP_Z 1
124#define PLOT(X,Y)   PB_WRITE_PIXEL(PB, X, Y, Z, fog0);
125
126#include "s_linetemp.h"
127
128   gl_flush_pb(ctx);
129}
130
131
132
133/* Smooth shaded, color index line */
134static void smooth_ci_line( GLcontext *ctx,
135                            SWvertex *vert0,
136			    SWvertex *vert1 )
137{
138   struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
139   GLint count = PB->count;
140   GLint *pbx = PB->x;
141   GLint *pby = PB->y;
142   GLuint *pbi = PB->index;
143
144   PB->mono = GL_FALSE;
145
146#define INTERP_XY 1
147#define INTERP_INDEX 1
148
149#define PLOT(X,Y)		\
150	pbx[count] = X;		\
151	pby[count] = Y;		\
152	pbi[count] = I;		\
153	count++;
154
155#include "s_linetemp.h"
156
157   PB->count = count;
158   gl_flush_pb(ctx);
159}
160
161
162
163/* Smooth shaded, color index line with Z interpolation/testing */
164static void smooth_ci_z_line( GLcontext *ctx,
165                              SWvertex *vert0,
166			      SWvertex *vert1 )
167{
168   struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
169   GLint count = PB->count;
170   GLint *pbx = PB->x;
171   GLint *pby = PB->y;
172   GLdepth *pbz = PB->z;
173   GLuint *pbi = PB->index;
174
175   PB->mono = GL_FALSE;
176
177#define INTERP_XY 1
178#define INTERP_Z 1
179#define INTERP_INDEX 1
180
181#define PLOT(X,Y)		\
182	pbx[count] = X;		\
183	pby[count] = Y;		\
184	pbz[count] = Z;		\
185	pbi[count] = I;		\
186	count++;
187
188#include "s_linetemp.h"
189
190   PB->count = count;
191   gl_flush_pb(ctx);
192}
193
194
195
196/* Smooth-shaded, RGBA line */
197static void smooth_rgba_line( GLcontext *ctx,
198                       	      SWvertex *vert0,
199			      SWvertex *vert1 )
200{
201   struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
202   GLint count = PB->count;
203   GLint *pbx = PB->x;
204   GLint *pby = PB->y;
205   GLchan (*pbrgba)[4] = PB->rgba;
206
207   PB->mono = GL_FALSE;
208
209#define INTERP_XY 1
210#define INTERP_RGB 1
211#define INTERP_ALPHA 1
212
213#define PLOT(X,Y)			\
214	pbx[count] = X;			\
215	pby[count] = Y;			\
216	pbrgba[count][RCOMP] = FixedToInt(r0);	\
217	pbrgba[count][GCOMP] = FixedToInt(g0);	\
218	pbrgba[count][BCOMP] = FixedToInt(b0);	\
219	pbrgba[count][ACOMP] = FixedToInt(a0);	\
220	count++;
221
222#include "s_linetemp.h"
223
224   PB->count = count;
225   gl_flush_pb(ctx);
226}
227
228
229
230/* Smooth-shaded, RGBA line with Z interpolation/testing */
231static void smooth_rgba_z_line( GLcontext *ctx,
232                       	        SWvertex *vert0,
233				SWvertex *vert1 )
234{
235   struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
236   GLint count = PB->count;
237   GLint *pbx = PB->x;
238   GLint *pby = PB->y;
239   GLdepth *pbz = PB->z;
240   GLfixed *pbfog = PB->fog;
241   GLchan (*pbrgba)[4] = PB->rgba;
242
243
244   PB->mono = GL_FALSE;
245
246#define INTERP_XY 1
247#define INTERP_Z 1
248#define INTERP_RGB 1
249#define INTERP_ALPHA 1
250
251#define PLOT(X,Y)				\
252	pbx[count] = X;				\
253	pby[count] = Y;				\
254	pbz[count] = Z;				\
255	pbfog[count] = fog0;			\
256	pbrgba[count][RCOMP] = FixedToInt(r0);	\
257	pbrgba[count][GCOMP] = FixedToInt(g0);	\
258	pbrgba[count][BCOMP] = FixedToInt(b0);	\
259	pbrgba[count][ACOMP] = FixedToInt(a0);	\
260	count++;
261
262#include "s_linetemp.h"
263
264   PB->count = count;
265   gl_flush_pb(ctx);
266}
267
268
269#define CHECK_FULL(count)		\
270   if (count >= PB_SIZE-MAX_WIDTH) {	\
271      PB->count = count;		\
272      gl_flush_pb(ctx);			\
273      count = PB->count;		\
274   }
275
276
277
278/* Smooth shaded, color index, any width, maybe stippled */
279static void general_smooth_ci_line( GLcontext *ctx,
280                           	    SWvertex *vert0,
281				    SWvertex *vert1 )
282{
283   struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
284   GLint count = PB->count;
285   GLint *pbx = PB->x;
286   GLint *pby = PB->y;
287   GLdepth *pbz = PB->z;
288   GLfixed *pbfog = PB->fog;
289   GLuint *pbi = PB->index;
290
291   PB->mono = GL_FALSE;
292
293   if (ctx->Line.StippleFlag) {
294      /* stippled */
295#define INTERP_XY 1
296#define INTERP_Z 1
297#define INTERP_INDEX 1
298#define WIDE 1
299#define STIPPLE 1
300#define PLOT(X,Y)		\
301	pbx[count] = X;		\
302	pby[count] = Y;		\
303	pbz[count] = Z;		\
304	pbfog[count] = fog0;	\
305	pbi[count] = I;		\
306	count++;		\
307	CHECK_FULL(count);
308#include "s_linetemp.h"
309   }
310   else {
311      /* unstippled */
312      if (ctx->Line.Width==2.0F) {
313         /* special case: unstippled and width=2 */
314#define INTERP_XY 1
315#define INTERP_Z 1
316#define INTERP_INDEX 1
317#define XMAJOR_PLOT(X,Y)				\
318	pbx[count] = X;  pbx[count+1] = X;		\
319	pby[count] = Y;  pby[count+1] = Y+1;		\
320	pbz[count] = Z;  pbz[count+1] = Z;		\
321	pbfog[count] = fog0;  pbfog[count+1] = fog0;	\
322	pbi[count] = I;  pbi[count+1] = I;		\
323	count += 2;					\
324	CHECK_FULL(count);
325#define YMAJOR_PLOT(X,Y)				\
326	pbx[count] = X;  pbx[count+1] = X+1;		\
327	pby[count] = Y;  pby[count+1] = Y;		\
328	pbz[count] = Z;  pbz[count+1] = Z;		\
329	pbfog[count] = fog0;  pbfog[count+1] = fog0;	\
330	pbi[count] = I;  pbi[count+1] = I;		\
331	count += 2;					\
332	CHECK_FULL(count);
333#include "s_linetemp.h"
334      }
335      else {
336         /* unstippled, any width */
337#define INTERP_XY 1
338#define INTERP_Z 1
339#define INTERP_INDEX 1
340#define WIDE 1
341#define PLOT(X,Y)		\
342	pbx[count] = X;		\
343	pby[count] = Y;		\
344	pbz[count] = Z;		\
345	pbi[count] = I;		\
346	pbfog[count] = fog0;	\
347	count++;		\
348	CHECK_FULL(count);
349#include "s_linetemp.h"
350      }
351   }
352
353   PB->count = count;
354   gl_flush_pb(ctx);
355}
356
357
358/* Flat shaded, color index, any width, maybe stippled */
359static void general_flat_ci_line( GLcontext *ctx,
360                                  SWvertex *vert0,
361				  SWvertex *vert1 )
362{
363   struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
364   GLint count;
365   GLint *pbx = PB->x;
366   GLint *pby = PB->y;
367   GLdepth *pbz = PB->z;
368   GLfixed *pbfog = PB->fog;
369   PB_SET_INDEX( PB, vert0->index );
370   count = PB->count;
371
372   if (ctx->Line.StippleFlag) {
373      /* stippled, any width */
374#define INTERP_XY 1
375#define INTERP_Z 1
376#define WIDE 1
377#define STIPPLE 1
378#define PLOT(X,Y)		\
379	pbx[count] = X;		\
380	pby[count] = Y;		\
381	pbz[count] = Z;		\
382	pbfog[count] = fog0;	\
383	count++;		\
384	CHECK_FULL(count);
385#include "s_linetemp.h"
386   }
387   else {
388      /* unstippled */
389      if (ctx->Line.Width==2.0F) {
390         /* special case: unstippled and width=2 */
391#define INTERP_XY 1
392#define INTERP_Z 1
393#define XMAJOR_PLOT(X,Y)				\
394	pbx[count] = X;  pbx[count+1] = X;		\
395	pby[count] = Y;  pby[count+1] = Y+1;		\
396	pbz[count] = Z;  pbz[count+1] = Z;		\
397	pbfog[count] = fog0;  pbfog[count+1] = fog0;	\
398	count += 2;					\
399	CHECK_FULL(count);
400#define YMAJOR_PLOT(X,Y)				\
401	pbx[count] = X;  pbx[count+1] = X+1;		\
402	pby[count] = Y;  pby[count+1] = Y;		\
403	pbz[count] = Z;  pbz[count+1] = Z;		\
404	pbfog[count] = fog0;  pbfog[count+1] = fog0;	\
405	count += 2;					\
406	CHECK_FULL(count);
407#include "s_linetemp.h"
408      }
409      else {
410         /* unstippled, any width */
411#define INTERP_XY 1
412#define INTERP_Z 1
413#define WIDE 1
414#define PLOT(X,Y)		\
415	pbx[count] = X;		\
416	pby[count] = Y;		\
417	pbz[count] = Z;		\
418	pbfog[count] = fog0;	\
419	count++;		\
420	CHECK_FULL(count);
421#include "s_linetemp.h"
422      }
423   }
424
425   PB->count = count;
426   gl_flush_pb(ctx);
427}
428
429
430
431static void general_smooth_rgba_line( GLcontext *ctx,
432                                      SWvertex *vert0,
433				      SWvertex *vert1 )
434{
435   struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
436   GLint count = PB->count;
437   GLint *pbx = PB->x;
438   GLint *pby = PB->y;
439   GLdepth *pbz = PB->z;
440   GLfixed *pbfog = PB->fog;
441   GLchan (*pbrgba)[4] = PB->rgba;
442
443   PB->mono = GL_FALSE;
444
445   if (ctx->Line.StippleFlag) {
446      /* stippled */
447#define INTERP_XY 1
448#define INTERP_Z 1
449#define INTERP_RGB 1
450#define INTERP_ALPHA 1
451#define WIDE 1
452#define STIPPLE 1
453#define PLOT(X,Y)				\
454	pbx[count] = X;				\
455	pby[count] = Y;				\
456	pbz[count] = Z;				\
457	pbfog[count] = fog0;			\
458	pbrgba[count][RCOMP] = FixedToInt(r0);	\
459	pbrgba[count][GCOMP] = FixedToInt(g0);	\
460	pbrgba[count][BCOMP] = FixedToInt(b0);	\
461	pbrgba[count][ACOMP] = FixedToInt(a0);	\
462	count++;				\
463	CHECK_FULL(count);
464#include "s_linetemp.h"
465   }
466   else {
467      /* unstippled */
468      if (ctx->Line.Width==2.0F) {
469         /* special case: unstippled and width=2 */
470#define INTERP_XY 1
471#define INTERP_Z 1
472#define INTERP_RGB 1
473#define INTERP_ALPHA 1
474#define XMAJOR_PLOT(X,Y)				\
475	pbx[count] = X;  pbx[count+1] = X;		\
476	pby[count] = Y;  pby[count+1] = Y+1;		\
477	pbz[count] = Z;  pbz[count+1] = Z;		\
478	pbfog[count] = fog0;  pbfog[count+1] = fog0;	\
479	pbrgba[count][RCOMP] = FixedToInt(r0);		\
480	pbrgba[count][GCOMP] = FixedToInt(g0);		\
481	pbrgba[count][BCOMP] = FixedToInt(b0);		\
482	pbrgba[count][ACOMP] = FixedToInt(a0);		\
483	pbrgba[count+1][RCOMP] = FixedToInt(r0);	\
484	pbrgba[count+1][GCOMP] = FixedToInt(g0);	\
485	pbrgba[count+1][BCOMP] = FixedToInt(b0);	\
486	pbrgba[count+1][ACOMP] = FixedToInt(a0);	\
487	count += 2;					\
488	CHECK_FULL(count);
489#define YMAJOR_PLOT(X,Y)				\
490	pbx[count] = X;  pbx[count+1] = X+1;		\
491	pby[count] = Y;  pby[count+1] = Y;		\
492	pbz[count] = Z;  pbz[count+1] = Z;		\
493	pbfog[count] = fog0;  pbfog[count+1] = fog0;	\
494	pbrgba[count][RCOMP] = FixedToInt(r0);		\
495	pbrgba[count][GCOMP] = FixedToInt(g0);		\
496	pbrgba[count][BCOMP] = FixedToInt(b0);		\
497	pbrgba[count][ACOMP] = FixedToInt(a0);		\
498	pbrgba[count+1][RCOMP] = FixedToInt(r0);	\
499	pbrgba[count+1][GCOMP] = FixedToInt(g0);	\
500	pbrgba[count+1][BCOMP] = FixedToInt(b0);	\
501	pbrgba[count+1][ACOMP] = FixedToInt(a0);	\
502	count += 2;					\
503	CHECK_FULL(count);
504#include "s_linetemp.h"
505      }
506      else {
507         /* unstippled, any width */
508#define INTERP_XY 1
509#define INTERP_Z 1
510#define INTERP_RGB 1
511#define INTERP_ALPHA 1
512#define WIDE 1
513#define PLOT(X,Y)				\
514	pbx[count] = X;				\
515	pby[count] = Y;				\
516	pbz[count] = Z;				\
517	pbfog[count] = fog0;  			\
518	pbrgba[count][RCOMP] = FixedToInt(r0);	\
519	pbrgba[count][GCOMP] = FixedToInt(g0);	\
520	pbrgba[count][BCOMP] = FixedToInt(b0);	\
521	pbrgba[count][ACOMP] = FixedToInt(a0);	\
522	count++;				\
523	CHECK_FULL(count);
524#include "s_linetemp.h"
525      }
526   }
527
528   PB->count = count;
529   gl_flush_pb(ctx);
530}
531
532
533static void general_flat_rgba_line( GLcontext *ctx,
534                                    SWvertex *vert0,
535				    SWvertex *vert1 )
536{
537   struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
538   const GLchan *color = vert0->color;
539   PB_SET_COLOR( PB, color[0], color[1], color[2], color[3] );
540
541   if (ctx->Line.StippleFlag) {
542      /* stippled */
543#define INTERP_XY 1
544#define INTERP_Z 1
545#define WIDE 1
546#define STIPPLE 1
547#define PLOT(X,Y)  PB_WRITE_PIXEL(PB, X, Y, Z, fog0);
548#include "s_linetemp.h"
549   }
550   else {
551      /* unstippled */
552      if (ctx->Line.Width==2.0F) {
553         /* special case: unstippled and width=2 */
554#define INTERP_XY 1
555#define INTERP_Z 1
556#define XMAJOR_PLOT(X,Y) PB_WRITE_PIXEL(PB, X, Y, Z, fog0); \
557                         PB_WRITE_PIXEL(PB, X, Y+1, Z, fog0);
558#define YMAJOR_PLOT(X,Y)  PB_WRITE_PIXEL(PB, X, Y, Z, fog0); \
559                          PB_WRITE_PIXEL(PB, X+1, Y, Z, fog0);
560#include "s_linetemp.h"
561      }
562      else {
563         /* unstippled, any width */
564#define INTERP_XY 1
565#define INTERP_Z 1
566#define WIDE 1
567#define PLOT(X,Y) PB_WRITE_PIXEL(PB, X, Y, Z, fog0);
568#include "s_linetemp.h"
569      }
570   }
571
572   gl_flush_pb(ctx);
573}
574
575
576/* Flat-shaded, textured, any width, maybe stippled */
577static void flat_textured_line( GLcontext *ctx,
578                                SWvertex *vert0,
579				SWvertex *vert1 )
580{
581   struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
582   GLint count;
583   GLint *pbx = PB->x;
584   GLint *pby = PB->y;
585   GLdepth *pbz = PB->z;
586   GLfixed *pbfog = PB->fog;
587   GLfloat *pbs = PB->s[0];
588   GLfloat *pbt = PB->t[0];
589   GLfloat *pbu = PB->u[0];
590   GLchan *color = vert0->color;
591   PB_SET_COLOR( PB, color[0], color[1], color[2], color[3] );
592   count = PB->count;
593
594   if (ctx->Line.StippleFlag) {
595      /* stippled */
596#define INTERP_XY 1
597#define INTERP_Z 1
598#define INTERP_TEX 1
599#define WIDE 1
600#define STIPPLE 1
601#define PLOT(X,Y)			\
602	{				\
603	   pbx[count] = X;		\
604	   pby[count] = Y;		\
605	   pbz[count] = Z;		\
606 	   pbfog[count] = fog0;		\
607	   pbs[count] = fragTexcoord[0];\
608	   pbt[count] = fragTexcoord[1];\
609	   pbu[count] = fragTexcoord[2];\
610	   count++;			\
611	   CHECK_FULL(count);		\
612	}
613#include "s_linetemp.h"
614   }
615   else {
616      /* unstippled */
617#define INTERP_XY 1
618#define INTERP_Z 1
619#define INTERP_TEX 1
620#define WIDE 1
621#define PLOT(X,Y)			\
622	{				\
623	   pbx[count] = X;		\
624	   pby[count] = Y;		\
625	   pbz[count] = Z;		\
626 	   pbfog[count] = fog0;		\
627	   pbs[count] = fragTexcoord[0];\
628	   pbt[count] = fragTexcoord[1];\
629	   pbu[count] = fragTexcoord[2];\
630	   count++;			\
631	   CHECK_FULL(count);		\
632	}
633#include "s_linetemp.h"
634   }
635
636   PB->count = count;
637   gl_flush_pb(ctx);
638}
639
640
641
642/* Smooth-shaded, textured, any width, maybe stippled */
643static void smooth_textured_line( GLcontext *ctx,
644                                  SWvertex *vert0,
645				  SWvertex *vert1 )
646{
647   struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
648   GLint count = PB->count;
649   GLint *pbx = PB->x;
650   GLint *pby = PB->y;
651   GLdepth *pbz = PB->z;
652   GLfixed *pbfog = PB->fog;
653   GLfloat *pbs = PB->s[0];
654   GLfloat *pbt = PB->t[0];
655   GLfloat *pbu = PB->u[0];
656   GLchan (*pbrgba)[4] = PB->rgba;
657
658   PB->mono = GL_FALSE;
659
660   if (ctx->Line.StippleFlag) {
661      /* stippled */
662#define INTERP_XY 1
663#define INTERP_Z 1
664#define INTERP_RGB 1
665#define INTERP_ALPHA 1
666#define INTERP_TEX 1
667#define WIDE 1
668#define STIPPLE 1
669#define PLOT(X,Y)					\
670	{						\
671	   pbx[count] = X;				\
672	   pby[count] = Y;				\
673	   pbz[count] = Z;				\
674 	   pbfog[count] = fog0;				\
675	   pbs[count] = fragTexcoord[0];		\
676	   pbt[count] = fragTexcoord[1];		\
677	   pbu[count] = fragTexcoord[2];		\
678	   pbrgba[count][RCOMP] = FixedToInt(r0);	\
679	   pbrgba[count][GCOMP] = FixedToInt(g0);	\
680	   pbrgba[count][BCOMP] = FixedToInt(b0);	\
681	   pbrgba[count][ACOMP] = FixedToInt(a0);	\
682	   count++;					\
683	   CHECK_FULL(count);				\
684	}
685#include "s_linetemp.h"
686   }
687   else {
688      /* unstippled */
689#define INTERP_XY 1
690#define INTERP_Z 1
691#define INTERP_RGB 1
692#define INTERP_ALPHA 1
693#define INTERP_TEX 1
694#define WIDE 1
695#define PLOT(X,Y)					\
696	{						\
697	   pbx[count] = X;				\
698	   pby[count] = Y;				\
699	   pbz[count] = Z;				\
700 	   pbfog[count] = fog0;				\
701	   pbs[count] = fragTexcoord[0];		\
702	   pbt[count] = fragTexcoord[1];		\
703	   pbu[count] = fragTexcoord[2];		\
704	   pbrgba[count][RCOMP] = FixedToInt(r0);	\
705	   pbrgba[count][GCOMP] = FixedToInt(g0);	\
706	   pbrgba[count][BCOMP] = FixedToInt(b0);	\
707	   pbrgba[count][ACOMP] = FixedToInt(a0);	\
708	   count++;					\
709	   CHECK_FULL(count);				\
710	}
711#include "s_linetemp.h"
712   }
713
714   PB->count = count;
715   gl_flush_pb(ctx);
716}
717
718
719/* Smooth-shaded, multitextured, any width, maybe stippled, separate specular
720 * color interpolation.
721 */
722static void smooth_multitextured_line( GLcontext *ctx,
723				       SWvertex *vert0,
724				       SWvertex *vert1 )
725{
726   struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
727   GLint count = PB->count;
728   GLint *pbx = PB->x;
729   GLint *pby = PB->y;
730   GLdepth *pbz = PB->z;
731   GLfixed *pbfog = PB->fog;
732   GLchan (*pbrgba)[4] = PB->rgba;
733   GLchan (*pbspec)[3] = PB->spec;
734
735   PB->mono = GL_FALSE;
736
737   if (ctx->Line.StippleFlag) {
738      /* stippled */
739#define INTERP_XY 1
740#define INTERP_Z 1
741#define INTERP_RGB 1
742#define INTERP_SPEC 1
743#define INTERP_ALPHA 1
744#define INTERP_MULTITEX 1
745#define WIDE 1
746#define STIPPLE 1
747#define PLOT(X,Y)						\
748	{							\
749	   GLuint u;						\
750	   pbx[count] = X;					\
751	   pby[count] = Y;					\
752	   pbz[count] = Z;					\
753 	   pbfog[count] = fog0;					\
754	   pbrgba[count][RCOMP] = FixedToInt(r0);		\
755	   pbrgba[count][GCOMP] = FixedToInt(g0);		\
756	   pbrgba[count][BCOMP] = FixedToInt(b0);		\
757	   pbrgba[count][ACOMP] = FixedToInt(a0);		\
758	   pbspec[count][RCOMP] = FixedToInt(sr0);		\
759	   pbspec[count][GCOMP] = FixedToInt(sg0);		\
760	   pbspec[count][BCOMP] = FixedToInt(sb0);		\
761	   for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {	\
762	      if (ctx->Texture.Unit[u]._ReallyEnabled) {	\
763	         PB->s[u][0] = fragTexcoord[u][0];		\
764	         PB->s[u][1] = fragTexcoord[u][1];		\
765	         PB->s[u][2] = fragTexcoord[u][2];		\
766	         PB->s[u][3] = fragTexcoord[u][3];		\
767	      }							\
768	   }							\
769	   count++;						\
770	   CHECK_FULL(count);					\
771	}
772#include "s_linetemp.h"
773   }
774   else {
775      /* unstippled */
776#define INTERP_XY 1
777#define INTERP_Z 1
778#define INTERP_RGB 1
779#define INTERP_SPEC 1
780#define INTERP_ALPHA 1
781#define INTERP_MULTITEX 1
782#define WIDE 1
783#define PLOT(X,Y)						\
784	{							\
785	   GLuint u;						\
786	   pbx[count] = X;					\
787	   pby[count] = Y;					\
788	   pbz[count] = Z;					\
789 	   pbfog[count] = fog0;					\
790	   pbrgba[count][RCOMP] = FixedToInt(r0);		\
791	   pbrgba[count][GCOMP] = FixedToInt(g0);		\
792	   pbrgba[count][BCOMP] = FixedToInt(b0);		\
793	   pbrgba[count][ACOMP] = FixedToInt(a0);		\
794	   pbspec[count][RCOMP] = FixedToInt(sr0);		\
795	   pbspec[count][GCOMP] = FixedToInt(sg0);		\
796	   pbspec[count][BCOMP] = FixedToInt(sb0);		\
797	   for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {	\
798	      if (ctx->Texture.Unit[u]._ReallyEnabled) {	\
799	         PB->s[u][0] = fragTexcoord[u][0];		\
800	         PB->s[u][1] = fragTexcoord[u][1];		\
801	         PB->s[u][2] = fragTexcoord[u][2];		\
802	         PB->s[u][3] = fragTexcoord[u][3];		\
803	      }							\
804	   }							\
805	   count++;						\
806	   CHECK_FULL(count);					\
807	}
808#include "s_linetemp.h"
809   }
810
811   PB->count = count;
812   gl_flush_pb(ctx);
813}
814
815
816/* Flat-shaded, multitextured, any width, maybe stippled, separate specular
817 * color interpolation.
818 */
819static void flat_multitextured_line( GLcontext *ctx,
820                                     SWvertex *vert0,
821				     SWvertex *vert1 )
822{
823   struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB;
824   GLint count = PB->count;
825   GLint *pbx = PB->x;
826   GLint *pby = PB->y;
827   GLdepth *pbz = PB->z;
828   GLfixed *pbfog = PB->fog;
829   GLchan (*pbrgba)[4] = PB->rgba;
830   GLchan (*pbspec)[3] = PB->spec;
831   GLchan *color = vert0->color;
832   GLchan sRed   = vert0->specular[0];
833   GLchan sGreen = vert0->specular[1];
834   GLchan sBlue  = vert0->specular[2];
835
836   PB->mono = GL_FALSE;
837
838   if (ctx->Line.StippleFlag) {
839      /* stippled */
840#define INTERP_XY 1
841#define INTERP_Z 1
842#define INTERP_ALPHA 1
843#define INTERP_MULTITEX 1
844#define WIDE 1
845#define STIPPLE 1
846#define PLOT(X,Y)						\
847	{							\
848	   GLuint u;						\
849	   pbx[count] = X;					\
850	   pby[count] = Y;					\
851	   pbz[count] = Z;					\
852 	   pbfog[count] = fog0;					\
853	   pbrgba[count][RCOMP] = color[0];			\
854	   pbrgba[count][GCOMP] = color[1];			\
855	   pbrgba[count][BCOMP] = color[2];			\
856	   pbrgba[count][ACOMP] = color[3];			\
857	   pbspec[count][RCOMP] = sRed;				\
858	   pbspec[count][GCOMP] = sGreen;			\
859	   pbspec[count][BCOMP] = sBlue;			\
860	   for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {	\
861	      if (ctx->Texture.Unit[u]._ReallyEnabled) {	\
862	         PB->s[u][0] = fragTexcoord[u][0];		\
863	         PB->s[u][1] = fragTexcoord[u][1];		\
864	         PB->s[u][2] = fragTexcoord[u][2];		\
865	         PB->s[u][3] = fragTexcoord[u][3];		\
866	      }							\
867	   }							\
868	   count++;						\
869	   CHECK_FULL(count);					\
870	}
871#include "s_linetemp.h"
872   }
873   else {
874      /* unstippled */
875#define INTERP_XY 1
876#define INTERP_Z 1
877#define INTERP_ALPHA 1
878#define INTERP_MULTITEX 1
879#define WIDE 1
880#define PLOT(X,Y)						\
881	{							\
882	   GLuint u;						\
883	   pbx[count] = X;					\
884	   pby[count] = Y;					\
885	   pbz[count] = Z;					\
886 	   pbfog[count] = fog0;					\
887	   pbrgba[count][RCOMP] = color[0];			\
888	   pbrgba[count][GCOMP] = color[1];			\
889	   pbrgba[count][BCOMP] = color[2];			\
890	   pbrgba[count][ACOMP] = color[3];			\
891	   pbspec[count][RCOMP] = sRed;				\
892	   pbspec[count][GCOMP] = sGreen;			\
893	   pbspec[count][BCOMP] = sBlue;			\
894	   for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {	\
895	      if (ctx->Texture.Unit[u]._ReallyEnabled) {	\
896	         PB->s[u][0] = fragTexcoord[u][0];		\
897	         PB->s[u][1] = fragTexcoord[u][1];		\
898	         PB->s[u][2] = fragTexcoord[u][2];		\
899	         PB->s[u][3] = fragTexcoord[u][3];		\
900	      }							\
901	   }							\
902	   count++;						\
903	   CHECK_FULL(count);					\
904	}
905#include "s_linetemp.h"
906   }
907
908   PB->count = count;
909   gl_flush_pb(ctx);
910}
911
912
913
914#ifdef DEBUG
915void
916_mesa_print_line_function(GLcontext *ctx)
917{
918   SWcontext *swrast = SWRAST_CONTEXT(ctx);
919
920   printf("Line Func == ");
921   if (swrast->Line == flat_ci_line)
922      printf("flat_ci_line\n");
923   else if (swrast->Line == flat_ci_z_line)
924      printf("flat_ci_z_line\n");
925   else if (swrast->Line == flat_rgba_line)
926      printf("flat_rgba_line\n");
927   else if (swrast->Line == flat_rgba_z_line)
928      printf("flat_rgba_z_line\n");
929   else if (swrast->Line == smooth_ci_line)
930      printf("smooth_ci_line\n");
931   else if (swrast->Line == smooth_ci_z_line)
932      printf("smooth_ci_z_line\n");
933   else if (swrast->Line == smooth_rgba_line)
934      printf("smooth_rgba_line\n");
935   else if (swrast->Line == smooth_rgba_z_line)
936      printf("smooth_rgba_z_line\n");
937   else if (swrast->Line == general_smooth_ci_line)
938      printf("general_smooth_ci_line\n");
939   else if (swrast->Line == general_flat_ci_line)
940      printf("general_flat_ci_line\n");
941   else if (swrast->Line == general_smooth_rgba_line)
942      printf("general_smooth_rgba_line\n");
943   else if (swrast->Line == general_flat_rgba_line)
944      printf("general_flat_rgba_line\n");
945   else if (swrast->Line == flat_textured_line)
946      printf("flat_textured_line\n");
947   else if (swrast->Line == smooth_textured_line)
948      printf("smooth_textured_line\n");
949   else if (swrast->Line == smooth_multitextured_line)
950      printf("smooth_multitextured_line\n");
951   else if (swrast->Line == flat_multitextured_line)
952      printf("flat_multitextured_line\n");
953   else
954      printf("Driver func %p\n", swrast->Line);
955}
956#endif
957
958
959
960/*
961 * Determine which line drawing function to use given the current
962 * rendering context.
963 *
964 * Please update the summary flag _SWRAST_NEW_LINE if you add or remove
965 * tests to this code.
966 */
967void
968_swrast_choose_line( GLcontext *ctx )
969{
970   SWcontext *swrast = SWRAST_CONTEXT(ctx);
971   const GLboolean rgbmode = ctx->Visual.RGBAflag;
972
973   if (ctx->RenderMode==GL_RENDER) {
974      if (ctx->Line.SmoothFlag) {
975         /* antialiased lines */
976         _swrast_choose_aa_line_function(ctx);
977         ASSERT(swrast->Triangle);
978      }
979      else if (ctx->Texture._ReallyEnabled) {
980         if (ctx->Texture._MultiTextureEnabled
981             || ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR
982 	     || ctx->Fog.ColorSumEnabled) {
983            /* multi-texture and/or separate specular color */
984            if (ctx->Light.ShadeModel==GL_SMOOTH)
985               swrast->Line = smooth_multitextured_line;
986            else
987               swrast->Line = flat_multitextured_line;
988         }
989         else {
990            if (ctx->Light.ShadeModel==GL_SMOOTH) {
991                swrast->Line = smooth_textured_line;
992            }
993            else {
994                swrast->Line = flat_textured_line;
995            }
996         }
997      }
998      else if (ctx->Line.Width!=1.0 || ctx->Line.StippleFlag) {
999         if (ctx->Light.ShadeModel==GL_SMOOTH) {
1000            if (rgbmode)
1001               swrast->Line = general_smooth_rgba_line;
1002            else
1003               swrast->Line = general_smooth_ci_line;
1004         }
1005         else {
1006            if (rgbmode)
1007               swrast->Line = general_flat_rgba_line;
1008            else
1009               swrast->Line = general_flat_ci_line;
1010         }
1011      }
1012      else {
1013	 if (ctx->Light.ShadeModel==GL_SMOOTH) {
1014	    /* Width==1, non-stippled, smooth-shaded */
1015            if (ctx->Depth.Test || ctx->Fog.Enabled) {
1016               if (rgbmode)
1017                  swrast->Line = smooth_rgba_z_line;
1018               else
1019                  swrast->Line = smooth_ci_z_line;
1020            }
1021            else {
1022               if (rgbmode)
1023                  swrast->Line = smooth_rgba_line;
1024               else
1025                  swrast->Line = smooth_ci_line;
1026            }
1027	 }
1028         else {
1029	    /* Width==1, non-stippled, flat-shaded */
1030            if (ctx->Depth.Test || ctx->Fog.Enabled) {
1031               if (rgbmode)
1032                  swrast->Line = flat_rgba_z_line;
1033               else
1034                  swrast->Line = flat_ci_z_line;
1035            }
1036            else {
1037               if (rgbmode)
1038                  swrast->Line = flat_rgba_line;
1039               else
1040                  swrast->Line = flat_ci_line;
1041            }
1042         }
1043      }
1044   }
1045   else if (ctx->RenderMode==GL_FEEDBACK) {
1046      swrast->Line = gl_feedback_line;
1047   }
1048   else {
1049      /* GL_SELECT mode */
1050      swrast->Line = gl_select_line;
1051   }
1052
1053   /*_mesa_print_line_function(ctx);*/
1054}
1055